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

679 lines
17 KiB
C
Raw Normal View History

2009-11-23 22:00:00 +01:00
//=======================================================================
// Copyright XashXT Group 2009 <20>
// cl_parse.c -- parse a message received from the server
//=======================================================================
2007-06-21 22:00:00 +02:00
2008-06-09 22:00:00 +02:00
#include "common.h"
2007-06-21 22:00:00 +02:00
#include "client.h"
2009-09-29 22:00:00 +02:00
#include "net_sound.h"
2007-06-21 22:00:00 +02:00
2009-11-25 22:00:00 +01:00
#define NET_TIMINGS 256
#define NET_TIMINGSMASK (NET_TIMINGS - 1)
2009-10-13 22:00:00 +02:00
char *svc_strings[256] =
{
"svc_bad",
2009-11-23 22:00:00 +01:00
// user messages space
2009-10-13 22:00:00 +02:00
"svc_nop",
"svc_disconnect",
"svc_reconnect",
"svc_stufftext",
"svc_serverdata",
"svc_configstring",
"svc_spawnbaseline",
"svc_download",
"svc_playerinfo",
2009-11-23 22:00:00 +01:00
"svc_physinfo",
2009-10-13 22:00:00 +02:00
"svc_packetentities",
"svc_frame",
"svc_sound",
"svc_setangle",
"svc_setview",
"svc_print",
2009-11-23 22:00:00 +01:00
"svc_centerprint",
2009-10-13 22:00:00 +02:00
"svc_crosshairangle",
2009-11-10 22:00:00 +01:00
"svc_setpause",
"svc_movevars",
2009-11-23 22:00:00 +01:00
"svc_particle",
"svc_soundfade",
2009-11-25 22:00:00 +01:00
"svc_bspdecal",
2009-12-02 22:00:00 +01:00
"svc_event",
"svc_event_reliable"
2009-10-13 22:00:00 +02:00
};
2009-11-25 22:00:00 +01:00
int packet_latency[NET_TIMINGS];
int packet_loss;
int CL_CalcNet( void )
{
int a, i;
frame_t *frame;
int lost = 0;
for( i = cls.netchan.outgoing_sequence - UPDATE_BACKUP + 1; i <= cls.netchan.outgoing_sequence; i++ )
{
frame = &cl.frames[i & UPDATE_MASK];
if( frame->recvtime == -1 )
packet_latency[i & NET_TIMINGSMASK] = 9999; // dropped
else if( frame->recvtime == -2 )
packet_latency[i & NET_TIMINGSMASK] = 10000; // choked
else if( !frame->valid )
packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta
else packet_latency[i & NET_TIMINGSMASK] = (frame->recvtime - frame->senttime) * 20;
}
for( a = 0; a < NET_TIMINGS; a++ )
{
i = (cls.netchan.outgoing_sequence - a) & NET_TIMINGSMASK;
if( packet_latency[i] == 9999 ) lost++;
}
packet_loss = lost * 100 / NET_TIMINGS;
return packet_loss;
}
2007-06-21 22:00:00 +02:00
/*
===============
CL_CheckOrDownloadFile
Returns true if the file exists, otherwise it attempts
to start a download from the server.
===============
*/
2008-08-02 22:00:00 +02:00
bool CL_CheckOrDownloadFile( const char *filename )
2007-06-21 22:00:00 +02:00
{
2008-08-02 22:00:00 +02:00
string name;
file_t *f;
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
if( FS_FileExists( filename ))
2007-06-21 22:00:00 +02:00
{
// it exists, no need to download
return true;
}
2008-08-02 22:00:00 +02:00
com.strncpy( cls.downloadname, filename, MAX_STRING );
com.strncpy( cls.downloadtempname, filename, MAX_STRING );
2007-06-21 22:00:00 +02:00
2008-08-02 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 won't be left
FS_StripExtension( cls.downloadtempname );
FS_DefaultExtension( cls.downloadtempname, ".tmp" );
com.strncpy( name, cls.downloadtempname, MAX_STRING );
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
f = FS_Open( name, "a+b" );
if( f )
2007-06-21 22:00:00 +02:00
{
// it exists
2008-11-27 22:00:00 +01:00
size_t len = FS_Tell( f );
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
cls.download = f;
2007-06-21 22:00:00 +02:00
// give the server an offset to start the download
2008-08-02 22:00:00 +02:00
MsgDev( D_INFO, "Resume download %s at %i\n", cls.downloadname, len );
2008-07-15 22:00:00 +02:00
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
2008-08-02 22:00:00 +02:00
MSG_Print( &cls.netchan.message, va("download %s %i", cls.downloadname, len ));
2007-06-21 22:00:00 +02:00
}
else
{
2008-08-02 22:00:00 +02:00
MsgDev( D_INFO, "Start download %s\n", cls.downloadname );
2008-07-15 22:00:00 +02:00
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
2008-08-02 22:00:00 +02:00
MSG_Print( &cls.netchan.message, va("download %s", cls.downloadname ));
2007-06-21 22:00:00 +02:00
}
cls.downloadnumber++;
return false;
}
/*
=====================
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 );
2008-08-02 22:00:00 +02:00
if( size == -1 )
2007-06-21 22:00:00 +02:00
{
2008-08-02 22:00:00 +02:00
Msg( "Server does not have this file.\n" );
if( cls.download )
2007-06-21 22:00:00 +02:00
{
// if here, we tried to resume a file but the server said no
2008-08-02 22:00:00 +02:00
FS_Close( cls.download );
2007-06-21 22:00:00 +02:00
cls.download = NULL;
}
2008-08-02 22:00:00 +02:00
CL_RequestNextDownload();
2007-06-21 22:00:00 +02:00
return;
}
// open the file if not opened yet
2008-08-02 22:00:00 +02:00
if( !cls.download )
2007-06-21 22:00:00 +02:00
{
2008-08-02 22:00:00 +02:00
com.strncpy( name, cls.downloadtempname, MAX_STRING );
cls.download = FS_Open ( name, "wb" );
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
if( !cls.download )
2007-06-21 22:00:00 +02:00
{
2008-05-20 22:00:00 +02:00
msg->readcount += size;
2008-08-02 22:00:00 +02:00
Msg( "Failed to open %s\n", cls.downloadtempname );
CL_RequestNextDownload();
2007-06-21 22:00:00 +02:00
return;
}
}
2008-08-02 22:00:00 +02:00
FS_Write( cls.download, msg->data + msg->readcount, size );
2008-05-20 22:00:00 +02:00
msg->readcount += size;
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
if( percent != 100 )
2007-06-21 22:00:00 +02:00
{
// request next block
2008-08-03 22:00:00 +02:00
Cvar_SetValue("scr_download", percent );
2008-07-15 22:00:00 +02:00
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_Print( &cls.netchan.message, "nextdl" );
2007-06-21 22:00:00 +02:00
}
else
{
2008-07-23 22:00:00 +02:00
string oldn, newn;
2007-06-21 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
FS_Close( cls.download );
2007-06-21 22:00:00 +02:00
// rename the temp file to it's final name
2008-08-02 22:00:00 +02:00
com.strncpy( oldn, cls.downloadtempname, MAX_STRING );
com.strncpy( newn, cls.downloadname, MAX_STRING );
r = rename( oldn, newn );
if( r ) MsgDev( D_ERROR, "failed to rename.\n" );
2007-06-21 22:00:00 +02:00
cls.download = NULL;
2008-11-27 22:00:00 +01:00
Cvar_SetValue( "scr_download", 0.0f );
2007-06-21 22:00:00 +02:00
// get another file if needed
2008-08-02 22:00:00 +02:00
CL_RequestNextDownload();
}
}
2008-12-03 22:00:00 +01:00
void CL_RunBackgroundTrack( void )
{
string intro, main, track;
// run background track
com.strncpy( track, cl.configstrings[CS_BACKGROUND_TRACK], MAX_STRING );
com.snprintf( intro, MAX_STRING, "%s_intro", cl.configstrings[CS_BACKGROUND_TRACK] );
com.snprintf( main, MAX_STRING, "%s_main", cl.configstrings[CS_BACKGROUND_TRACK] );
if( FS_FileExists( va( "media/%s.ogg", intro )) && FS_FileExists( va( "media/%s.ogg", main )))
{
// combined track with introduction and main loop theme
S_StartBackgroundTrack( intro, main );
}
else if( FS_FileExists( va( "media/%s.ogg", track )))
{
// single looped theme
S_StartBackgroundTrack( track, track );
}
else if( !com.strcmp( track, "" ))
{
// blank name stopped last track
S_StopBackgroundTrack();
}
}
2008-12-21 22:00:00 +01:00
/*
==================
CL_ParseSoundPacket
==================
*/
void CL_ParseSoundPacket( sizebuf_t *msg )
{
2009-10-11 22:00:00 +02:00
vec3_t pos_;
float *pos = NULL;
2008-12-21 22:00:00 +01:00
int channel, sound_num;
float volume, attenuation;
int flags, pitch, entnum;
2009-09-29 22:00:00 +02:00
flags = MSG_ReadWord( msg );
2008-12-21 22:00:00 +01:00
sound_num = MSG_ReadWord( msg );
channel = MSG_ReadByte( msg );
2009-09-29 22:00:00 +02:00
if( flags & SND_VOLUME )
2008-12-21 22:00:00 +01:00
volume = MSG_ReadByte( msg ) / 255.0f;
2009-09-29 22:00:00 +02:00
else volume = VOL_NORM;
if( flags & SND_SOUNDLEVEL )
{
int soundlevel = MSG_ReadByte( msg );
attenuation = SNDLVL_TO_ATTN( soundlevel );
}
else attenuation = ATTN_NONE;
2008-12-21 22:00:00 +01:00
if( flags & SND_PITCH )
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
2009-10-22 22:00:00 +02:00
entnum = MSG_ReadWord( msg );
2008-12-21 22:00:00 +01:00
2009-09-29 22:00:00 +02:00
// positioned in space
2009-10-11 22:00:00 +02:00
if( flags & SND_FIXED_ORIGIN )
{
pos = pos_;
MSG_ReadPos( msg, pos );
}
S_StartSound( pos, entnum, channel, cl.sound_precache[sound_num], volume, attenuation, pitch, flags );
2008-12-21 22:00:00 +01:00
}
2009-11-10 22:00:00 +01:00
/*
==================
CL_ParseMovevars
==================
*/
void CL_ParseMovevars( sizebuf_t *msg )
{
MSG_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
Mem_Copy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
}
2009-11-23 22:00:00 +01:00
/*
==================
CL_ParseParticles
==================
*/
void CL_ParseParticles( sizebuf_t *msg )
{
vec3_t org, dir;
int i, count, color;
MSG_ReadPos( msg, org );
for( i = 0; i < 3; i++ )
dir[i] = MSG_ReadChar( msg ) * (1.0f / 16);
count = MSG_ReadByte( msg );
color = MSG_ReadByte( msg );
CL_ParticleEffect( org, dir, color, count );
}
/*
==================
CL_ParseStaticDecal
==================
*/
void CL_ParseStaticDecal( sizebuf_t *msg )
{
vec3_t origin;
int decalIndex, entityIndex, modelIndex;
MSG_ReadPos( msg, origin );
decalIndex = MSG_ReadWord( msg );
entityIndex = MSG_ReadShort( msg );
2009-11-25 22:00:00 +01:00
if( entityIndex > 0 )
modelIndex = MSG_ReadWord( msg );
2009-11-23 22:00:00 +01:00
CL_SpawnStaticDecal( origin, decalIndex, entityIndex, modelIndex );
}
2009-11-25 22:00:00 +01:00
void CL_ParseSoundFade( sizebuf_t *msg )
{
float fadePercent, fadeOutSeconds;
float holdTime, fadeInSeconds;
fadePercent = MSG_ReadFloat( msg );
fadeOutSeconds = MSG_ReadFloat( msg );
holdTime = MSG_ReadFloat( msg );
fadeInSeconds = MSG_ReadFloat( msg );
S_FadeClientVolume( fadePercent, fadeOutSeconds, holdTime, fadeInSeconds );
}
2009-12-02 22:00:00 +01:00
void CL_ParseReliableEvent( sizebuf_t *msg, int flags )
{
int event_index;
event_args_t nullargs, args;
float delay;
Mem_Set( &nullargs, 0, sizeof( nullargs ));
event_index = MSG_ReadWord( msg ); // read event index
delay = MSG_ReadWord( msg ) / 100.0f; // read event delay
MSG_ReadDeltaEvent( msg, &nullargs, &args ); // FIXME: zero-compressing
CL_QueueEvent( flags, event_index, delay, &args );
}
void CL_ParseEvent( sizebuf_t *msg )
{
int i, num_events;
num_events = MSG_ReadByte( msg );
// parse events queue
for( i = 0 ; i < num_events; i++ )
CL_ParseReliableEvent( msg, 0 );
}
2007-06-21 22:00:00 +02:00
/*
=====================================================================
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
{
2009-10-11 22:00:00 +02:00
string str;
2009-07-27 22:00:00 +02:00
const char *levelshot_ext[] = { "tga", "jpg", "png" };
2007-06-21 22:00:00 +02:00
int i;
2007-10-19 22:00:00 +02:00
2009-09-28 22:00:00 +02:00
MsgDev( D_NOTE, "Serverdata packet received.\n" );
2008-07-11 22:00:00 +02:00
2007-11-04 22:00:00 +01:00
// wipe the client_t struct
2008-07-12 22:00:00 +02:00
CL_ClearState();
2007-06-21 22:00:00 +02:00
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;
2008-08-02 22:00:00 +02:00
if( i != PROTOCOL_VERSION )
2009-06-24 22:00:00 +02:00
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
cl.servercount = MSG_ReadLong( msg );
2009-11-27 22:00:00 +01:00
cl.playernum = MSG_ReadByte( msg );
clgame.globals->maxClients = MSG_ReadByte( msg );
clgame.globals->maxEntities = MSG_ReadWord( msg );
2009-09-28 22:00:00 +02:00
com.strncpy( str, MSG_ReadString( msg ), MAX_STRING );
2009-10-11 22:00:00 +02:00
com.strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
2007-06-21 22:00:00 +02:00
2009-11-27 22:00:00 +01:00
CL_InitEdicts (); // re-arrange edicts
2008-08-02 22:00:00 +02:00
// get splash name
2009-07-27 22:00:00 +02:00
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s", str ));
2008-12-06 22:00:00 +01:00
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
2009-07-27 22:00:00 +02:00
for( i = 0; i < 3; i++ )
if( FS_FileExists( va( "%s.%s", cl_levelshot_name->string, levelshot_ext[i] )))
break;
if( i == 3 )
2007-06-21 22:00:00 +02:00
{
2009-08-20 22:00:00 +02:00
Cvar_Set( "cl_levelshot_name", MAP_DEFAULT_SHADER ); // render a black screen
2009-09-23 22:00:00 +02:00
cls.scrshot_request = scrshot_plaque; // make levelshot
2007-06-21 22:00:00 +02:00
}
2008-08-02 22:00:00 +02:00
// seperate the printfs so the server message can have a color
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");
2009-10-11 22:00:00 +02:00
Msg( "^2%s\n", clgame.maptitle );
2008-08-03 22:00:00 +02:00
2008-08-02 22:00:00 +02:00
// need to prep refresh at next oportunity
2008-08-03 22:00:00 +02:00
cl.video_prepped = false;
cl.audio_prepped = false;
2009-11-28 22:00:00 +01:00
// initialize world and clients
CL_InitWorld ();
2007-06-21 22:00:00 +02:00
}
/*
==================
CL_ParseBaseline
==================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseBaseline( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2007-10-29 22:00:00 +01:00
int newnum;
2007-06-21 22:00:00 +02:00
entity_state_t nullstate;
2009-11-28 22:00:00 +01:00
entity_state_t *baseline;
2009-11-27 22:00:00 +01:00
edict_t *ent;
2007-06-21 22:00:00 +02:00
2008-12-25 22:00:00 +01:00
Mem_Set( &nullstate, 0, sizeof( nullstate ));
2009-10-22 22:00:00 +02:00
newnum = MSG_ReadWord( msg );
2008-07-01 22:00:00 +02:00
2009-11-27 22:00:00 +01:00
if( newnum < 0 ) Host_Error( "CL_SpawnEdict: invalid number %i\n", newnum );
if( newnum > clgame.globals->maxEntities ) Host_Error( "CL_AllocEdict: no free edicts\n" );
// increase edicts
while( newnum >= clgame.globals->numEntities )
clgame.globals->numEntities++;
ent = EDICT_NUM( newnum );
2009-11-28 22:00:00 +01:00
if( ent->free ) CL_InitEdict( ent ); // initialize edict
2009-09-25 22:00:00 +02:00
2009-11-28 22:00:00 +01:00
baseline = &clgame.baselines[newnum];
MSG_ReadDeltaEntity( msg, &nullstate, baseline, newnum );
CL_LinkEdict( ent, false ); // first entering, link always
2007-06-21 22:00:00 +02:00
}
/*
================
CL_ParseConfigString
================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseConfigString( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2008-08-04 22:00:00 +02:00
int i;
2007-06-21 22:00:00 +02:00
2008-05-20 22:00:00 +02:00
i = MSG_ReadShort( msg );
2008-08-02 22:00:00 +02:00
if( i < 0 || i >= MAX_CONFIGSTRINGS )
2009-01-04 22:00:00 +01:00
Host_Error( "configstring > MAX_CONFIGSTRINGS\n" );
2008-08-02 22:00:00 +02:00
com.strcpy( cl.configstrings[i], MSG_ReadString( msg ));
2009-01-04 22:00:00 +01:00
2007-06-21 22:00:00 +02:00
// do something apropriate
2008-11-28 22:00:00 +01:00
if( i == CS_SKYNAME && cl.video_prepped )
2007-06-21 22:00:00 +02:00
{
2009-07-26 22:00:00 +02:00
re->RegisterShader( cl.configstrings[CS_SKYNAME], SHADER_SKY );
2008-08-04 22:00:00 +02:00
}
2009-11-10 22:00:00 +01:00
else if( i == CS_SERVERFLAGS )
2009-01-11 22:00:00 +01:00
{
2009-11-10 22:00:00 +01:00
// update shared serverflags
clgame.globals->serverflags = com.atoi( cl.configstrings[CS_SERVERFLAGS] );
}
else if( i > CS_SERVERFLAGS && i < CS_MODELS )
{
Host_Error( "CL_ParseConfigString: reserved configstring #%i are used\n", i );
2009-01-11 22:00:00 +01:00
}
2008-11-28 22:00:00 +01:00
else if( i == CS_BACKGROUND_TRACK && cl.audio_prepped )
{
2008-12-03 22:00:00 +01:00
CL_RunBackgroundTrack();
2008-11-28 22:00:00 +01:00
}
2008-08-04 22:00:00 +02:00
else if( i >= CS_MODELS && i < CS_MODELS+MAX_MODELS && cl.video_prepped )
{
re->RegisterModel( cl.configstrings[i], i-CS_MODELS );
2009-10-29 22:00:00 +01:00
CM_RegisterModel( cl.configstrings[i], i-CS_MODELS );
2007-06-21 22:00:00 +02:00
}
2008-08-04 22:00:00 +02:00
else if( i >= CS_SOUNDS && i < CS_SOUNDS+MAX_SOUNDS && cl.audio_prepped )
2007-06-21 22:00:00 +02:00
{
2008-08-04 22:00:00 +02:00
cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound( cl.configstrings[i] );
2007-06-21 22:00:00 +02:00
}
2008-12-15 22:00:00 +01:00
else if( i >= CS_DECALS && i < CS_DECALS+MAX_DECALS && cl.video_prepped )
{
2009-01-16 22:00:00 +01:00
cl.decal_shaders[i-CS_DECALS] = re->RegisterShader( cl.configstrings[i], SHADER_GENERIC );
2008-12-15 22:00:00 +01:00
}
else if( i >= CS_USER_MESSAGES && i < CS_USER_MESSAGES+MAX_USER_MESSAGES )
{
2008-12-26 22:00:00 +01:00
CL_LinkUserMessage( cl.configstrings[i], i - CS_USER_MESSAGES );
2008-12-15 22:00:00 +01:00
}
2009-12-02 22:00:00 +01:00
else if( i >= CS_EVENTS && i < CS_EVENTS+MAX_EVENTS )
{
CL_SetEventIndex( cl.configstrings[i], i - CS_EVENTS );
}
2008-08-02 22:00:00 +02:00
else if( i >= CS_CLASSNAMES && i < CS_CLASSNAMES+MAX_CLASSNAMES )
2007-06-21 22:00:00 +02:00
{
2008-12-25 22:00:00 +01:00
// edicts classnames for search by classname on client
cl.edict_classnames[i-CS_CLASSNAMES] = MAKE_STRING( cl.configstrings[i] );
2007-06-21 22:00:00 +02:00
}
2008-08-02 22:00:00 +02:00
else if( i >= CS_LIGHTSTYLES && i < CS_LIGHTSTYLES+MAX_LIGHTSTYLES )
2007-06-21 22:00:00 +02:00
{
2008-08-02 22:00:00 +02:00
CL_SetLightstyle( i - CS_LIGHTSTYLES );
2007-06-21 22:00:00 +02:00
}
}
2008-11-27 22:00:00 +01:00
/*
================
CL_ParseSetAngle
set the view angle to this absolute value
================
*/
void CL_ParseSetAngle( sizebuf_t *msg )
{
2009-09-13 22:00:00 +02:00
cl.refdef.cl_viewangles[0] = MSG_ReadAngle32( msg );
cl.refdef.cl_viewangles[1] = MSG_ReadAngle32( msg );
cl.refdef.cl_viewangles[2] = MSG_ReadAngle32( msg );
2008-11-27 22:00:00 +01:00
}
2007-06-21 22:00:00 +02:00
2009-01-23 22:00:00 +01:00
/*
================
CL_ParseCrosshairAngle
offset crosshair angles
================
*/
void CL_ParseCrosshairAngle( sizebuf_t *msg )
{
2009-09-29 22:00:00 +02:00
cl.refdef.crosshairangle[0] = MSG_ReadAngle8( msg );
cl.refdef.crosshairangle[1] = MSG_ReadAngle8( msg );
2009-01-23 22:00:00 +01:00
cl.refdef.crosshairangle[2] = 0; // not used for screen space
}
2007-06-21 22:00:00 +02:00
/*
=====================================================================
ACTION MESSAGES
=====================================================================
*/
/*
=====================
CL_ParseServerMessage
=====================
*/
2008-05-20 22:00:00 +02:00
void CL_ParseServerMessage( sizebuf_t *msg )
2007-06-21 22:00:00 +02:00
{
2008-06-30 22:00:00 +02:00
char *s;
2009-11-23 22:00:00 +01:00
int i, cmd;
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
{
2009-06-24 22:00:00 +02:00
if( msg->error )
2007-06-21 22:00:00 +02:00
{
2007-09-10 22:00:00 +02:00
Host_Error("CL_ParseServerMessage: Bad server message\n");
2009-06-24 22:00:00 +02:00
return;
2007-06-21 22:00:00 +02:00
}
2008-05-20 22:00:00 +02:00
cmd = MSG_ReadByte( msg );
2008-07-12 22:00:00 +02:00
if( cmd == -1 ) break;
2008-07-15 22:00:00 +02:00
2009-10-13 22:00:00 +02:00
// if( cmd > 200 ) MsgDev( D_INFO, "CL_Parse: %s received.\n", svc_strings[cmd - 200] );
2007-08-17 22:00:00 +02:00
// other commands
2008-06-30 22:00:00 +02:00
switch( cmd )
2007-06-21 22:00:00 +02:00
{
case svc_nop:
2008-06-30 22:00:00 +02:00
MsgDev( D_ERROR, "CL_ParseServerMessage: user message out of bounds\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:
2008-06-30 22:00:00 +02:00
Msg( "Server disconnected, reconnecting\n" );
if( cls.download )
2007-06-21 22:00:00 +02:00
{
2008-06-30 22:00:00 +02:00
FS_Close( cls.download );
2007-06-21 22:00:00 +02:00
cls.download = NULL;
}
cls.state = ca_connecting;
2008-06-30 22:00:00 +02:00
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
2007-06-21 22:00:00 +02:00
break;
case svc_stufftext:
2008-05-20 22:00:00 +02:00
s = MSG_ReadString( msg );
2008-06-30 22:00:00 +02:00
Cbuf_AddText( s );
2007-06-21 22:00:00 +02:00
break;
case svc_serverdata:
2008-08-02 22:00:00 +02:00
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_spawnbaseline:
2008-05-20 22:00:00 +02:00
CL_ParseBaseline( 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;
2008-12-21 22:00:00 +01:00
case svc_sound:
CL_ParseSoundPacket( msg );
break;
2008-11-27 22:00:00 +01:00
case svc_setangle:
CL_ParseSetAngle( msg );
break;
2009-09-18 22:00:00 +02:00
case svc_setview:
cl.refdef.viewentity = MSG_ReadWord( msg );
break;
2009-01-23 22:00:00 +01:00
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;
2009-11-23 22:00:00 +01:00
case svc_physinfo:
com.strncpy( cl.physinfo, MSG_ReadString( msg ), sizeof( cl.physinfo ));
break;
2008-12-26 22:00:00 +01:00
case svc_print:
2009-11-23 22:00:00 +01:00
i = MSG_ReadByte( msg );
if( i == PRINT_CHAT ) // chat
S_StartLocalSound( "misc/talk.wav", 1.0f, 100, NULL );
2008-12-26 22:00:00 +01:00
Con_Print( va( "^6%s\n", MSG_ReadString( msg )));
break;
2009-11-23 22:00:00 +01:00
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), SCREEN_HEIGHT/2, BIGCHAR_WIDTH );
break;
2009-11-10 22:00:00 +01:00
case svc_setpause:
cl.refdef.paused = (MSG_ReadByte( msg ) != 0 );
break;
case svc_movevars:
CL_ParseMovevars( msg );
break;
2009-11-23 22:00:00 +01:00
case svc_particle:
CL_ParseParticles( msg );
break;
case svc_bspdecal:
CL_ParseStaticDecal( msg );
break;
2009-11-25 22:00:00 +01:00
case svc_soundfade:
CL_ParseSoundFade( msg );
break;
2009-12-02 22:00:00 +01:00
case svc_event:
CL_ParseEvent( msg );
break;
case svc_event_reliable:
CL_ParseReliableEvent( msg, FEV_RELIABLE );
break;
2007-06-21 22:00:00 +02:00
case svc_frame:
2008-05-20 22:00:00 +02:00
CL_ParseFrame( msg );
2007-06-21 22:00:00 +02:00
break;
2008-08-11 22:00:00 +02:00
case svc_playerinfo:
2007-06-21 22:00:00 +02:00
case svc_packetentities:
2008-08-02 22:00:00 +02:00
Host_Error( "CL_ParseServerMessage: out of place frame data\n" );
2008-06-30 22:00:00 +02:00
break;
case svc_bad:
2008-08-02 22:00:00 +02:00
Host_Error( "CL_ParseServerMessage: svc_bad\n" );
2007-06-21 22:00:00 +02:00
break;
2007-11-17 22:00:00 +01:00
default:
2008-12-25 22:00:00 +01:00
CL_ParseUserMessage( msg, cmd );
2007-11-17 22:00:00 +01:00
break;
2007-06-21 22:00:00 +02:00
}
}
2008-06-30 22:00:00 +02:00
}