diff options
author | Tim Angus <tim@ngus.net> | 2005-12-10 03:08:56 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2005-12-10 03:08:56 +0000 |
commit | 3b447421efc76ba76fbdae62f893fc6916af5433 (patch) | |
tree | 035963614a2e6333b6d38667b5142c2c0e7863c7 /ioq3-r437/src/client/cl_parse.c | |
parent | 08446c16acbbb9a9d12fccb21e27cfa29d076e77 (diff) |
* Well I fucked that up then...
Diffstat (limited to 'ioq3-r437/src/client/cl_parse.c')
-rw-r--r-- | ioq3-r437/src/client/cl_parse.c | 655 |
1 files changed, 0 insertions, 655 deletions
diff --git a/ioq3-r437/src/client/cl_parse.c b/ioq3-r437/src/client/cl_parse.c deleted file mode 100644 index e9eddc77..00000000 --- a/ioq3-r437/src/client/cl_parse.c +++ /dev/null @@ -1,655 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code 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. - -Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// cl_parse.c -- parse a message received from the server - -#include "client.h" - -char *svc_strings[256] = { - "svc_bad", - - "svc_nop", - "svc_gamestate", - "svc_configstring", - "svc_baseline", - "svc_serverCommand", - "svc_download", - "svc_snapshot" -}; - -void SHOWNET( msg_t *msg, char *s) { - if ( cl_shownet->integer >= 2) { - Com_Printf ("%3i:%s\n", msg->readcount-1, s); - } -} - - -/* -========================================================================= - -MESSAGE PARSING - -========================================================================= -*/ - -/* -================== -CL_DeltaEntity - -Parses deltas from the given base and adds the resulting entity -to the current frame -================== -*/ -void CL_DeltaEntity (msg_t *msg, clSnapshot_t *frame, int newnum, entityState_t *old, - qboolean unchanged) { - entityState_t *state; - - // save the parsed entity state into the big circular buffer so - // it can be used as the source for a later delta - state = &cl.parseEntities[cl.parseEntitiesNum & (MAX_PARSE_ENTITIES-1)]; - - if ( unchanged ) { - *state = *old; - } else { - MSG_ReadDeltaEntity( msg, old, state, newnum ); - } - - if ( state->number == (MAX_GENTITIES-1) ) { - return; // entity was delta removed - } - cl.parseEntitiesNum++; - frame->numEntities++; -} - -/* -================== -CL_ParsePacketEntities - -================== -*/ -void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *newframe) { - int newnum; - entityState_t *oldstate; - int oldindex, oldnum; - - newframe->parseEntitiesNum = cl.parseEntitiesNum; - newframe->numEntities = 0; - - // delta from the entities present in oldframe - oldindex = 0; - oldstate = NULL; - if (!oldframe) { - oldnum = 99999; - } else { - if ( oldindex >= oldframe->numEntities ) { - oldnum = 99999; - } else { - oldstate = &cl.parseEntities[ - (oldframe->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)]; - oldnum = oldstate->number; - } - } - - while ( 1 ) { - // read the entity index number - newnum = MSG_ReadBits( msg, GENTITYNUM_BITS ); - - if ( newnum == (MAX_GENTITIES-1) ) { - break; - } - - if ( msg->readcount > msg->cursize ) { - Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message"); - } - - while ( oldnum < newnum ) { - // one or more entities from the old packet are unchanged - if ( cl_shownet->integer == 3 ) { - Com_Printf ("%3i: unchanged: %i\n", msg->readcount, oldnum); - } - CL_DeltaEntity( msg, newframe, oldnum, oldstate, qtrue ); - - oldindex++; - - if ( oldindex >= oldframe->numEntities ) { - oldnum = 99999; - } else { - oldstate = &cl.parseEntities[ - (oldframe->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)]; - oldnum = oldstate->number; - } - } - if (oldnum == newnum) { - // delta from previous state - if ( cl_shownet->integer == 3 ) { - Com_Printf ("%3i: delta: %i\n", msg->readcount, newnum); - } - CL_DeltaEntity( msg, newframe, newnum, oldstate, qfalse ); - - oldindex++; - - if ( oldindex >= oldframe->numEntities ) { - oldnum = 99999; - } else { - oldstate = &cl.parseEntities[ - (oldframe->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)]; - oldnum = oldstate->number; - } - continue; - } - - if ( oldnum > newnum ) { - // delta from baseline - if ( cl_shownet->integer == 3 ) { - Com_Printf ("%3i: baseline: %i\n", msg->readcount, newnum); - } - CL_DeltaEntity( msg, newframe, newnum, &cl.entityBaselines[newnum], qfalse ); - continue; - } - - } - - // any remaining entities in the old frame are copied over - while ( oldnum != 99999 ) { - // one or more entities from the old packet are unchanged - if ( cl_shownet->integer == 3 ) { - Com_Printf ("%3i: unchanged: %i\n", msg->readcount, oldnum); - } - CL_DeltaEntity( msg, newframe, oldnum, oldstate, qtrue ); - - oldindex++; - - if ( oldindex >= oldframe->numEntities ) { - oldnum = 99999; - } else { - oldstate = &cl.parseEntities[ - (oldframe->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)]; - oldnum = oldstate->number; - } - } -} - - -/* -================ -CL_ParseSnapshot - -If the snapshot is parsed properly, it will be copied to -cl.snap and saved in cl.snapshots[]. If the snapshot is invalid -for any reason, no changes to the state will be made at all. -================ -*/ -void CL_ParseSnapshot( msg_t *msg ) { - int len; - clSnapshot_t *old; - clSnapshot_t newSnap; - int deltaNum; - int oldMessageNum; - int i, packetNum; - - // get the reliable sequence acknowledge number - // NOTE: now sent with all server to client messages - //clc.reliableAcknowledge = MSG_ReadLong( msg ); - - // read in the new snapshot to a temporary buffer - // we will only copy to cl.snap if it is valid - Com_Memset (&newSnap, 0, sizeof(newSnap)); - - // we will have read any new server commands in this - // message before we got to svc_snapshot - newSnap.serverCommandNum = clc.serverCommandSequence; - - newSnap.serverTime = MSG_ReadLong( msg ); - - newSnap.messageNum = clc.serverMessageSequence; - - deltaNum = MSG_ReadByte( msg ); - if ( !deltaNum ) { - newSnap.deltaNum = -1; - } else { - newSnap.deltaNum = newSnap.messageNum - deltaNum; - } - newSnap.snapFlags = MSG_ReadByte( msg ); - - // If the frame is delta compressed from data that we - // no longer have available, we must suck up the rest of - // the frame, but not use it, then ask for a non-compressed - // message - if ( newSnap.deltaNum <= 0 ) { - newSnap.valid = qtrue; // uncompressed frame - old = NULL; - clc.demowaiting = qfalse; // we can start recording now - } else { - old = &cl.snapshots[newSnap.deltaNum & PACKET_MASK]; - if ( !old->valid ) { - // should never happen - Com_Printf ("Delta from invalid frame (not supposed to happen!).\n"); - } else if ( old->messageNum != newSnap.deltaNum ) { - // The frame that the server did the delta from - // is too old, so we can't reconstruct it properly. - Com_Printf ("Delta frame too old.\n"); - } else if ( cl.parseEntitiesNum - old->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) { - Com_Printf ("Delta parseEntitiesNum too old.\n"); - } else { - newSnap.valid = qtrue; // valid delta parse - } - } - - // read areamask - len = MSG_ReadByte( msg ); - MSG_ReadData( msg, &newSnap.areamask, len); - - // read playerinfo - SHOWNET( msg, "playerstate" ); - if ( old ) { - MSG_ReadDeltaPlayerstate( msg, &old->ps, &newSnap.ps ); - } else { - MSG_ReadDeltaPlayerstate( msg, NULL, &newSnap.ps ); - } - - // read packet entities - SHOWNET( msg, "packet entities" ); - CL_ParsePacketEntities( msg, old, &newSnap ); - - // if not valid, dump the entire thing now that it has - // been properly read - if ( !newSnap.valid ) { - return; - } - - // clear the valid flags of any snapshots between the last - // received and this one, so if there was a dropped packet - // it won't look like something valid to delta from next - // time we wrap around in the buffer - oldMessageNum = cl.snap.messageNum + 1; - - if ( newSnap.messageNum - oldMessageNum >= PACKET_BACKUP ) { - oldMessageNum = newSnap.messageNum - ( PACKET_BACKUP - 1 ); - } - for ( ; oldMessageNum < newSnap.messageNum ; oldMessageNum++ ) { - cl.snapshots[oldMessageNum & PACKET_MASK].valid = qfalse; - } - - // copy to the current good spot - cl.snap = newSnap; - cl.snap.ping = 999; - // calculate ping time - for ( i = 0 ; i < PACKET_BACKUP ; i++ ) { - packetNum = ( clc.netchan.outgoingSequence - 1 - i ) & PACKET_MASK; - if ( cl.snap.ps.commandTime >= cl.outPackets[ packetNum ].p_serverTime ) { - cl.snap.ping = cls.realtime - cl.outPackets[ packetNum ].p_realtime; - break; - } - } - // save the frame off in the backup array for later delta comparisons - cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap; - - if (cl_shownet->integer == 3) { - Com_Printf( " snapshot:%i delta:%i ping:%i\n", cl.snap.messageNum, - cl.snap.deltaNum, cl.snap.ping ); - } - - cl.newSnapshots = qtrue; -} - - -//===================================================================== - -int cl_connectedToPureServer; - -/* -================== -CL_SystemInfoChanged - -The systeminfo configstring has been changed, so parse -new information out of it. This will happen at every -gamestate, and possibly during gameplay. -================== -*/ -void CL_SystemInfoChanged( void ) { - char *systemInfo; - const char *s, *t; - char key[BIG_INFO_KEY]; - char value[BIG_INFO_VALUE]; - qboolean gameSet; - - systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; - // NOTE TTimo: - // when the serverId changes, any further messages we send to the server will use this new serverId - // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475 - // in some cases, outdated cp commands might get sent with this news serverId - cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); - - // don't set any vars when playing a demo - if ( clc.demoplaying ) { - return; - } - - s = Info_ValueForKey( systemInfo, "sv_cheats" ); - if ( atoi(s) == 0 ) { - Cvar_SetCheatState(); - } - - // check pure server string - s = Info_ValueForKey( systemInfo, "sv_paks" ); - t = Info_ValueForKey( systemInfo, "sv_pakNames" ); - FS_PureServerSetLoadedPaks( s, t ); - - s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); - t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); - FS_PureServerSetReferencedPaks( s, t ); - - gameSet = qfalse; - // scan through all the variables in the systeminfo and locally set cvars to match - s = systemInfo; - while ( s ) { - Info_NextPair( &s, key, value ); - if ( !key[0] ) { - break; - } - // ehw! - if ( !Q_stricmp( key, "fs_game" ) ) { - gameSet = qtrue; - } - - Cvar_Set( key, value ); - } - // if game folder should not be set and it is set at the client side - if ( !gameSet && *Cvar_VariableString("fs_game") ) { - Cvar_Set( "fs_game", "" ); - } - cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); -} - -/* -================== -CL_ParseGamestate -================== -*/ -void CL_ParseGamestate( msg_t *msg ) { - int i; - entityState_t *es; - int newnum; - entityState_t nullstate; - int cmd; - char *s; - - Con_Close(); - - clc.connectPacketCount = 0; - - // wipe local client state - CL_ClearState(); - - // a gamestate always marks a server command sequence - clc.serverCommandSequence = MSG_ReadLong( msg ); - - // parse all the configstrings and baselines - cl.gameState.dataCount = 1; // leave a 0 at the beginning for uninitialized configstrings - while ( 1 ) { - cmd = MSG_ReadByte( msg ); - - if ( cmd == svc_EOF ) { - break; - } - - if ( cmd == svc_configstring ) { - int len; - - i = MSG_ReadShort( msg ); - if ( i < 0 || i >= MAX_CONFIGSTRINGS ) { - Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" ); - } - s = MSG_ReadBigString( msg ); - len = strlen( s ); - - if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) { - Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" ); - } - - // append it to the gameState string buffer - cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount; - Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, s, len + 1 ); - cl.gameState.dataCount += len + 1; - } else if ( cmd == svc_baseline ) { - newnum = MSG_ReadBits( msg, GENTITYNUM_BITS ); - if ( newnum < 0 || newnum >= MAX_GENTITIES ) { - Com_Error( ERR_DROP, "Baseline number out of range: %i", newnum ); - } - Com_Memset (&nullstate, 0, sizeof(nullstate)); - es = &cl.entityBaselines[ newnum ]; - MSG_ReadDeltaEntity( msg, &nullstate, es, newnum ); - } else { - Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte" ); - } - } - - clc.clientNum = MSG_ReadLong(msg); - // read the checksum feed - clc.checksumFeed = MSG_ReadLong( msg ); - - // parse serverId and other cvars - CL_SystemInfoChanged(); - - // reinitialize the filesystem if the game directory has changed - FS_ConditionalRestart( clc.checksumFeed ); - - // This used to call CL_StartHunkUsers, but now we enter the download state before loading the - // cgame - CL_InitDownloads(); - - // make sure the game starts - Cvar_Set( "cl_paused", "0" ); -} - - -//===================================================================== - -/* -===================== -CL_ParseDownload - -A download message has been received from the server -===================== -*/ -void CL_ParseDownload ( msg_t *msg ) { - int size; - unsigned char data[MAX_MSGLEN]; - int block; - - // read the data - block = MSG_ReadShort ( msg ); - - if ( !block ) - { - // block zero is special, contains file size - clc.downloadSize = MSG_ReadLong ( msg ); - - Cvar_SetValue( "cl_downloadSize", clc.downloadSize ); - - if (clc.downloadSize < 0) - { - Com_Error(ERR_DROP, MSG_ReadString( msg ) ); - return; - } - } - - size = MSG_ReadShort ( msg ); - if (size > 0) - MSG_ReadData( msg, data, size ); - - if (clc.downloadBlock != block) { - Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", clc.downloadBlock, block); - return; - } - - // open the file if not opened yet - if (!clc.download) - { - if (!*clc.downloadTempName) { - Com_Printf("Server sending download, but no download was requested\n"); - CL_AddReliableCommand( "stopdl" ); - return; - } - - clc.download = FS_SV_FOpenFileWrite( clc.downloadTempName ); - - if (!clc.download) { - Com_Printf( "Could not create %s\n", clc.downloadTempName ); - CL_AddReliableCommand( "stopdl" ); - CL_NextDownload(); - return; - } - } - - if (size) - FS_Write( data, size, clc.download ); - - CL_AddReliableCommand( va("nextdl %d", clc.downloadBlock) ); - clc.downloadBlock++; - - clc.downloadCount += size; - - // So UI gets access to it - Cvar_SetValue( "cl_downloadCount", clc.downloadCount ); - - if (!size) { // A zero length block means EOF - if (clc.download) { - FS_FCloseFile( clc.download ); - clc.download = 0; - - // rename the file - FS_SV_Rename ( clc.downloadTempName, clc.downloadName ); - } - *clc.downloadTempName = *clc.downloadName = 0; - Cvar_Set( "cl_downloadName", "" ); - - // send intentions now - // We need this because without it, we would hold the last nextdl and then start - // loading right away. If we take a while to load, the server is happily trying - // to send us that last block over and over. - // Write it twice to help make sure we acknowledge the download - CL_WritePacket(); - CL_WritePacket(); - - // get another file if needed - CL_NextDownload (); - } -} - -/* -===================== -CL_ParseCommandString - -Command strings are just saved off until cgame asks for them -when it transitions a snapshot -===================== -*/ -void CL_ParseCommandString( msg_t *msg ) { - char *s; - int seq; - int index; - - seq = MSG_ReadLong( msg ); - s = MSG_ReadString( msg ); - - // see if we have already executed stored it off - if ( clc.serverCommandSequence >= seq ) { - return; - } - clc.serverCommandSequence = seq; - - index = seq & (MAX_RELIABLE_COMMANDS-1); - Q_strncpyz( clc.serverCommands[ index ], s, sizeof( clc.serverCommands[ index ] ) ); -} - - -/* -===================== -CL_ParseServerMessage -===================== -*/ -void CL_ParseServerMessage( msg_t *msg ) { - int cmd; - - if ( cl_shownet->integer == 1 ) { - Com_Printf ("%i ",msg->cursize); - } else if ( cl_shownet->integer >= 2 ) { - Com_Printf ("------------------\n"); - } - - MSG_Bitstream(msg); - - // get the reliable sequence acknowledge number - clc.reliableAcknowledge = MSG_ReadLong( msg ); - // - if ( clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS ) { - clc.reliableAcknowledge = clc.reliableSequence; - } - - // - // parse the message - // - while ( 1 ) { - if ( msg->readcount > msg->cursize ) { - Com_Error (ERR_DROP,"CL_ParseServerMessage: read past end of server message"); - break; - } - - cmd = MSG_ReadByte( msg ); - - if ( cmd == svc_EOF) { - SHOWNET( msg, "END OF MESSAGE" ); - break; - } - - if ( cl_shownet->integer >= 2 ) { - if ( !svc_strings[cmd] ) { - Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd ); - } else { - SHOWNET( msg, svc_strings[cmd] ); - } - } - - // other commands - switch ( cmd ) { - default: - Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n"); - break; - case svc_nop: - break; - case svc_serverCommand: - CL_ParseCommandString( msg ); - break; - case svc_gamestate: - CL_ParseGamestate( msg ); - break; - case svc_snapshot: - CL_ParseSnapshot( msg ); - break; - case svc_download: - CL_ParseDownload( msg ); - break; - } - } -} - - |