mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
- change MSG_ReadString to return const char * and return a pointer
directly into the packet data. - change a bunch of char *'s to const char *'s for the above. Only thing that had trouble was the cl_nofake handler, which I changed to use a local buffer. - add MSG_ReadStaticString which acts like the old MSG_ReadString, specifically that it uses a static buffer and tollerates unterminated strings. - add a Q_strnlen function, and make strnlen use it if strnlen is undefined. - Add a net_svc.h and net_svc.c which will preparse svc messages into structs, for easier handling. Currently only soundlist and modellist are done.
This commit is contained in:
parent
1b1955551a
commit
18036b63d9
15 changed files with 249 additions and 53 deletions
|
@ -53,7 +53,8 @@ int MSG_ReadByte (msg_t *msg);
|
|||
int MSG_ReadShort (msg_t *msg);
|
||||
int MSG_ReadLong (msg_t *msg);
|
||||
float MSG_ReadFloat (msg_t *msg);
|
||||
char *MSG_ReadString (msg_t *msg);
|
||||
const char *MSG_ReadString (msg_t *msg);
|
||||
char *MSG_ReadStaticString (msg_t *msg);
|
||||
char *MSG_ReadStringLine (msg_t *msg);
|
||||
|
||||
float MSG_ReadCoord (msg_t *msg);
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
#define string_h
|
||||
|
||||
const char * Q_strcasestr (const char *haystack, const char *needle);
|
||||
size_t Q_strnlen (const char *s, size_t maxlen);
|
||||
|
||||
#endif // string_h
|
||||
|
|
|
@ -93,6 +93,10 @@ extern int vsnprintf(char *s, size_t maxlen, const char *format, va_list arg);
|
|||
#if !defined(strcasestr)
|
||||
# define strcasestr Q_strcasestr
|
||||
#endif
|
||||
// FIXME: same as above
|
||||
#if !defined(strnlen)
|
||||
# define strnlen Q_strnlen
|
||||
#endif
|
||||
|
||||
#undef field_offset
|
||||
#define field_offset(type,field) ((int)&(((type *)0)->field))
|
||||
|
|
|
@ -40,7 +40,9 @@ static const char rcsid[] =
|
|||
#include "QF/msg.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/string.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
/*
|
||||
MESSAGE IO FUNCTIONS
|
||||
|
@ -261,8 +263,36 @@ MSG_ReadFloat (msg_t *msg)
|
|||
return dat.f;
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
MSG_ReadString (msg_t *msg)
|
||||
{
|
||||
char *string;
|
||||
int len, maxlen;
|
||||
|
||||
if (msg->readcount + 1 > msg->message->cursize) {
|
||||
msg->badread = true;
|
||||
return "";
|
||||
}
|
||||
|
||||
string = &msg->message->data[msg->readcount];
|
||||
|
||||
maxlen = msg->message->cursize - msg->readcount;
|
||||
len = strnlen (string, maxlen);
|
||||
if (len == maxlen) {
|
||||
msg->badread = true;
|
||||
return "";
|
||||
}
|
||||
msg->readcount += len + 1;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
// Netchan_OutOfBandPrint is broken such that it strips the
|
||||
// terminating nul, which means connection packets (amoung others)
|
||||
// aren't nul-terminated. So I provide the old string function for
|
||||
// connectionless-packet parsers to use.
|
||||
char *
|
||||
MSG_ReadStaticString (msg_t *msg)
|
||||
{
|
||||
static char string[2048];
|
||||
int l, c;
|
||||
|
|
|
@ -45,7 +45,7 @@ static const char rcsid[] =
|
|||
const char *
|
||||
Q_strcasestr (const char *haystack, const char *needle)
|
||||
{
|
||||
int len = strlen (needle);
|
||||
size_t len = strlen (needle);
|
||||
while (*haystack) {
|
||||
if (!strncasecmp (haystack, needle, len))
|
||||
return haystack;
|
||||
|
@ -53,3 +53,16 @@ Q_strcasestr (const char *haystack, const char *needle)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Q_strnlen
|
||||
|
||||
strlen with a cutoff
|
||||
*/
|
||||
size_t
|
||||
Q_strnlen (const char *s, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; s[i] && i < maxlen; i++);
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ CL_ParseServerInfo (void)
|
|||
{
|
||||
char model_precache[MAX_MODELS][MAX_QPATH];
|
||||
char sound_precache[MAX_SOUNDS][MAX_QPATH];
|
||||
char *str;
|
||||
const char *str;
|
||||
int nummodels, numsounds, i;
|
||||
|
||||
Con_DPrintf ("Serverinfo packet received.\n");
|
||||
|
|
|
@ -969,7 +969,7 @@ _Datagram_CheckNewConnections (void)
|
|||
}
|
||||
|
||||
if (command == CCREQ_RULE_INFO) {
|
||||
char *prevCvarName;
|
||||
const char *prevCvarName;
|
||||
cvar_t *var;
|
||||
|
||||
// find the search start location
|
||||
|
@ -1277,7 +1277,7 @@ _Datagram_Connect (const char *host)
|
|||
int reps;
|
||||
double start_time;
|
||||
int control;
|
||||
char *reason;
|
||||
const char *reason;
|
||||
|
||||
// see if we can resolve the host name
|
||||
if (dfunc.GetAddrFromName (host, &sendaddr) == -1)
|
||||
|
|
|
@ -448,7 +448,7 @@ qboolean
|
|||
SV_ReadClientMessage (void)
|
||||
{
|
||||
int cmd, ret;
|
||||
char *s;
|
||||
const char *s;
|
||||
|
||||
do {
|
||||
nextmsg:
|
||||
|
|
54
qw/include/net_svc.h
Normal file
54
qw/include/net_svc.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
net_svc.h
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef NET_SVC_H
|
||||
#define NET_SVC_H
|
||||
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/msg.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
|
||||
typedef struct net_svc_soundlist_s
|
||||
{
|
||||
byte startsound;
|
||||
const char *sounds[MAX_SOUNDS + 1]; // space left for terminating empty string
|
||||
byte nextsound;
|
||||
} net_svc_soundlist_t;
|
||||
|
||||
typedef struct net_svc_modellist_s
|
||||
{
|
||||
byte startmodel;
|
||||
const char *models[MAX_MODELS + 1]; // space left for terminating empty string
|
||||
byte nextmodel;
|
||||
} net_svc_modellist_t;
|
||||
|
||||
void NET_SVC_Soundlist_Parse (net_svc_soundlist_t *soundlist, msg_t *message);
|
||||
void NET_SVC_Modellist_Parse (net_svc_modellist_t *modellist, msg_t *message);
|
||||
|
||||
#endif // NET_SVC_H
|
|
@ -112,7 +112,7 @@ client_LIB_DEPS= libqfnet.la libasm.la $(qf_client_LIBS)
|
|||
client_sources= cl_cam.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c cl_input.c \
|
||||
cl_main.c cl_misc.c cl_ngraph.c cl_parse.c cl_pred.c \
|
||||
cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \
|
||||
console.c locs.c sbar.c skin.c teamplay.c
|
||||
console.c locs.c net_svc.c sbar.c skin.c teamplay.c
|
||||
|
||||
# Software-rendering clients
|
||||
|
||||
|
|
|
@ -883,12 +883,12 @@ CL_ConnectionlessPacket (void)
|
|||
Con_Printf ("Command packet from remote host. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
s = MSG_ReadString (net_message);
|
||||
s = MSG_ReadStaticString (net_message);
|
||||
|
||||
strncpy (cmdtext, s, sizeof (cmdtext) - 1);
|
||||
cmdtext[sizeof (cmdtext) - 1] = 0;
|
||||
|
||||
s = MSG_ReadString (net_message);
|
||||
s = MSG_ReadStaticString (net_message);
|
||||
|
||||
while (*s && isspace ((int) *s))
|
||||
s++;
|
||||
|
@ -923,7 +923,7 @@ CL_ConnectionlessPacket (void)
|
|||
}
|
||||
// print command from somewhere
|
||||
if (c == A2C_PRINT) {
|
||||
s = MSG_ReadString (net_message);
|
||||
s = MSG_ReadStaticString (net_message);
|
||||
if (SL_CheckStatus(NET_AdrToString (net_from), s))
|
||||
{
|
||||
Con_Printf("status response\n");
|
||||
|
@ -952,7 +952,7 @@ CL_ConnectionlessPacket (void)
|
|||
if (c == S2C_CHALLENGE) {
|
||||
Con_Printf ("challenge\n");
|
||||
|
||||
s = MSG_ReadString (net_message);
|
||||
s = MSG_ReadStaticString (net_message);
|
||||
cls.challenge = atoi (s);
|
||||
if (strstr (s, "QF"))
|
||||
CL_AddQFInfoKeys ();
|
||||
|
@ -964,7 +964,7 @@ CL_ConnectionlessPacket (void)
|
|||
{
|
||||
Con_Printf("Master Server Reply\n");
|
||||
clcp_temp = MSG_ReadByte (net_message);
|
||||
s = MSG_ReadString (net_message);
|
||||
s = MSG_ReadStaticString (net_message);
|
||||
MSL_ParseServerList(s);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ static const char rcsid[] =
|
|||
#include "client.h"
|
||||
#include "compat.h"
|
||||
#include "host.h"
|
||||
#include "net_svc.h"
|
||||
#include "pmove.h"
|
||||
#include "protocol.h"
|
||||
#include "sbar.h"
|
||||
|
@ -427,7 +428,7 @@ CL_ParseDownload (void)
|
|||
}
|
||||
|
||||
if (size == -2) {
|
||||
char *newname = MSG_ReadString (net_message);
|
||||
const char *newname = MSG_ReadString (net_message);
|
||||
|
||||
if (strncmp (newname, cls.downloadname, strlen (cls.downloadname))
|
||||
|| strstr (newname + strlen (cls.downloadname), "/")) {
|
||||
|
@ -612,7 +613,7 @@ void
|
|||
CL_ParseServerData (void)
|
||||
{
|
||||
char fn[MAX_OSPATH];
|
||||
char *str;
|
||||
const char *str;
|
||||
int protover;
|
||||
qboolean cflag = false;
|
||||
|
||||
|
@ -724,16 +725,15 @@ CL_ClearBaselines (void)
|
|||
void
|
||||
CL_ParseSoundlist (void)
|
||||
{
|
||||
char *str;
|
||||
int numsounds, n;
|
||||
const char *str;
|
||||
int numsounds, i;
|
||||
net_svc_soundlist_t soundlist;
|
||||
|
||||
// precache sounds
|
||||
// memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
|
||||
NET_SVC_Soundlist_Parse (&soundlist, net_message);
|
||||
|
||||
numsounds = MSG_ReadByte (net_message);
|
||||
|
||||
for (;;) {
|
||||
str = MSG_ReadString (net_message);
|
||||
for (i = 0, numsounds = soundlist.startsound;; i++) {
|
||||
str = soundlist.sounds[i];
|
||||
if (!str[0])
|
||||
break;
|
||||
numsounds++;
|
||||
|
@ -742,12 +742,11 @@ CL_ParseSoundlist (void)
|
|||
strcpy (cl.sound_name[numsounds], str);
|
||||
}
|
||||
|
||||
n = MSG_ReadByte (net_message);
|
||||
|
||||
if (n) {
|
||||
if (soundlist.nextsound) {
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message,
|
||||
va (soundlist_name, cl.servercount, n));
|
||||
va (soundlist_name, cl.servercount,
|
||||
soundlist.nextsound));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -759,44 +758,45 @@ CL_ParseSoundlist (void)
|
|||
void
|
||||
CL_ParseModellist (void)
|
||||
{
|
||||
int nummodels, n;
|
||||
char *str;
|
||||
int nummodels, i;
|
||||
const char *str;
|
||||
net_svc_modellist_t modellist;
|
||||
|
||||
// precache models and note certain default indexes
|
||||
nummodels = MSG_ReadByte (net_message);
|
||||
NET_SVC_Modellist_Parse (&modellist, net_message);
|
||||
|
||||
for (;;) {
|
||||
str = MSG_ReadString (net_message);
|
||||
for (i = 0, nummodels = modellist.startmodel;; i++) {
|
||||
str = modellist.models[i];
|
||||
if (!str[0])
|
||||
break;
|
||||
nummodels++;
|
||||
if (nummodels == MAX_MODELS)
|
||||
Host_EndGame ("Server sent too many model_precache");
|
||||
strcpy (cl.model_name[nummodels], str);
|
||||
strncpy (cl.model_name[nummodels], str, MAX_QPATH - 1);
|
||||
cl.model_name[nummodels][MAX_QPATH - 1] = '\0';
|
||||
|
||||
if (!strcmp (cl.model_name[nummodels], "progs/spike.mdl"))
|
||||
if (!strcmp (str, "progs/spike.mdl"))
|
||||
cl_spikeindex = nummodels;
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/player.mdl"))
|
||||
else if (!strcmp (str, "progs/player.mdl"))
|
||||
cl_playerindex = nummodels;
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/flag.mdl"))
|
||||
else if (!strcmp (str, "progs/flag.mdl"))
|
||||
cl_flagindex = nummodels;
|
||||
// for deadbodyfilter & gibfilter
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/h_player.mdl"))
|
||||
else if (!strcmp (str, "progs/h_player.mdl"))
|
||||
cl_h_playerindex = nummodels;
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/gib1.mdl"))
|
||||
else if (!strcmp (str, "progs/gib1.mdl"))
|
||||
cl_gib1index = nummodels;
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/gib2.mdl"))
|
||||
else if (!strcmp (str, "progs/gib2.mdl"))
|
||||
cl_gib2index = nummodels;
|
||||
else if (!strcmp (cl.model_name[nummodels], "progs/gib3.mdl"))
|
||||
else if (!strcmp (str, "progs/gib3.mdl"))
|
||||
cl_gib3index = nummodels;
|
||||
}
|
||||
|
||||
n = MSG_ReadByte (net_message);
|
||||
|
||||
if (n) {
|
||||
if (modellist.nextmodel) {
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message,
|
||||
va (modellist_name, cl.servercount, n));
|
||||
va (modellist_name, cl.servercount,
|
||||
modellist.nextmodel));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1099,7 +1099,7 @@ int received_framecount;
|
|||
void
|
||||
CL_ParseServerMessage (void)
|
||||
{
|
||||
char *s;
|
||||
const char *s;
|
||||
int cmd, i, j;
|
||||
|
||||
received_framecount = host_framecount;
|
||||
|
@ -1151,18 +1151,24 @@ CL_ParseServerMessage (void)
|
|||
Host_EndGame ("Server disconnected");
|
||||
break;
|
||||
|
||||
case svc_print:
|
||||
case svc_print: {
|
||||
char p[2048];
|
||||
int j;
|
||||
i = MSG_ReadByte (net_message);
|
||||
s = MSG_ReadString (net_message);
|
||||
if (i == PRINT_CHAT) {
|
||||
// TODO: cl_nofake 2 -- accept fake messages from
|
||||
// teammates
|
||||
char *p;
|
||||
|
||||
if (cl_nofake->int_val) {
|
||||
for (p = s; *p; p++)
|
||||
if (*p == 13)
|
||||
*p = '#';
|
||||
do {
|
||||
p[j] = (s[j] == 13) ? '#' : s[j];
|
||||
if (j == sizeof (p) - 1) {
|
||||
p[j] = '\0';
|
||||
break;
|
||||
}
|
||||
} while (s[j++]);
|
||||
s = p;
|
||||
}
|
||||
con_ormask = 128;
|
||||
S_LocalSound ("misc/talk.wav");
|
||||
|
@ -1170,7 +1176,7 @@ CL_ParseServerMessage (void)
|
|||
Con_Printf ("%s", s);
|
||||
con_ormask = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
case svc_centerprint:
|
||||
SCR_CenterPrint (MSG_ReadString (net_message));
|
||||
break;
|
||||
|
|
|
@ -411,7 +411,7 @@ Analyze_Server_Packet (const byte * data, int len)
|
|||
void
|
||||
Parse_Server_Packet ()
|
||||
{
|
||||
char *s;
|
||||
const char *s;
|
||||
int c, i, ii, iii, mask1, mask2;
|
||||
long seq1, seq2;
|
||||
|
||||
|
@ -626,7 +626,7 @@ Parse_Server_Packet ()
|
|||
Net_LogPrintf ("**QW OBSOLETE**");
|
||||
break;
|
||||
case svc_centerprint:
|
||||
Net_LogPrintf (MSG_ReadString (&packet));
|
||||
Net_LogPrintf ("%s", MSG_ReadString (&packet));
|
||||
break;
|
||||
case svc_killedmonster:
|
||||
break;
|
||||
|
|
87
qw/source/net_svc.c
Normal file
87
qw/source/net_svc.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
net_svc.c
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 2001 Adam Olsen
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
# ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#else
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/msg.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "net_svc.h"
|
||||
|
||||
void
|
||||
NET_SVC_Soundlist_Parse (net_svc_soundlist_t *soundlist, msg_t *message)
|
||||
{
|
||||
int i;
|
||||
|
||||
soundlist->startsound = MSG_ReadByte (message);
|
||||
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
soundlist->sounds[i] = MSG_ReadString (message);
|
||||
if (!*soundlist->sounds[i])
|
||||
break;
|
||||
}
|
||||
// this is a bit redundant, but I think the robustness is a good thing
|
||||
soundlist->sounds[MAX_SOUNDS] = "";
|
||||
|
||||
soundlist->nextsound = MSG_ReadByte (message);
|
||||
}
|
||||
|
||||
void
|
||||
NET_SVC_Modellist_Parse (net_svc_modellist_t *modellist, msg_t *message)
|
||||
{
|
||||
int i;
|
||||
|
||||
modellist->startmodel = MSG_ReadByte (message);
|
||||
|
||||
for (i = 0; i < MAX_MODELS; i++) {
|
||||
modellist->models[i] = MSG_ReadString (message);
|
||||
if (!*modellist->models[i])
|
||||
break;
|
||||
}
|
||||
// this is a bit redundant, but I think the robustness is a good thing
|
||||
modellist->models[MAX_MODELS] = "";
|
||||
|
||||
modellist->nextmodel = MSG_ReadByte (message);
|
||||
}
|
||||
|
|
@ -1673,7 +1673,7 @@ void
|
|||
SV_ExecuteClientMessage (client_t *cl)
|
||||
{
|
||||
int c;
|
||||
char *s;
|
||||
const char *s;
|
||||
usercmd_t oldest, oldcmd, newcmd;
|
||||
client_frame_t *frame;
|
||||
vec3_t o;
|
||||
|
|
Loading…
Reference in a new issue