This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/client/cl_parse.c

738 lines
16 KiB
C
Raw Normal View History

2007-06-21 22:00:00 +02:00
/*
Copyright (C) 1997-2001 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 the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// cl_parse.c -- parse a message received from the server
#include "client.h"
char *svc_strings[256] =
{
"svc_bad",
"svc_temp_entity",
"svc_layout",
"svc_inventory",
"svc_nop",
"svc_disconnect",
"svc_reconnect",
"svc_sound",
2008-05-18 22:00:00 +02:00
"svc_ambientsound",
2007-06-21 22:00:00 +02:00
"svc_print",
"svc_stufftext",
"svc_serverdata",
"svc_configstring",
"svc_spawnbaseline",
"svc_centerprint",
"svc_download",
"svc_playerinfo",
"svc_packetentities",
"svc_deltapacketentities",
"svc_frame"
};
//=============================================================================
void CL_DownloadFileName(char *dest, int destlen, char *fn)
{
strncpy(dest, fn, destlen );
}
/*
===============
CL_CheckOrDownloadFile
Returns true if the file exists, otherwise it attempts
to start a download from the server.
===============
*/
bool CL_CheckOrDownloadFile (char *filename)
{
file_t *fp;
char name[MAX_SYSPATH];
if (strstr (filename, ".."))
{
2007-07-28 22:00:00 +02:00
Msg ("Refusing to download a path with ..\n");
2007-06-21 22:00:00 +02:00
return true;
}
if (FS_LoadFile (filename, NULL))
{
// it exists, no need to download
return true;
}
strcpy (cls.downloadname, filename);
2007-08-01 22:00:00 +02:00
strcpy (cls.downloadtempname, filename);
2007-06-21 22:00:00 +02:00
// download to a temp name, and only rename
// to the real name when done, so if interrupted
// a runt file wont be left
2007-08-01 22:00:00 +02:00
FS_StripExtension (cls.downloadtempname);
FS_DefaultExtension(cls.downloadtempname, ".tmp");
2007-06-21 22:00:00 +02:00
//ZOID
// check to see if we already have a tmp for this file, if so, try to resume
// open the file if not opened yet
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
fp = FS_Open(name, "r+b");
if (fp)
{
// it exists
int len;
FS_Seek(fp, 0, SEEK_END);
len = FS_Tell(fp);
cls.download = fp;
// give the server an offset to start the download
2007-07-28 22:00:00 +02:00
Msg ("Resuming %s\n", cls.downloadname);
2007-06-21 22:00:00 +02:00
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("download %s %i", cls.downloadname, len));
}
else
{
2007-07-28 22:00:00 +02:00
Msg ("Downloading %s\n", cls.downloadname);
2007-06-21 22:00:00 +02:00
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
}
cls.downloadnumber++;
return false;
}
/*
===============
CL_Download_f
Request a download from the server
===============
*/
void CL_Download_f (void)
{
char filename[MAX_OSPATH];
if (Cmd_Argc() != 2)
{
2007-07-28 22:00:00 +02:00
Msg("Usage: download <filename>\n");
2007-06-21 22:00:00 +02:00
return;
}
2007-08-11 22:00:00 +02:00
sprintf(filename, "%s", Cmd_Argv(1));
2007-06-21 22:00:00 +02:00
if (strstr (filename, ".."))
{
2007-07-28 22:00:00 +02:00
Msg ("Refusing to download a path with ..\n");
2007-06-21 22:00:00 +02:00
return;
}
if (FS_LoadFile (filename, NULL))
{
// it exists, no need to download
2007-07-28 22:00:00 +02:00
Msg("File already exists.\n");
2007-06-21 22:00:00 +02:00
return;
}
strcpy (cls.downloadname, filename);
2007-08-01 22:00:00 +02:00
strcpy (cls.downloadtempname, filename);
2007-07-28 22:00:00 +02:00
Msg ("Downloading %s\n", cls.downloadname);
2007-06-21 22:00:00 +02:00
// download to a temp name, and only rename
// to the real name when done, so if interrupted
// a runt file wont be left
2007-08-01 22:00:00 +02:00
// download to a temp name, and only rename
// to the real name when done, so if interrupted
// a runt file wont be left
FS_StripExtension (cls.downloadtempname);
FS_DefaultExtension(cls.downloadtempname, ".tmp");
2007-06-21 22:00:00 +02:00
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message,
va("download %s", cls.downloadname));
cls.downloadnumber++;
}
/*
======================
CL_RegisterSounds
======================
*/
void CL_RegisterSounds (void)
{
int i;
2007-11-01 22:00:00 +01:00
S_BeginRegistration();
2007-06-21 22:00:00 +02:00
CL_RegisterTEntSounds ();
2007-11-01 22:00:00 +01:00
for (i = 1; i < MAX_SOUNDS; i++)
2007-06-21 22:00:00 +02:00
{
2007-11-01 22:00:00 +01:00
if (!cl.configstrings[CS_SOUNDS+i][0]) break;
2007-06-21 22:00:00 +02:00
cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);
2007-11-01 22:00:00 +01:00
Sys_SendKeyEvents (); // pump message loop
2007-06-21 22:00:00 +02:00
}
2007-11-01 22:00:00 +01:00
S_EndRegistration();
2007-06-21 22:00:00 +02:00
}
/*
=====================
CL_ParseDownload
A download message has been received from the server
=====================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseDownload( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
int size, percent;
2008-05-20 22:00:00 +02:00
string name;
2007-06-21 22:00:00 +02:00
int r;
// read the data
2008-05-20 22:00:00 +02:00
size = MSG_ReadShort( msg );
percent = MSG_ReadByte( msg );
2007-06-21 22:00:00 +02:00
if (size == -1)
{
2008-05-20 22:00:00 +02:00
Msg("Server does not have this file.\n");
2007-06-21 22:00:00 +02:00
if (cls.download)
{
// if here, we tried to resume a file but the server said no
2008-05-20 22:00:00 +02:00
FS_Close(cls.download);
2007-06-21 22:00:00 +02:00
cls.download = NULL;
}
CL_RequestNextDownload ();
return;
}
// open the file if not opened yet
if (!cls.download)
{
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
cls.download = FS_Open (name, "wb");
if (!cls.download)
{
2008-05-20 22:00:00 +02:00
msg->readcount += size;
2007-07-28 22:00:00 +02:00
Msg ("Failed to open %s\n", cls.downloadtempname);
2007-06-21 22:00:00 +02:00
CL_RequestNextDownload ();
return;
}
}
2008-05-20 22:00:00 +02:00
FS_Write (cls.download, msg->data + msg->readcount, size );
msg->readcount += size;
2007-06-21 22:00:00 +02:00
if (percent != 100)
{
// request next block
cls.downloadpercent = percent;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "nextdl");
}
else
{
char oldn[MAX_OSPATH];
char newn[MAX_OSPATH];
FS_Close (cls.download);
// rename the temp file to it's final name
CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname);
CL_DownloadFileName(newn, sizeof(newn), cls.downloadname);
r = rename (oldn, newn);
if (r)
2007-07-28 22:00:00 +02:00
Msg ("failed to rename.\n");
2007-06-21 22:00:00 +02:00
cls.download = NULL;
cls.downloadpercent = 0;
// get another file if needed
CL_RequestNextDownload ();
}
}
/*
=====================================================================
SERVER CONNECTING MESSAGES
=====================================================================
*/
/*
==================
CL_ParseServerData
==================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseServerData( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2007-11-17 22:00:00 +01:00
char *str;
2007-06-21 22:00:00 +02:00
int i;
2007-10-19 22:00:00 +02:00
2007-11-17 22:00:00 +01:00
MsgDev(D_INFO, "Serverdata packet received.\n");
2007-09-10 22:00:00 +02:00
2007-11-04 22:00:00 +01:00
// wipe the client_t struct
2007-06-21 22:00:00 +02:00
CL_ClearState ();
cls.state = ca_connected;
2007-09-10 22:00:00 +02:00
// parse protocol version number
2008-05-20 22:00:00 +02:00
i = MSG_ReadLong( msg );
2007-06-21 22:00:00 +02:00
cls.serverProtocol = i;
2007-09-10 22:00:00 +02:00
if (i != PROTOCOL_VERSION) Host_Error("Server returned version %i, not %i", i, PROTOCOL_VERSION);
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
cl.servercount = MSG_ReadLong( msg );
2007-06-21 22:00:00 +02:00
// parse player entity number
2008-05-20 22:00:00 +02:00
cl.playernum = MSG_ReadShort( msg );
2007-06-21 22:00:00 +02:00
// get the full level name
2008-05-20 22:00:00 +02:00
str = MSG_ReadString( msg );
2007-06-21 22:00:00 +02:00
if (cl.playernum == -1)
2007-09-10 22:00:00 +02:00
{
// playing a cinematic or showing a pic, not a level
2007-11-06 22:00:00 +01:00
SCR_PlayCinematic( str, 0 );
2007-06-21 22:00:00 +02:00
}
else
{
// seperate the printfs so the server message can have a color
2007-11-08 22:00:00 +01:00
Msg("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
2007-06-21 22:00:00 +02:00
// need to prep refresh at next oportunity
cl.refresh_prepped = false;
}
}
/*
==================
CL_ParseBaseline
==================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseBaseline( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
entity_state_t *es;
2007-10-29 22:00:00 +01:00
int bits;
int newnum;
2007-06-21 22:00:00 +02:00
entity_state_t nullstate;
memset (&nullstate, 0, sizeof(nullstate));
2008-05-20 22:00:00 +02:00
newnum = CL_ParseEntityBits( msg, &bits );
2007-06-21 22:00:00 +02:00
es = &cl_entities[newnum].baseline;
2008-05-20 22:00:00 +02:00
MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, bits);
2007-06-21 22:00:00 +02:00
}
/*
================
CL_LoadClientinfo
================
*/
void CL_LoadClientinfo (clientinfo_t *ci, char *s)
{
int i;
char *t;
char model_name[MAX_QPATH];
char skin_name[MAX_QPATH];
char model_filename[MAX_QPATH];
char weapon_filename[MAX_QPATH];
strncpy(ci->cinfo, s, sizeof(ci->cinfo));
ci->cinfo[sizeof(ci->cinfo)-1] = 0;
// isolate the player's name
strncpy(ci->name, s, sizeof(ci->name));
ci->name[sizeof(ci->name)-1] = 0;
t = strstr (s, "\\");
if (t)
{
ci->name[t-s] = 0;
s = t+1;
}
if (cl_noskins->value || *s == 0)
{
2007-09-14 22:00:00 +02:00
sprintf (model_filename, "models/players/gordon/player.mdl");
sprintf (weapon_filename, "models/weapons/w_glock.mdl");
2007-11-07 22:00:00 +01:00
strcpy (ci->iconname, "hud/i_fixme");
2007-08-17 22:00:00 +02:00
ci->model = re->RegisterModel (model_filename);
2007-06-21 22:00:00 +02:00
memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));
2007-08-17 22:00:00 +02:00
ci->weaponmodel[0] = re->RegisterModel (weapon_filename);
ci->icon = re->RegisterPic (ci->iconname);
2007-06-21 22:00:00 +02:00
}
else
{
// isolate the model name
strcpy (model_name, s);
t = strstr(model_name, "/");
2007-09-14 22:00:00 +02:00
if (!t) t = strstr(model_name, "\\");
if (!t) t = model_name;
2007-06-21 22:00:00 +02:00
*t = 0;
// isolate the skin name
strcpy (skin_name, s + strlen(model_name) + 1);
// model file
2007-09-14 22:00:00 +02:00
sprintf (model_filename, "models/players/%s/player.mdl", model_name);
2007-08-17 22:00:00 +02:00
ci->model = re->RegisterModel (model_filename);
2007-06-21 22:00:00 +02:00
if (!ci->model)
{
2007-09-14 22:00:00 +02:00
strcpy(model_name, "gordon");
sprintf (model_filename, "models/players/gordon/player.mdl");
2007-08-17 22:00:00 +02:00
ci->model = re->RegisterModel (model_filename);
2007-06-21 22:00:00 +02:00
}
// if we don't have the skin and the model wasn't male,
// see if the male has it (this is for CTF's skins)
2007-08-01 22:00:00 +02:00
if (!ci->skin && strcasecmp(model_name, "male"))
2007-06-21 22:00:00 +02:00
{
// change model to male
strcpy(model_name, "male");
2007-09-14 22:00:00 +02:00
sprintf (model_filename, "models/players/gordon/player.mdl");
2007-08-17 22:00:00 +02:00
ci->model = re->RegisterModel (model_filename);
2007-06-21 22:00:00 +02:00
}
// weapon file
2007-09-14 22:00:00 +02:00
for (i = 0; i < num_cl_weaponmodels; i++)
{
sprintf (weapon_filename, "models/weapons/%s", cl_weaponmodels[i]);
2007-08-17 22:00:00 +02:00
ci->weaponmodel[i] = re->RegisterModel(weapon_filename);
2007-09-14 22:00:00 +02:00
if (!cl_vwep->value) break; // only one when vwep is off
2007-06-21 22:00:00 +02:00
}
// icon file
2007-11-07 22:00:00 +01:00
strcpy (ci->iconname, "hud/i_fixme");
2007-08-17 22:00:00 +02:00
ci->icon = re->RegisterPic (ci->iconname);
2007-06-21 22:00:00 +02:00
}
// must have loaded all data types to be valud
if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0])
{
ci->skin = NULL;
ci->icon = NULL;
ci->model = NULL;
ci->weaponmodel[0] = NULL;
return;
}
}
/*
================
CL_ParseClientinfo
Load the skin, icon, and model for a client
================
*/
void CL_ParseClientinfo (int player)
{
char *s;
clientinfo_t *ci;
s = cl.configstrings[player+CS_PLAYERSKINS];
ci = &cl.clientinfo[player];
CL_LoadClientinfo (ci, s);
}
/*
================
CL_ParseConfigString
================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseConfigString( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
int i;
2008-05-20 22:00:00 +02:00
char *s;
string olds;
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
i = MSG_ReadShort( msg );
2007-09-10 22:00:00 +02:00
if (i < 0 || i >= MAX_CONFIGSTRINGS) Host_Error("configstring > MAX_CONFIGSTRINGS\n");
2008-05-20 22:00:00 +02:00
s = MSG_ReadString( msg );
2007-06-21 22:00:00 +02:00
strncpy (olds, cl.configstrings[i], sizeof(olds));
olds[sizeof(olds) - 1] = 0;
strcpy (cl.configstrings[i], s);
// do something apropriate
if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
{
2007-11-08 22:00:00 +01:00
CL_SetLightstyle (i - CS_LIGHTS);
2007-06-21 22:00:00 +02:00
}
else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
{
2008-01-13 22:00:00 +01:00
if(cl.refresh_prepped)
2007-06-21 22:00:00 +02:00
{
2007-08-17 22:00:00 +02:00
cl.model_draw[i-CS_MODELS] = re->RegisterModel (cl.configstrings[i]);
2007-06-21 22:00:00 +02:00
if (cl.configstrings[i][0] == '*')
2008-01-15 22:00:00 +01:00
cl.model_clip[i-CS_MODELS] = pe->RegisterModel(cl.configstrings[i] );
2008-01-13 22:00:00 +01:00
else cl.model_clip[i-CS_MODELS] = NULL;
2007-06-21 22:00:00 +02:00
}
}
else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS)
{
if (cl.refresh_prepped)
cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
}
else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_MODELS)
{
if (cl.refresh_prepped)
2007-08-17 22:00:00 +02:00
cl.image_precache[i-CS_IMAGES] = re->RegisterPic (cl.configstrings[i]);
2007-06-21 22:00:00 +02:00
}
else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
{
if (cl.refresh_prepped && strcmp(olds, s))
CL_ParseClientinfo (i-CS_PLAYERSKINS);
}
}
/*
=====================================================================
ACTION MESSAGES
=====================================================================
*/
/*
==================
CL_ParseStartSoundPacket
==================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseStartSoundPacket( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2008-05-20 22:00:00 +02:00
vec3_t pos_v;
2007-06-21 22:00:00 +02:00
float *pos;
2007-10-29 22:00:00 +01:00
int channel, ent;
int sound_num;
float volume;
float attenuation;
int flags;
2007-06-21 22:00:00 +02:00
float ofs;
2008-05-20 22:00:00 +02:00
flags = MSG_ReadByte( msg );
sound_num = MSG_ReadByte( msg );
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
if (flags & SND_VOLUME) volume = MSG_ReadByte( msg ) / 255.0;
2007-11-24 22:00:00 +01:00
else volume = DEFAULT_SOUND_PACKET_VOL;
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
if (flags & SND_ATTENUATION) attenuation = MSG_ReadByte( msg ) / 64.0;
2007-11-24 22:00:00 +01:00
else attenuation = DEFAULT_SOUND_PACKET_ATTN;
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
if (flags & SND_OFFSET) ofs = MSG_ReadByte( msg ) / 1000.0;
2007-10-29 22:00:00 +01:00
else ofs = 0;
2007-06-21 22:00:00 +02:00
if (flags & SND_ENT)
2007-09-10 22:00:00 +02:00
{
// entity reletive
2008-05-20 22:00:00 +02:00
channel = MSG_ReadShort( msg );
2007-06-21 22:00:00 +02:00
ent = channel>>3;
2007-09-10 22:00:00 +02:00
if (ent > MAX_EDICTS) Host_Error("CL_ParseStartSoundPacket: ent out of range\n" );
2007-06-21 22:00:00 +02:00
channel &= 7;
}
else
{
ent = 0;
channel = 0;
}
if (flags & SND_POS)
2007-10-29 22:00:00 +01:00
{
// positioned in space
2008-05-20 22:00:00 +02:00
MSG_ReadPos32( msg, pos_v);
2007-06-21 22:00:00 +02:00
pos = pos_v;
}
2007-10-29 22:00:00 +01:00
else pos = NULL; // use entity number
2007-06-21 22:00:00 +02:00
2007-10-29 22:00:00 +01:00
if (!cl.sound_precache[sound_num]) return;
2007-11-01 22:00:00 +01:00
S_StartSound (pos, ent, channel, cl.sound_precache[sound_num]);
2007-06-21 22:00:00 +02:00
}
2008-05-20 22:00:00 +02:00
void CL_ParseAmbientSound( sizebuf_t *msg )
2008-05-18 22:00:00 +02:00
{
sound_t loopSoundHandle;
int entityNum, soundNum;
vec3_t ambient_org;
2008-05-20 22:00:00 +02:00
entityNum = MSG_ReadShort( msg );
soundNum = MSG_ReadShort( msg );
MSG_ReadPos32( msg, ambient_org);
2008-05-18 22:00:00 +02:00
loopSoundHandle = S_RegisterSound( cl.configstrings[CS_SOUNDS + soundNum] );
// add ambient looping sound
S_AddRealLoopingSound( entityNum, ambient_org, vec3_origin, loopSoundHandle );
}
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
void SHOWNET( sizebuf_t *msg, char *s )
2007-06-21 22:00:00 +02:00
{
2008-05-20 22:00:00 +02:00
if (cl_shownet->value >= 2) Msg ("%3i:%s\n", msg->readcount-1, s);
2007-06-21 22:00:00 +02:00
}
/*
=====================
CL_ParseServerMessage
=====================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseServerMessage( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2007-08-17 22:00:00 +02:00
int i, cmd;
2007-06-21 22:00:00 +02:00
char *s;
2007-08-17 22:00:00 +02:00
// if recording demos, copy the message out
2008-05-20 22:00:00 +02:00
if (cl_shownet->value == 1) Msg ("%i ",msg->cursize);
2007-08-17 22:00:00 +02:00
else if (cl_shownet->value >= 2) Msg ("------------------\n");
2007-06-21 22:00:00 +02:00
2007-08-17 22:00:00 +02:00
// parse the message
2008-05-20 22:00:00 +02:00
while( 1 )
2007-06-21 22:00:00 +02:00
{
2008-05-20 22:00:00 +02:00
if (msg->readcount > msg->cursize)
2007-06-21 22:00:00 +02:00
{
2007-09-10 22:00:00 +02:00
Host_Error("CL_ParseServerMessage: Bad server message\n");
2007-06-21 22:00:00 +02:00
break;
}
2008-05-20 22:00:00 +02:00
cmd = MSG_ReadByte( msg );
2007-06-21 22:00:00 +02:00
if (cmd == -1)
{
2008-05-20 22:00:00 +02:00
SHOWNET( msg, "END OF MESSAGE" );
2007-06-21 22:00:00 +02:00
break;
}
2007-08-17 22:00:00 +02:00
if (cl_shownet->value >= 2)
2007-06-21 22:00:00 +02:00
{
2008-05-20 22:00:00 +02:00
if (!svc_strings[cmd]) Msg ("%3i:BAD CMD %i\n", msg->readcount - 1, cmd);
else SHOWNET( msg, svc_strings[cmd] );
2007-06-21 22:00:00 +02:00
}
2007-08-17 22:00:00 +02:00
// other commands
2007-06-21 22:00:00 +02:00
switch (cmd)
{
case svc_nop:
2007-07-28 22:00:00 +02:00
// Msg ("svc_nop\n");
2007-06-21 22:00:00 +02:00
break;
case svc_disconnect:
2007-09-10 22:00:00 +02:00
CL_Drop ();
Host_AbortCurrentFrame();
2007-06-21 22:00:00 +02:00
break;
case svc_reconnect:
2007-07-28 22:00:00 +02:00
Msg ("Server disconnected, reconnecting\n");
2007-06-21 22:00:00 +02:00
if (cls.download)
{
//ZOID, close download
FS_Close (cls.download);
cls.download = NULL;
}
cls.state = ca_connecting;
cls.connect_time = -99999; // CL_CheckForResend() will fire immediately
break;
case svc_print:
2008-05-20 22:00:00 +02:00
i = MSG_ReadByte( msg );
2007-11-24 22:00:00 +01:00
if (i == 3) S_StartLocalSound ("misc/talk.wav"); // chat
2008-05-20 22:00:00 +02:00
Msg ("^6%s", MSG_ReadString( msg ));
2007-06-21 22:00:00 +02:00
break;
case svc_centerprint:
2008-05-20 22:00:00 +02:00
CG_CenterPrint(MSG_ReadString( msg ), SCREEN_HEIGHT/2, BIGCHAR_WIDTH );
2007-06-21 22:00:00 +02:00
break;
case svc_stufftext:
2008-05-20 22:00:00 +02:00
s = MSG_ReadString( msg );
2007-06-21 22:00:00 +02:00
Cbuf_AddText (s);
break;
case svc_serverdata:
Cbuf_Execute (); // make sure any stuffed commands are done
2008-05-20 22:00:00 +02:00
CL_ParseServerData( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_configstring:
2008-05-20 22:00:00 +02:00
CL_ParseConfigString( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_sound:
2008-05-20 22:00:00 +02:00
CL_ParseStartSoundPacket( msg );
2007-06-21 22:00:00 +02:00
break;
2008-05-18 22:00:00 +02:00
case svc_ambientsound:
2008-05-20 22:00:00 +02:00
CL_ParseAmbientSound( msg );
2008-05-18 22:00:00 +02:00
break;
2007-06-21 22:00:00 +02:00
case svc_spawnbaseline:
2008-05-20 22:00:00 +02:00
CL_ParseBaseline( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_temp_entity:
2008-05-20 22:00:00 +02:00
CL_ParseTEnt( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_download:
2008-05-20 22:00:00 +02:00
CL_ParseDownload( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_frame:
2008-05-20 22:00:00 +02:00
CL_ParseFrame( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_inventory:
2008-05-20 22:00:00 +02:00
CG_ParseInventory( msg );
2007-06-21 22:00:00 +02:00
break;
case svc_layout:
2008-05-20 22:00:00 +02:00
s = MSG_ReadString( msg );
com.strncpy(cl.layout, s, sizeof(cl.layout)-1);
2007-06-21 22:00:00 +02:00
break;
case svc_playerinfo:
case svc_packetentities:
case svc_deltapacketentities:
2007-09-10 22:00:00 +02:00
Host_Error("Out of place frame data\n");
2007-06-21 22:00:00 +02:00
break;
2007-11-17 22:00:00 +01:00
default:
Host_Error("CL_ParseServerMessage: Illegible server message %d\n", cmd );
break;
2007-06-21 22:00:00 +02:00
}
}
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if (cls.demorecording && !cls.demowaiting)
2008-05-20 22:00:00 +02:00
CL_WriteDemoMessage();
2007-06-21 22:00:00 +02:00
}