mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-03 18:10:59 +00:00
remove a whole swath of potential buffer overflows by removing the buffer.
Also audit a few of the "FIXME: overflow" tags
This commit is contained in:
parent
59c26b5ce0
commit
ada828bdc9
12 changed files with 246 additions and 310 deletions
|
@ -51,12 +51,13 @@ qboolean Info_FilterForKey (const char *key, const char **filter_list);
|
||||||
|
|
||||||
void Info_Print (info_t *info);
|
void Info_Print (info_t *info);
|
||||||
void Info_RemoveKey (info_t *info, const char *key);
|
void Info_RemoveKey (info_t *info, const char *key);
|
||||||
void Info_SetValueForKey (info_t *info, const char *key, const char *value, int flags);
|
int Info_SetValueForKey (info_t *info, const char *key, const char *value, int flags);
|
||||||
void Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int flags);
|
int Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int flags);
|
||||||
const char *Info_ValueForKey (info_t *info, const char *key);
|
const char *Info_ValueForKey (info_t *info, const char *key);
|
||||||
|
|
||||||
info_t *Info_ParseString (const char *s, int maxsize, int flags);
|
info_t *Info_ParseString (const char *s, int maxsize, int flags);
|
||||||
void Info_Destroy (info_t *info);
|
void Info_Destroy (info_t *info);
|
||||||
char *Info_MakeString (info_t *info, int (*filter)(const char *));
|
char *Info_MakeString (info_t *info, int (*filter)(const char *));
|
||||||
|
void Info_AddKeys (info_t *info, info_t *keys);
|
||||||
|
|
||||||
#endif // _INFO_H
|
#endif // _INFO_H
|
||||||
|
|
|
@ -94,8 +94,9 @@ Info_RemoveKey (info_t *info, const char *key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int flags)
|
Info_SetValueForStarKey (info_t *info, const char *key, const char *value,
|
||||||
|
int flags)
|
||||||
{
|
{
|
||||||
info_key_t *k;
|
info_key_t *k;
|
||||||
int cursize;
|
int cursize;
|
||||||
|
@ -104,17 +105,17 @@ Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int f
|
||||||
|
|
||||||
if (strstr (key, "\\") || strstr (value, "\\")) {
|
if (strstr (key, "\\") || strstr (value, "\\")) {
|
||||||
Sys_Printf ("Can't use keys or values with a \\\n");
|
Sys_Printf ("Can't use keys or values with a \\\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr (key, "\"") || strstr (value, "\"")) {
|
if (strstr (key, "\"") || strstr (value, "\"")) {
|
||||||
Sys_Printf ("Can't use keys or values with a \"\n");
|
Sys_Printf ("Can't use keys or values with a \"\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen (key) > 63 || strlen (value) > 63) {
|
if (strlen (key) > 63 || strlen (value) > 63) {
|
||||||
Sys_Printf ("Keys and values must be < 64 characters.\n");
|
Sys_Printf ("Keys and values must be < 64 characters.\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
k = Hash_Find (info->tab, key);
|
k = Hash_Find (info->tab, key);
|
||||||
cursize = info->cursize;
|
cursize = info->cursize;
|
||||||
|
@ -125,11 +126,11 @@ Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int f
|
||||||
if (info->maxsize &&
|
if (info->maxsize &&
|
||||||
cursize + strlen (key) + 1 + strlen (value) + 1 > info->maxsize) {
|
cursize + strlen (key) + 1 + strlen (value) + 1 > info->maxsize) {
|
||||||
Sys_Printf ("Info string length exceeded\n");
|
Sys_Printf ("Info string length exceeded\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (k) {
|
if (k) {
|
||||||
if (strequal (k->value, value))
|
if (strequal (k->value, value))
|
||||||
return;
|
return 0;
|
||||||
info->cursize -= strlen (k->value) + 1;
|
info->cursize -= strlen (k->value) + 1;
|
||||||
free ((char*)k->value);
|
free ((char*)k->value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,18 +157,19 @@ Info_SetValueForStarKey (info_t *info, const char *key, const char *value, int f
|
||||||
*d = 0;
|
*d = 0;
|
||||||
info->cursize += strlen (str) + 1;
|
info->cursize += strlen (str) + 1;
|
||||||
k->value = str;
|
k->value = str;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
Info_SetValueForKey (info_t *info, const char *key, const char *value,
|
Info_SetValueForKey (info_t *info, const char *key, const char *value,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
if (key[0] == '*') {
|
if (key[0] == '*') {
|
||||||
Sys_Printf ("Can't set * keys\n");
|
Sys_Printf ("Can't set * keys\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info_SetValueForStarKey (info, key, value, flags);
|
return Info_SetValueForStarKey (info, key, value, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -269,3 +271,16 @@ Info_MakeString (info_t *info, int (*filter)(const char *))
|
||||||
free (key_list);
|
free (key_list);
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Info_AddKeys (info_t *info, info_t *keys)
|
||||||
|
{
|
||||||
|
info_key_t **key_list;
|
||||||
|
info_key_t **key;
|
||||||
|
|
||||||
|
key_list = (info_key_t **)Hash_GetList (keys->tab);
|
||||||
|
for (key = key_list; *key; key++) {
|
||||||
|
Info_SetValueForKey (info, (*key)->key, (*key)->value, 0);
|
||||||
|
}
|
||||||
|
free (key_list);
|
||||||
|
}
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ QFS_Open (const char *path, const char *mode)
|
||||||
QFile *
|
QFile *
|
||||||
QFS_WOpen (const char *path, int zip)
|
QFS_WOpen (const char *path, int zip)
|
||||||
{
|
{
|
||||||
char mode[5] = "wb\000\000";
|
char mode[5] = "wb\000\000\000";
|
||||||
|
|
||||||
if (zip) {
|
if (zip) {
|
||||||
mode[2] = 'z';
|
mode[2] = 'z';
|
||||||
|
|
|
@ -183,7 +183,7 @@ static void
|
||||||
SV_SendServerinfo (client_t *client)
|
SV_SendServerinfo (client_t *client)
|
||||||
{
|
{
|
||||||
const char **s;
|
const char **s;
|
||||||
char message[2048];
|
char message[2048];
|
||||||
|
|
||||||
MSG_WriteByte (&client->message, svc_print);
|
MSG_WriteByte (&client->message, svc_print);
|
||||||
snprintf (message, sizeof (message), "%c\nVersion %s server (%i CRC)", 2,
|
snprintf (message, sizeof (message), "%c\nVersion %s server (%i CRC)", 2,
|
||||||
|
|
|
@ -91,7 +91,7 @@ typedef struct {
|
||||||
float fixangletime[MAX_CLIENTS];
|
float fixangletime[MAX_CLIENTS];
|
||||||
vec3_t angles[MAX_CLIENTS];
|
vec3_t angles[MAX_CLIENTS];
|
||||||
struct dstring_s *name;
|
struct dstring_s *name;
|
||||||
struct dstring_s *path;
|
struct dstring_s *text;
|
||||||
int parsecount;
|
int parsecount;
|
||||||
int lastwritten;
|
int lastwritten;
|
||||||
demo_frame_t frames[DEMO_FRAMES];
|
demo_frame_t frames[DEMO_FRAMES];
|
||||||
|
|
|
@ -663,45 +663,16 @@ CL_AddQFInfoKeys (void)
|
||||||
static void
|
static void
|
||||||
CL_FullInfo_f (void)
|
CL_FullInfo_f (void)
|
||||||
{
|
{
|
||||||
char key[512], value[512]; //FIXME: overflow
|
info_t *info;
|
||||||
char *o;
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
if (Cmd_Argc () != 2) {
|
if (Cmd_Argc () != 2) {
|
||||||
Con_Printf ("fullinfo <complete info string>\n");
|
Con_Printf ("fullinfo <complete info string>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = Cmd_Argv (1);
|
info = Info_ParseString (Cmd_Argv (1), MAX_INFO_STRING, 0);
|
||||||
if (*s == '\\')
|
Info_AddKeys (cls.userinfo, info);
|
||||||
s++;
|
Info_Destroy (info);
|
||||||
while (*s) {
|
|
||||||
o = key;
|
|
||||||
while (*s && *s != '\\')
|
|
||||||
*o++ = *s++;
|
|
||||||
*o = 0;
|
|
||||||
|
|
||||||
if (!*s) {
|
|
||||||
Con_Printf ("MISSING VALUE\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
o = value;
|
|
||||||
s++;
|
|
||||||
while (*s && *s != '\\')
|
|
||||||
*o++ = *s++;
|
|
||||||
*o = 0;
|
|
||||||
|
|
||||||
if (*s)
|
|
||||||
s++;
|
|
||||||
|
|
||||||
if (strcaseequal (key, pmodel_name) || strcaseequal (key, emodel_name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Info_SetValueForKey (cls.userinfo, key, value,
|
|
||||||
(!strequal (key, "name")) |
|
|
||||||
(strequal (key, "team") << 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -411,7 +411,7 @@ read_hosts (const char *fname)
|
||||||
{
|
{
|
||||||
FILE *host_file;
|
FILE *host_file;
|
||||||
int host_port;
|
int host_port;
|
||||||
char host_name[256]; //FIXME: overflow
|
char host_name[256];
|
||||||
static const char *fake_heartbeat = " ";
|
static const char *fake_heartbeat = " ";
|
||||||
char *buf;
|
char *buf;
|
||||||
struct sockaddr_in host_addr;
|
struct sockaddr_in host_addr;
|
||||||
|
@ -501,7 +501,7 @@ ma_log (const char *fmt, ...)
|
||||||
va_list args;
|
va_list args;
|
||||||
time_t mytime = 0;
|
time_t mytime = 0;
|
||||||
struct tm *local = NULL;
|
struct tm *local = NULL;
|
||||||
char stamp[1024]; //FIXME: overflow
|
char stamp[123];
|
||||||
|
|
||||||
mytime = time (NULL);
|
mytime = time (NULL);
|
||||||
local = localtime (&mytime);
|
local = localtime (&mytime);
|
||||||
|
|
|
@ -416,7 +416,7 @@ Sbar_SortFrags (qboolean includespec)
|
||||||
static void
|
static void
|
||||||
Sbar_SortTeams (void)
|
Sbar_SortTeams (void)
|
||||||
{
|
{
|
||||||
char t[16 + 1]; //FIXME: overflow
|
char t[16 + 1];
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
player_info_t *s;
|
player_info_t *s;
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ dmo_ping (view_t *view, int x, int y, player_info_t *s)
|
||||||
static inline void
|
static inline void
|
||||||
dmo_uid (view_t *view, int x, int y, player_info_t *s)
|
dmo_uid (view_t *view, int x, int y, player_info_t *s)
|
||||||
{
|
{
|
||||||
char num[12]; //FIXME: overflow
|
char num[12];
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
p = s->userid;
|
p = s->userid;
|
||||||
|
@ -683,7 +683,7 @@ draw_weapons_hud (view_t *view)
|
||||||
static void
|
static void
|
||||||
draw_ammo_sbar (view_t *view)
|
draw_ammo_sbar (view_t *view)
|
||||||
{
|
{
|
||||||
char num[12]; //FIXME: overflow
|
char num[12];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// ammo counts
|
// ammo counts
|
||||||
|
@ -704,7 +704,7 @@ draw_ammo_sbar (view_t *view)
|
||||||
static void
|
static void
|
||||||
draw_ammo_hud (view_t *view)
|
draw_ammo_hud (view_t *view)
|
||||||
{
|
{
|
||||||
char num[12]; //FIXME: overflow
|
char num[12];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// ammo counts
|
// ammo counts
|
||||||
|
@ -989,7 +989,7 @@ Sbar_Draw (void)
|
||||||
void
|
void
|
||||||
Sbar_TeamOverlay (view_t *view)
|
Sbar_TeamOverlay (view_t *view)
|
||||||
{
|
{
|
||||||
char num[12]; //FIXME: overflow
|
char num[20];
|
||||||
int pavg, plow, phigh, i, k, l, x, y;
|
int pavg, plow, phigh, i, k, l, x, y;
|
||||||
team_t *tm;
|
team_t *tm;
|
||||||
info_key_t *player_team = cl.players[cl.playernum].team;
|
info_key_t *player_team = cl.players[cl.playernum].team;
|
||||||
|
@ -1481,7 +1481,7 @@ static void
|
||||||
draw_minifrags (view_t *view)
|
draw_minifrags (view_t *view)
|
||||||
{
|
{
|
||||||
int numlines, top, bottom, f, i, k, x, y;
|
int numlines, top, bottom, f, i, k, x, y;
|
||||||
char num[12]; //FIXME: overflow
|
char num[20];
|
||||||
player_info_t *s;
|
player_info_t *s;
|
||||||
|
|
||||||
scr_copyeverything = 1;
|
scr_copyeverything = 1;
|
||||||
|
@ -1555,7 +1555,7 @@ static void
|
||||||
draw_miniteam (view_t *view)
|
draw_miniteam (view_t *view)
|
||||||
{
|
{
|
||||||
int i, k, x, y;
|
int i, k, x, y;
|
||||||
char num[12]; //FIXME: overflow
|
char num[12];
|
||||||
info_key_t *player_team = cl.players[cl.playernum].team;
|
info_key_t *player_team = cl.players[cl.playernum].team;
|
||||||
team_t *tm;
|
team_t *tm;
|
||||||
|
|
||||||
|
@ -1590,7 +1590,7 @@ draw_time (view_t *view)
|
||||||
struct tm *local = NULL;
|
struct tm *local = NULL;
|
||||||
time_t utc = 0;
|
time_t utc = 0;
|
||||||
const char *timefmt = NULL;
|
const char *timefmt = NULL;
|
||||||
char st[80]; //FIXME: overflow
|
char st[80];
|
||||||
|
|
||||||
// Get local time
|
// Get local time
|
||||||
utc = time (NULL);
|
utc = time (NULL);
|
||||||
|
@ -1609,7 +1609,7 @@ draw_time (view_t *view)
|
||||||
static void
|
static void
|
||||||
draw_fps (view_t *view)
|
draw_fps (view_t *view)
|
||||||
{
|
{
|
||||||
static char st[80]; //FIXME: overflow
|
static char st[80];
|
||||||
double t;
|
double t;
|
||||||
static double lastframetime;
|
static double lastframetime;
|
||||||
static double lastfps;
|
static double lastfps;
|
||||||
|
|
|
@ -341,12 +341,12 @@ SV_Give_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this to keep track of current level --KB
|
// Use this to keep track of current level --KB
|
||||||
static char curlevel[MAX_QPATH] = ""; //FIXME: overflow
|
static dstring_t *curlevel;
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
SV_Current_Map (void)
|
SV_Current_Map (void)
|
||||||
{
|
{
|
||||||
return curlevel;
|
return curlevel ? curlevel->str : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -393,29 +393,33 @@ nice_time (float time)
|
||||||
static void
|
static void
|
||||||
SV_Map_f (void)
|
SV_Map_f (void)
|
||||||
{
|
{
|
||||||
char level[MAX_QPATH]; //FIXME: overflow
|
const char *level;
|
||||||
char expanded[MAX_QPATH]; //FIXME: overflow
|
char *expanded;
|
||||||
QFile *f;
|
QFile *f;
|
||||||
|
|
||||||
|
if (!curlevel)
|
||||||
|
curlevel = dstring_newstr ();
|
||||||
|
|
||||||
if (Cmd_Argc () > 2) {
|
if (Cmd_Argc () > 2) {
|
||||||
SV_Printf ("map <levelname> : continue game on a new level\n");
|
SV_Printf ("map <levelname> : continue game on a new level\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Cmd_Argc () == 1) {
|
if (Cmd_Argc () == 1) {
|
||||||
SV_Printf ("map is %s (%s)\n", curlevel, nice_time (sv.time));
|
SV_Printf ("map is %s (%s)\n", curlevel->str, nice_time (sv.time));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strncpy (level, Cmd_Argv (1), sizeof (level) - 1);
|
level = Cmd_Argv (1);
|
||||||
level[sizeof (level) - 1] = 0;
|
|
||||||
|
|
||||||
// check to make sure the level exists
|
// check to make sure the level exists
|
||||||
snprintf (expanded, sizeof (expanded), "maps/%s.bsp", level);
|
expanded = nva ("maps/%s.bsp", level);
|
||||||
QFS_FOpenFile (expanded, &f);
|
QFS_FOpenFile (expanded, &f);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
SV_Printf ("Can't find %s\n", expanded);
|
SV_Printf ("Can't find %s\n", expanded);
|
||||||
|
free (expanded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Qclose (f);
|
Qclose (f);
|
||||||
|
free (expanded);
|
||||||
|
|
||||||
if (sv.demorecording)
|
if (sv.demorecording)
|
||||||
SV_Stop_f ();
|
SV_Stop_f ();
|
||||||
|
@ -423,8 +427,7 @@ SV_Map_f (void)
|
||||||
SV_BroadcastCommand ("changing\n");
|
SV_BroadcastCommand ("changing\n");
|
||||||
SV_SendMessagesToAll ();
|
SV_SendMessagesToAll ();
|
||||||
|
|
||||||
strncpy (curlevel, level, sizeof (curlevel) - 1);
|
dstring_copystr (curlevel, level);
|
||||||
curlevel[sizeof (curlevel) - 1] = 0;
|
|
||||||
SV_SpawnServer (level);
|
SV_SpawnServer (level);
|
||||||
|
|
||||||
SV_BroadcastCommand ("reconnect\n");
|
SV_BroadcastCommand ("reconnect\n");
|
||||||
|
@ -562,17 +565,36 @@ SV_Status_f (void)
|
||||||
#define MAXPENALTY 10.0
|
#define MAXPENALTY 10.0
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_Cuff_f (void)
|
SV_Punish (int mode)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double mins = 0.5;
|
double mins = 0.5;
|
||||||
qboolean all = false, done = false;
|
qboolean all = false, done = false;
|
||||||
client_t *cl = 0;
|
client_t *cl = 0;
|
||||||
char text[1024]; //FIXME: overflow
|
dstring_t *text = dstring_new();
|
||||||
|
const char *cmd = 0;
|
||||||
|
const char *cmd_do = 0;
|
||||||
|
const char *cmd_undo = 0;
|
||||||
|
int field_offs = 0;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
cmd = "cuff";
|
||||||
|
cmd_do = "cuffed";
|
||||||
|
cmd_undo = "un-cuffed";
|
||||||
|
field_offs = field_offset (client_t, cuff_time);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cmd = "mute";
|
||||||
|
cmd_do = "muted";
|
||||||
|
cmd_undo = "can speak";
|
||||||
|
field_offs = field_offset (client_t, lockedtill);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (Cmd_Argc () != 2 && Cmd_Argc () != 3) {
|
if (Cmd_Argc () != 2 && Cmd_Argc () != 3) {
|
||||||
SV_Printf ("usage: cuff <name/userid/ALL> [minutes]\n"
|
SV_Printf ("usage: %s <name/userid/ALL> [minutes]\n"
|
||||||
" (default = 0.5, 0 = cancel cuff).\n");
|
" (default = 0.5, 0 = cancel cuff).\n", cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,133 +611,52 @@ SV_Cuff_f (void)
|
||||||
mins = MAXPENALTY;
|
mins = MAXPENALTY;
|
||||||
}
|
}
|
||||||
if (cl) {
|
if (cl) {
|
||||||
cl->cuff_time = realtime + mins * 60.0;
|
*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
|
||||||
if (mins) {
|
if (mins) {
|
||||||
sprintf (text, "You are cuffed for %.1f minutes\n\n"
|
dsprintf (text, "You are %s for %.1f minutes\n\n"
|
||||||
"reconnecting won't help...\n", mins);
|
"reconnecting won't help...\n", cmd_do, mins);
|
||||||
ClientReliableWrite_Begin (cl, svc_centerprint, 2 + strlen (text));
|
ClientReliableWrite_Begin (cl, svc_centerprint,
|
||||||
ClientReliableWrite_String (cl, text);
|
2 + strlen (text->str));
|
||||||
|
ClientReliableWrite_String (cl, text->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (all) {
|
if (all) {
|
||||||
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
|
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
|
||||||
if (cl->state < cs_zombie)
|
if (cl->state < cs_zombie)
|
||||||
continue;
|
continue;
|
||||||
cl->cuff_time = realtime + mins * 60.0;
|
*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
|
||||||
done = true;
|
done = true;
|
||||||
if (mins) {
|
if (mins) {
|
||||||
sprintf (text, "You are cuffed for %.1f minutes\n\n"
|
dsprintf (text, "You are %s for %.1f minutes\n\n"
|
||||||
"reconnecting won't help...\n", mins);
|
"reconnecting won't help...\n", cmd_do, mins);
|
||||||
ClientReliableWrite_Begin (cl, svc_centerprint,
|
ClientReliableWrite_Begin (cl, svc_centerprint,
|
||||||
2 + strlen (text));
|
2 + strlen (text->str));
|
||||||
ClientReliableWrite_String (cl, text);
|
ClientReliableWrite_String (cl, text->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (done) {
|
if (done) {
|
||||||
if (mins)
|
if (mins)
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s cuffed for %.1f minutes.\n",
|
SV_BroadcastPrintf (PRINT_HIGH, "%s %s for %.1f minutes.\n",
|
||||||
all? "All Users" : cl->name, mins);
|
all? "All Users" : cl->name, cmd_do, mins);
|
||||||
else
|
else
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s un-cuffed.\n",
|
SV_BroadcastPrintf (PRINT_HIGH, "%s %s.\n",
|
||||||
all? "All Users" : cl->name);
|
all? "All Users" : cl->name, cmd_do);
|
||||||
}
|
}
|
||||||
|
dstring_delete (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SV_Cuff_f (void)
|
||||||
|
{
|
||||||
|
SV_Punish (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_Mute_f (void)
|
SV_Mute_f (void)
|
||||||
{
|
{
|
||||||
int i;
|
SV_Punish (1);
|
||||||
double mins = 0.5;
|
|
||||||
qboolean all = false, done = false;
|
|
||||||
client_t *cl = 0;
|
|
||||||
char text[1024]; //FIXME: overflow
|
|
||||||
|
|
||||||
if (Cmd_Argc () != 2 && Cmd_Argc () != 3) {
|
|
||||||
SV_Printf ("usage: mute <name/userid/ALL> [minutes]\n"
|
|
||||||
" (default = 0.5, 0 = cancel mute).\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (strequal (Cmd_Argv (1),"ALL")) {
|
|
||||||
all = true;
|
|
||||||
} else {
|
|
||||||
cl = SV_Match_User (Cmd_Argv (1));
|
|
||||||
}
|
|
||||||
if (!all && !cl)
|
|
||||||
return;
|
|
||||||
if (Cmd_Argc () == 3) {
|
|
||||||
mins = atof (Cmd_Argv (2));
|
|
||||||
if (mins < 0.0 || mins > MAXPENALTY)
|
|
||||||
mins = MAXPENALTY;
|
|
||||||
}
|
|
||||||
if (cl) {
|
|
||||||
cl->lockedtill = realtime + mins * 60.0;
|
|
||||||
done = true;
|
|
||||||
if (mins) {
|
|
||||||
sprintf (text, "You are muted for %.1f minutes\n\n"
|
|
||||||
"reconnecting won't help...\n", mins);
|
|
||||||
ClientReliableWrite_Begin (cl, svc_centerprint, 2 + strlen (text));
|
|
||||||
ClientReliableWrite_String (cl, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (all) {
|
|
||||||
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
|
|
||||||
if (cl->state < cs_zombie)
|
|
||||||
continue;
|
|
||||||
cl->lockedtill = realtime + mins * 60.0;
|
|
||||||
done = true;
|
|
||||||
if (mins) {
|
|
||||||
sprintf (text, "You are muted for %.1f minutes\n\n"
|
|
||||||
"reconnecting won't help...\n", mins);
|
|
||||||
ClientReliableWrite_Begin (cl, svc_centerprint,
|
|
||||||
2 + strlen (text));
|
|
||||||
ClientReliableWrite_String (cl, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (done) {
|
|
||||||
if (mins)
|
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s muted for %.1f minutes.\n",
|
|
||||||
all? "All Users" : cl->name, mins);
|
|
||||||
else
|
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s allowed to speak.\n",
|
|
||||||
all? "All Users" : cl->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
SV_Tell (const char *prefix)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
char text[512]; //FIXME: overflow
|
|
||||||
client_t *cl;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (Cmd_Argc () < 3) {
|
|
||||||
SV_Printf ("usage: tell <name/userid> <text...>\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(cl = SV_Match_User (Cmd_Argv (1))))
|
|
||||||
return;
|
|
||||||
|
|
||||||
p = Hunk_TempAlloc (strlen (Cmd_Args (2)) + 1);
|
|
||||||
strcpy (p, Cmd_Args (2));
|
|
||||||
if (*p == '"') {
|
|
||||||
p++;
|
|
||||||
p[strlen (p) - 1] = 0;
|
|
||||||
}
|
|
||||||
// construct "[PRIVATE] Console> "
|
|
||||||
sprintf (text, "[\xd0\xd2\xc9\xd6\xc1\xd4\xc5] %s\x8d ", prefix);
|
|
||||||
i = strlen (text);
|
|
||||||
strncat (text, p, sizeof (text) - 1 - i);
|
|
||||||
text[sizeof (text) - 1] = 0;
|
|
||||||
SV_Printf ("%s\n", text);
|
|
||||||
for (; text[i];)
|
|
||||||
text[i++] |= 0x80; // non-bold text
|
|
||||||
SV_ClientPrintf (1, cl, PRINT_CHAT, "\n"); // bell
|
|
||||||
SV_ClientPrintf (1, cl, PRINT_HIGH, "%s\n", text);
|
|
||||||
SV_ClientPrintf (1, cl, PRINT_CHAT, "%s", ""); // bell
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -759,11 +700,10 @@ SV_Match_f (void)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_ConSay (const char *prefix)
|
SV_ConSay (const char *prefix, client_t *client)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
char text[1024]; //FIXME: overflow
|
dstring_t *text;
|
||||||
client_t *client;
|
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (Cmd_Argc () < 2)
|
if (Cmd_Argc () < 2)
|
||||||
|
@ -775,51 +715,67 @@ SV_ConSay (const char *prefix)
|
||||||
p++;
|
p++;
|
||||||
p[strlen (p) - 1] = 0;
|
p[strlen (p) - 1] = 0;
|
||||||
}
|
}
|
||||||
strcpy (text, prefix); // bold header
|
text = dstring_new ();
|
||||||
strcat (text, "\x8d "); // and arrow
|
dstring_copystr (text, prefix);
|
||||||
j = strlen (text);
|
dstring_appendstr (text, "\x8d "); // arrow
|
||||||
strncat (text, p, sizeof (text) - j);
|
j = strlen (text->str);
|
||||||
SV_Printf ("%s\n", text);
|
dstring_appendstr (text, p);
|
||||||
while (text[j])
|
SV_Printf ("%s\n", text->str);
|
||||||
text[j++] |= 0x80; // non-bold text
|
while (text->str[j])
|
||||||
|
text->str[j++] |= 0x80; // non-bold text
|
||||||
|
|
||||||
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
|
if (client) {
|
||||||
if (client->state < cs_zombie)
|
SV_ClientPrintf (1, client, PRINT_CHAT, "\n"); // bell
|
||||||
continue;
|
SV_ClientPrintf (1, client, PRINT_HIGH, "%s\n", text->str);
|
||||||
SV_ClientPrintf (1, client, PRINT_HIGH, "%s\n", text);
|
SV_ClientPrintf (1, client, PRINT_CHAT, "%s", ""); // bell
|
||||||
if (*prefix != 'I') // beep, except for Info says
|
} else {
|
||||||
SV_ClientPrintf (0, client, PRINT_CHAT, "%s", "");
|
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
|
||||||
}
|
if (client->state < cs_zombie)
|
||||||
if (sv.demorecording) {
|
continue;
|
||||||
DemoWrite_Begin (dem_all, 0, strlen (text) + 3);
|
SV_ClientPrintf (1, client, PRINT_HIGH, "%s\n", text->str);
|
||||||
MSG_WriteByte (&demo.dbuf->sz, svc_print);
|
if (*prefix != 'I') // beep, except for Info says
|
||||||
MSG_WriteByte (&demo.dbuf->sz, PRINT_CHAT);
|
SV_ClientPrintf (0, client, PRINT_CHAT, "%s", "");
|
||||||
MSG_WriteString (&demo.dbuf->sz, text);
|
}
|
||||||
|
if (sv.demorecording) {
|
||||||
|
DemoWrite_Begin (dem_all, 0, strlen (text->str) + 3);
|
||||||
|
MSG_WriteByte (&demo.dbuf->sz, svc_print);
|
||||||
|
MSG_WriteByte (&demo.dbuf->sz, PRINT_CHAT);
|
||||||
|
MSG_WriteString (&demo.dbuf->sz, text->str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_Tell_f (void)
|
SV_Tell_f (void)
|
||||||
{
|
{
|
||||||
|
client_t *cl;
|
||||||
|
|
||||||
|
if (Cmd_Argc () < 3) {
|
||||||
|
SV_Printf ("usage: tell <name/userid> <text...>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(cl = SV_Match_User (Cmd_Argv (1))))
|
||||||
|
return;
|
||||||
|
|
||||||
if (rcon_from_user)
|
if (rcon_from_user)
|
||||||
SV_Tell("Admin");
|
SV_ConSay ("[\xd0\xd2\xc9\xd6\xc1\xd4\xc5] Admin", cl);
|
||||||
else
|
else
|
||||||
SV_Tell("Console");
|
SV_ConSay ("[\xd0\xd2\xc9\xd6\xc1\xd4\xc5] Console", cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_ConSay_f (void)
|
SV_ConSay_f (void)
|
||||||
{
|
{
|
||||||
if (rcon_from_user)
|
if (rcon_from_user)
|
||||||
SV_ConSay ("Admin");
|
SV_ConSay ("Admin", 0);
|
||||||
else
|
else
|
||||||
SV_ConSay ("Console");
|
SV_ConSay ("Console", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_ConSay_Info_f (void)
|
SV_ConSay_Info_f (void)
|
||||||
{
|
{
|
||||||
SV_ConSay ("Info");
|
SV_ConSay ("Info", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -541,14 +541,12 @@ SV_DemoWritePackets (int num)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
memwrite (QFile * _mem, const void *buffer, int size)
|
memwrite (QFile *_mem, const void *buffer, int size)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
byte **mem = (byte **) _mem;
|
byte **mem = (byte **) _mem;
|
||||||
const byte *buf;
|
|
||||||
|
|
||||||
for (i = size, buf = buffer; i; i--)
|
memcpy (*mem, buffer, size);
|
||||||
*(*mem)++ = *buf++;
|
*mem += size;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -585,18 +583,12 @@ SV_Stop (int reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reason == 2) {
|
if (reason == 2) {
|
||||||
char path[MAX_OSPATH];
|
|
||||||
|
|
||||||
// stop and remove
|
// stop and remove
|
||||||
if (demo.disk)
|
if (demo.disk)
|
||||||
Qclose (demo.file);
|
Qclose (demo.file);
|
||||||
|
|
||||||
sprintf (path, "%s/%s/%s", qfs_gamedir->dir.def, demo.path->str,
|
QFS_Remove (demo.name->str);
|
||||||
demo.name->str);
|
QFS_Remove (demo.text->str);
|
||||||
QFS_Remove (path);
|
|
||||||
|
|
||||||
strcpy (path + strlen (path) - 3, "txt");
|
|
||||||
QFS_Remove (path);
|
|
||||||
|
|
||||||
demo.file = NULL;
|
demo.file = NULL;
|
||||||
sv.demorecording = false;
|
sv.demorecording = false;
|
||||||
|
@ -632,8 +624,8 @@ SV_Stop (int reason)
|
||||||
if (!reason)
|
if (!reason)
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server recording completed\n");
|
SV_BroadcastPrintf (PRINT_CHAT, "Server recording completed\n");
|
||||||
else
|
else
|
||||||
SV_BroadcastPrintf (PRINT_CHAT,
|
SV_BroadcastPrintf (PRINT_CHAT, "Server recording stoped\n"
|
||||||
"Server recording stoped\nMax demo size exceeded\n");
|
"Max demo size exceeded\n");
|
||||||
/*
|
/*
|
||||||
if (sv_onrecordfinish->string[0]) {
|
if (sv_onrecordfinish->string[0]) {
|
||||||
extern redirect_t sv_redirected;
|
extern redirect_t sv_redirected;
|
||||||
|
@ -740,12 +732,15 @@ SV_WriteSetDemoMessage (void)
|
||||||
static const char *
|
static const char *
|
||||||
SV_PrintTeams (void)
|
SV_PrintTeams (void)
|
||||||
{
|
{
|
||||||
char teams[MAX_CLIENTS][128];
|
const char *teams[MAX_CLIENTS];
|
||||||
char *p;
|
char *p;
|
||||||
int i, j, numcl = 0, numt = 0;
|
int i, j, numcl = 0, numt = 0;
|
||||||
client_t *clients[MAX_CLIENTS];
|
client_t *clients[MAX_CLIENTS];
|
||||||
char buf[2048] = { 0 };
|
|
||||||
const char *team;
|
const char *team;
|
||||||
|
static dstring_t *buffer;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
buffer = dstring_new ();
|
||||||
|
|
||||||
// count teams and players
|
// count teams and players
|
||||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||||
|
@ -756,42 +751,43 @@ SV_PrintTeams (void)
|
||||||
|
|
||||||
team = Info_ValueForKey (svs.clients[i].userinfo, "team");
|
team = Info_ValueForKey (svs.clients[i].userinfo, "team");
|
||||||
clients[numcl++] = &svs.clients[i];
|
clients[numcl++] = &svs.clients[i];
|
||||||
|
|
||||||
for (j = 0; j < numt; j++)
|
for (j = 0; j < numt; j++)
|
||||||
if (!strcmp (team, teams[j]))
|
if (!strcmp (team, teams[j]))
|
||||||
break;
|
break;
|
||||||
if (j != numt)
|
if (j != numt)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcpy (teams[numt++], team);
|
teams[numt++] = team;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create output
|
// create output
|
||||||
|
|
||||||
if (numcl == 2) // duel
|
if (numcl == 2) // duel
|
||||||
{
|
{
|
||||||
sprintf (buf, "team1 %s\nteam2 %s\n", clients[0]->name,
|
dsprintf (buffer, "team1 %s\nteam2 %s\n", clients[0]->name,
|
||||||
clients[1]->name);
|
clients[1]->name);
|
||||||
} else if (!teamplay->int_val) // ffa
|
} else if (!teamplay->int_val) // ffa
|
||||||
{
|
{
|
||||||
sprintf (buf, "players:\n");
|
dsprintf (buffer, "players:\n");
|
||||||
for (i = 0; i < numcl; i++)
|
for (i = 0; i < numcl; i++)
|
||||||
sprintf (buf + strlen (buf), " %s\n", clients[i]->name);
|
dasprintf (buffer, " %s\n", clients[i]->name);
|
||||||
} else { // teamplay
|
} else { // teamplay
|
||||||
for (j = 0; j < numt; j++) {
|
for (j = 0; j < numt; j++) {
|
||||||
sprintf (buf + strlen (buf), "team %s:\n", teams[j]);
|
dasprintf (buffer, "team %s:\n", teams[j]);
|
||||||
for (i = 0; i < numcl; i++) {
|
for (i = 0; i < numcl; i++) {
|
||||||
team = Info_ValueForKey (svs.clients[i].userinfo, "team");
|
team = Info_ValueForKey (svs.clients[i].userinfo, "team");
|
||||||
if (!strcmp (team, teams[j]))
|
if (!strcmp (team, teams[j]))
|
||||||
sprintf (buf + strlen (buf), " %s\n", clients[i]->name);
|
dasprintf (buffer, " %s\n", clients[i]->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!numcl)
|
if (!numcl)
|
||||||
return "\n";
|
return "\n";
|
||||||
for (p = buf; *p; p++)
|
for (p = buffer->str; *p; p++)
|
||||||
*p = sys_char_map[(byte) * p];
|
*p = sys_char_map[(byte) * p];
|
||||||
return va ("%s", buf);
|
return buffer->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -806,19 +802,21 @@ SV_Record (char *name)
|
||||||
sizebuf_t buf;
|
sizebuf_t buf;
|
||||||
char buf_data[MAX_MSGLEN];
|
char buf_data[MAX_MSGLEN];
|
||||||
int n, i;
|
int n, i;
|
||||||
char path[MAX_OSPATH];
|
|
||||||
const char *info;
|
const char *info;
|
||||||
dstring_t *tn = demo.name, *tp = demo.path;
|
|
||||||
|
|
||||||
client_t *player;
|
client_t *player;
|
||||||
const char *gamedir, *s;
|
const char *gamedir, *s;
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
|
|
||||||
memset (&demo, 0, sizeof (demo));
|
{
|
||||||
|
// save over memset
|
||||||
|
dstring_t *tn = demo.name, *tt = demo.text;
|
||||||
|
memset (&demo, 0, sizeof (demo));
|
||||||
|
dstring_clearstr (demo.name = tn);
|
||||||
|
dstring_clearstr (demo.text = tt);
|
||||||
|
}
|
||||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||||
demo.recorder.frames[i].entities.entities = demo_entities[i];
|
demo.recorder.frames[i].entities.entities = demo_entities[i];
|
||||||
dstring_clearstr (demo.name = tn);
|
|
||||||
dstring_clearstr (demo.path = tp);
|
|
||||||
|
|
||||||
DemoBuffer_Init (&demo.dbuffer, demo.buffer, sizeof (demo.buffer));
|
DemoBuffer_Init (&demo.dbuffer, demo.buffer, sizeof (demo.buffer));
|
||||||
DemoSetMsgBuf (NULL, &demo.frames[0].buf);
|
DemoSetMsgBuf (NULL, &demo.frames[0].buf);
|
||||||
|
@ -835,45 +833,36 @@ SV_Record (char *name)
|
||||||
SV_InitRecord ();
|
SV_InitRecord ();
|
||||||
|
|
||||||
s = name + strlen (name);
|
s = name + strlen (name);
|
||||||
while (*s != '/')
|
while (s > name && *s != '/')
|
||||||
s--;
|
s--;
|
||||||
dstring_clearstr (demo.name);
|
dstring_copystr (demo.name, s + (*s == '/'));
|
||||||
dstring_clearstr (demo.path);
|
|
||||||
dstring_appendstr (demo.name, s + 1);
|
|
||||||
dstring_appendstr (demo.path, sv_demoDir->string);
|
|
||||||
|
|
||||||
if (demo.path->size < 2)
|
SV_BroadcastPrintf (PRINT_CHAT, "Server started recording (%s):\n%s\n",
|
||||||
dstring_appendstr (demo.path, ".");
|
|
||||||
|
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n",
|
|
||||||
demo.disk ? "disk" : "memory", demo.name->str);
|
demo.disk ? "disk" : "memory", demo.name->str);
|
||||||
Cvar_Set (serverdemo, demo.name->str);
|
Cvar_Set (serverdemo, demo.name->str);
|
||||||
|
|
||||||
strcpy (path, name);
|
dstring_copystr (demo.text, name);
|
||||||
strcpy (path + strlen (path) - 3, "txt");
|
strcpy (demo.text->str + strlen (demo.text->str) - 3, "txt");
|
||||||
|
|
||||||
if (sv_demotxt->int_val) {
|
if (sv_demotxt->int_val) {
|
||||||
QFile *f;
|
QFile *f;
|
||||||
|
|
||||||
f = QFS_Open (path, "w+t");
|
f = QFS_Open (demo.text->str, "w+t");
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
char buf[2000];
|
|
||||||
char date[20];
|
char date[20];
|
||||||
time_t tim;
|
time_t tim;
|
||||||
|
|
||||||
time (&tim);
|
time (&tim);
|
||||||
strftime (date, 19, "%Y-%m-%d-%H-%M", localtime (&tim));
|
strftime (date, sizeof (date), "%Y-%m-%d-%H-%M", localtime (&tim));
|
||||||
|
Qprintf (f, "date %s\nmap %s\nteamplay %d\ndeathmatch %d\n"
|
||||||
sprintf (buf, "date %s\nmap %s\nteamplay %d\ndeathmatch %d\n"
|
|
||||||
"timelimit %d\n%s",
|
"timelimit %d\n%s",
|
||||||
date, sv.name, teamplay->int_val,
|
date, sv.name, teamplay->int_val,
|
||||||
deathmatch->int_val, timelimit->int_val, SV_PrintTeams ());
|
deathmatch->int_val, timelimit->int_val,
|
||||||
Qwrite (f, buf, strlen (buf));
|
SV_PrintTeams ());
|
||||||
Qflush (f);
|
|
||||||
Qclose (f);
|
Qclose (f);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
unlink (path);
|
QFS_Remove (demo.text->str);
|
||||||
|
|
||||||
sv.demorecording = true;
|
sv.demorecording = true;
|
||||||
demo.pingtime = demo.time = sv.time;
|
demo.pingtime = demo.time = sv.time;
|
||||||
|
@ -1058,26 +1047,28 @@ SV_Record (char *name)
|
||||||
Cleans the demo name, removes restricted chars, makes name lowercase
|
Cleans the demo name, removes restricted chars, makes name lowercase
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
SV_CleanName (const unsigned char *name)
|
SV_CleanName (const unsigned char *name)
|
||||||
{
|
{
|
||||||
static char text[1024];
|
static char *text;
|
||||||
char *out = text;
|
static size_t text_len;
|
||||||
|
char *out, c;
|
||||||
|
|
||||||
*out = sys_char_map[*name++];
|
if (text_len < strlen (name)) {
|
||||||
|
text_len = (strlen (name) + 1023) & ~1023;
|
||||||
|
text = realloc (text, text_len);
|
||||||
|
}
|
||||||
|
|
||||||
while (*name)
|
out = text;
|
||||||
if (*out == '_' && sys_char_map[*name] == '_')
|
do {
|
||||||
name++;
|
c = sys_char_map[*name++];
|
||||||
else
|
if (c != '_')
|
||||||
*++out = sys_char_map[*name++];
|
*out++ = c;
|
||||||
|
} while (c);
|
||||||
|
|
||||||
*++out = 0;
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_DEMO_NAME 64 // FIXME
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SV_Record_f
|
SV_Record_f
|
||||||
|
|
||||||
|
@ -1253,7 +1244,7 @@ Demo_Init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
demo.name = dstring_newstr ();
|
demo.name = dstring_newstr ();
|
||||||
demo.path = dstring_newstr ();
|
demo.text = dstring_newstr ();
|
||||||
|
|
||||||
svs.demomem = Hunk_AllocName (size, "demo");
|
svs.demomem = Hunk_AllocName (size, "demo");
|
||||||
svs.demomemsize = size;
|
svs.demomemsize = size;
|
||||||
|
|
|
@ -1361,8 +1361,8 @@ PF_logfrag (progs_t *pr)
|
||||||
|
|
||||||
// do gib event callback
|
// do gib event callback
|
||||||
if (sv_frag_e->func) {
|
if (sv_frag_e->func) {
|
||||||
char buf[16]; //FIXME: overflow
|
char buf[16];
|
||||||
char type1[2], type2[2]; //FIXME: overflow
|
char type1[2], type2[2];
|
||||||
int u1, u2;
|
int u1, u2;
|
||||||
|
|
||||||
type1[1] = type2[1] = 0;
|
type1[1] = type2[1] = 0;
|
||||||
|
|
|
@ -558,15 +558,15 @@ SV_Begin_f (void *unused)
|
||||||
static void
|
static void
|
||||||
SV_NextDownload_f (void *unused)
|
SV_NextDownload_f (void *unused)
|
||||||
{
|
{
|
||||||
byte buffer[1024];
|
byte buffer[768]; // FIXME protocol limit? could be bigger?
|
||||||
int percent, size, r;
|
int percent, size, r;
|
||||||
|
|
||||||
if (!host_client->download)
|
if (!host_client->download)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
r = host_client->downloadsize - host_client->downloadcount;
|
r = host_client->downloadsize - host_client->downloadcount;
|
||||||
if (r > 768)
|
if (r > sizeof (buffer))
|
||||||
r = 768;
|
r = sizeof (buffer);
|
||||||
r = Qread (host_client->download, buffer, r);
|
r = Qread (host_client->download, buffer, r);
|
||||||
ClientReliableWrite_Begin (host_client, svc_download, 6 + r);
|
ClientReliableWrite_Begin (host_client, svc_download, 6 + r);
|
||||||
ClientReliableWrite_Short (host_client, r);
|
ClientReliableWrite_Short (host_client, r);
|
||||||
|
@ -741,29 +741,16 @@ static void
|
||||||
SV_Say (qboolean team)
|
SV_Say (qboolean team)
|
||||||
{
|
{
|
||||||
char *i, *p;
|
char *i, *p;
|
||||||
char text[2048], t1[32];
|
dstring_t *text;
|
||||||
const char *t2, *type;
|
const char *t1 = 0, *t2, *type, *fmt;
|
||||||
client_t *client;
|
client_t *client;
|
||||||
int tmp, j, cls = 0;
|
int tmp, j, cls = 0;
|
||||||
|
|
||||||
if (Cmd_Argc () < 2)
|
if (Cmd_Argc () < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (team) {
|
if (team)
|
||||||
strncpy (t1, Info_ValueForKey (host_client->userinfo, "team"), 31);
|
t1 = Info_ValueForKey (host_client->userinfo, "team");
|
||||||
t1[31] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host_client->spectator && (!sv_spectalk->int_val || team)) {
|
|
||||||
snprintf (text, sizeof (text), "[SPEC] %s: ", host_client->name);
|
|
||||||
type = "2";
|
|
||||||
} else if (team) {
|
|
||||||
snprintf (text, sizeof (text), "(%s): ", host_client->name);
|
|
||||||
type = "1";
|
|
||||||
} else {
|
|
||||||
snprintf (text, sizeof (text), "%s: ", host_client->name);
|
|
||||||
type = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fp_messages) {
|
if (fp_messages) {
|
||||||
if (!sv.paused && realtime < host_client->lockedtill) {
|
if (!sv.paused && realtime < host_client->lockedtill) {
|
||||||
|
@ -793,6 +780,20 @@ SV_Say (qboolean team)
|
||||||
host_client->whensaid[host_client->whensaidhead] = realtime;
|
host_client->whensaid[host_client->whensaidhead] = realtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text = dstring_new ();
|
||||||
|
|
||||||
|
if (host_client->spectator && (!sv_spectalk->int_val || team)) {
|
||||||
|
fmt = "[SPEC] %s: ";
|
||||||
|
type = "2";
|
||||||
|
} else if (team) {
|
||||||
|
fmt = "(%s): ";
|
||||||
|
type = "1";
|
||||||
|
} else {
|
||||||
|
fmt = "%s: ";
|
||||||
|
type = "0";
|
||||||
|
}
|
||||||
|
dsprintf (text, fmt, host_client->name);
|
||||||
|
|
||||||
p = Hunk_TempAlloc (strlen (Cmd_Args (1)) + 1);
|
p = Hunk_TempAlloc (strlen (Cmd_Args (1)) + 1);
|
||||||
strcpy (p, Cmd_Args (1));
|
strcpy (p, Cmd_Args (1));
|
||||||
|
|
||||||
|
@ -810,6 +811,7 @@ SV_Say (qboolean team)
|
||||||
SV_ClientPrintf (1, host_client, PRINT_HIGH, "You were kicked "
|
SV_ClientPrintf (1, host_client, PRINT_HIGH, "You were kicked "
|
||||||
"for attempting to fake messages\n");
|
"for attempting to fake messages\n");
|
||||||
SV_DropClient (host_client);
|
SV_DropClient (host_client);
|
||||||
|
dstring_delete (text);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
*i = '#';
|
*i = '#';
|
||||||
|
@ -818,11 +820,9 @@ SV_Say (qboolean team)
|
||||||
if (sv_chat_e->func)
|
if (sv_chat_e->func)
|
||||||
GIB_Event_Callback (sv_chat_e, 2, va ("%i", host_client->userid), p,
|
GIB_Event_Callback (sv_chat_e, 2, va ("%i", host_client->userid), p,
|
||||||
type);
|
type);
|
||||||
|
|
||||||
strncat (text, p, sizeof (text) - strlen (text));
|
|
||||||
strncat (text, "\n", sizeof (text) - strlen (text));
|
|
||||||
|
|
||||||
SV_Printf ("%s", text);
|
dstring_appendstr (text, p);
|
||||||
|
dstring_appendstr (text, "\n");
|
||||||
|
|
||||||
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
|
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
|
||||||
if (client->state < cs_connected) // Clients connecting can hear.
|
if (client->state < cs_connected) // Clients connecting can hear.
|
||||||
|
@ -843,22 +843,25 @@ SV_Say (qboolean team)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cls |= 1 << j;
|
cls |= 1 << j;
|
||||||
SV_ClientPrintf (0, client, PRINT_CHAT, "%s", text);
|
SV_ClientPrintf (0, client, PRINT_CHAT, "%s", text->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sv.demorecording || !cls)
|
if (!sv.demorecording || !cls) {
|
||||||
|
dstring_delete (text);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// non-team messages should be seen allways, even if not tracking any
|
// non-team messages should be seen allways, even if not tracking any
|
||||||
// player
|
// player
|
||||||
if (!team && ((host_client->spectator && sv_spectalk->value)
|
if (!team && ((host_client->spectator && sv_spectalk->value)
|
||||||
|| !host_client->spectator)) {
|
|| !host_client->spectator)) {
|
||||||
DemoWrite_Begin (dem_all, 0, strlen (text) + 3);
|
DemoWrite_Begin (dem_all, 0, strlen (text->str) + 3);
|
||||||
} else {
|
} else {
|
||||||
DemoWrite_Begin (dem_multiple, cls, strlen (text) + 3);
|
DemoWrite_Begin (dem_multiple, cls, strlen (text->str) + 3);
|
||||||
}
|
}
|
||||||
MSG_WriteByte (&demo.dbuf->sz, svc_print);
|
MSG_WriteByte (&demo.dbuf->sz, svc_print);
|
||||||
MSG_WriteByte (&demo.dbuf->sz, PRINT_CHAT);
|
MSG_WriteByte (&demo.dbuf->sz, PRINT_CHAT);
|
||||||
MSG_WriteString (&demo.dbuf->sz, text);
|
MSG_WriteString (&demo.dbuf->sz, text->str);
|
||||||
|
dstring_delete (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1084,7 +1087,7 @@ SV_Msg_f (void *unused)
|
||||||
static void
|
static void
|
||||||
SV_SetInfo_f (void *unused)
|
SV_SetInfo_f (void *unused)
|
||||||
{
|
{
|
||||||
char oldval[MAX_INFO_STRING];
|
char *oldval;
|
||||||
|
|
||||||
if (Cmd_Argc () == 1) {
|
if (Cmd_Argc () == 1) {
|
||||||
SV_Printf ("User info settings:\n");
|
SV_Printf ("User info settings:\n");
|
||||||
|
@ -1100,22 +1103,20 @@ SV_SetInfo_f (void *unused)
|
||||||
if (Cmd_Argv (1)[0] == '*')
|
if (Cmd_Argv (1)[0] == '*')
|
||||||
return; // don't set priveledged values
|
return; // don't set priveledged values
|
||||||
|
|
||||||
// preserve the old value
|
|
||||||
strcpy (oldval, Info_ValueForKey (host_client->userinfo,
|
|
||||||
Cmd_Argv (1)));
|
|
||||||
|
|
||||||
if (UserInfoCallback) {
|
if (UserInfoCallback) {
|
||||||
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
||||||
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, Cmd_Argv (1));
|
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, Cmd_Argv (1));
|
||||||
P_STRING (&sv_pr_state, 1) = PR_SetString (&sv_pr_state, Cmd_Argv (2));
|
P_STRING (&sv_pr_state, 1) = PR_SetString (&sv_pr_state, Cmd_Argv (2));
|
||||||
PR_ExecuteProgram (&sv_pr_state, UserInfoCallback);
|
PR_ExecuteProgram (&sv_pr_state, UserInfoCallback);
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
Info_SetValueForKey (host_client->userinfo, Cmd_Argv (1), Cmd_Argv (2),
|
|
||||||
!sv_highchars->int_val);
|
oldval = strdup (Info_ValueForKey (host_client->userinfo, Cmd_Argv (1)));
|
||||||
if (strequal
|
if (!Info_SetValueForKey (host_client->userinfo, Cmd_Argv (1),
|
||||||
(Info_ValueForKey (host_client->userinfo, Cmd_Argv (1)), oldval))
|
Cmd_Argv (2), !sv_highchars->int_val)) {
|
||||||
return; // key hasn't changed
|
// key hasn't changed
|
||||||
|
free (oldval);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process any changed values
|
// process any changed values
|
||||||
|
@ -1127,6 +1128,7 @@ SV_SetInfo_f (void *unused)
|
||||||
Cmd_Argv (1), oldval,
|
Cmd_Argv (1), oldval,
|
||||||
Info_ValueForKey (host_client->userinfo,
|
Info_ValueForKey (host_client->userinfo,
|
||||||
Cmd_Argv (1)));
|
Cmd_Argv (1)));
|
||||||
|
free (oldval);
|
||||||
|
|
||||||
if (Info_FilterForKey (Cmd_Argv (1), client_info_filters)) {
|
if (Info_FilterForKey (Cmd_Argv (1), client_info_filters)) {
|
||||||
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue