Browse Source

engine: client: consolidate modern and legacy protocol parsing functions, if possible

pull/2/head
Alibek Omarov 1 year ago
parent
commit
3cfdb1213b
  1. 289
      engine/client/cl_parse.c
  2. 3
      engine/common/protocol.h

289
engine/client/cl_parse.c

@ -843,15 +843,15 @@ void CL_ParseFileTransferFailed( sizebuf_t *msg )
CL_ParseServerData CL_ParseServerData
================== ==================
*/ */
void CL_ParseServerData( sizebuf_t *msg ) void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
{ {
char gamefolder[MAX_QPATH]; char gamefolder[MAX_QPATH];
qboolean background; qboolean background;
int i; int i;
Con_Reportf( "Serverdata packet received.\n" ); Con_Reportf( "%s packet received.\n", legacy ? "Legacy serverdata" : "Serverdata" );
cls.timestart = Sys_DoubleTime();
cls.timestart = Sys_DoubleTime();
cls.demowaiting = false; // server is changed cls.demowaiting = false; // server is changed
// wipe the client_t struct // wipe the client_t struct
@ -862,27 +862,46 @@ void CL_ParseServerData( sizebuf_t *msg )
// parse protocol version number // parse protocol version number
i = MSG_ReadLong( msg ); i = MSG_ReadLong( msg );
if( i != PROTOCOL_VERSION ) if( legacy )
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION ); {
if( i != PROTOCOL_LEGACY_VERSION )
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_LEGACY_VERSION );
}
else
{
if( i != PROTOCOL_VERSION )
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
}
cl.servercount = MSG_ReadLong( msg ); cl.servercount = MSG_ReadLong( msg );
cl.checksum = MSG_ReadLong( msg ); cl.checksum = MSG_ReadLong( msg );
cl.playernum = MSG_ReadByte( msg ); cl.playernum = MSG_ReadByte( msg );
cl.maxclients = MSG_ReadByte( msg ); cl.maxclients = MSG_ReadByte( msg );
clgame.maxEntities = MSG_ReadWord( msg ); clgame.maxEntities = MSG_ReadWord( msg );
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS ); if( legacy )
clgame.maxModels = MSG_ReadWord( msg ); {
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING ); clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_LEGACY_EDICTS );
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING ); clgame.maxModels = 512; // ???
}
else
{
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
clgame.maxModels = MSG_ReadWord( msg );
}
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), sizeof( clgame.mapname ));
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
background = MSG_ReadOneBit( msg ); background = MSG_ReadOneBit( msg );
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_QPATH ); Q_strncpy( gamefolder, MSG_ReadString( msg ), sizeof( gamefolder ));
host.features = (uint)MSG_ReadLong( msg ); host.features = (uint)MSG_ReadLong( msg );
// receive the player hulls if( !legacy )
for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
{ {
host.player_mins[i/3][i%3] = MSG_ReadChar( msg ); // receive the player hulls
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg ); for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
{
host.player_mins[i/3][i%3] = MSG_ReadChar( msg );
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg );
}
} }
if( clgame.maxModels > MAX_MODELS ) if( clgame.maxModels > MAX_MODELS )
@ -961,8 +980,11 @@ void CL_ParseServerData( sizebuf_t *msg )
COM_ClearCustomizationList( &cl.players[i].customdata, true ); COM_ClearCustomizationList( &cl.players[i].customdata, true );
CL_CreateCustomizationList(); CL_CreateCustomizationList();
// request resources from server if( !legacy )
CL_ServerCommand( true, "sendres %i\n", cl.servercount ); {
// request resources from server
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
}
memset( &clgame.movevars, 0, sizeof( clgame.movevars )); memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars )); memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
@ -1137,7 +1159,7 @@ void CL_ParseClientData( sizebuf_t *msg )
CL_ParseBaseline CL_ParseBaseline
================== ==================
*/ */
void CL_ParseBaseline( sizebuf_t *msg ) void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
{ {
int i, newnum; int i, newnum;
entity_state_t nullstate; entity_state_t nullstate;
@ -1150,8 +1172,15 @@ void CL_ParseBaseline( sizebuf_t *msg )
while( 1 ) while( 1 )
{ {
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS ); if( legacy )
if( newnum == LAST_EDICT ) break; // end of baselines {
newnum = MSG_ReadWord( msg );
}
else
{
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
if( newnum == LAST_EDICT ) break; // end of baselines
}
player = CL_IsPlayerIndex( newnum ); player = CL_IsPlayerIndex( newnum );
if( newnum >= clgame.maxEntities ) if( newnum >= clgame.maxEntities )
@ -1162,14 +1191,22 @@ void CL_ParseBaseline( sizebuf_t *msg )
ent->index = newnum; ent->index = newnum;
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f ); MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f );
}
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 ); if( legacy )
{
break; // only one baseline allowed in legacy protocol
}
}
for( i = 0; i < cl.instanced_baseline_count; i++ ) if( !legacy )
{ {
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS ); cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
for( i = 0; i < cl.instanced_baseline_count; i++ )
{
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
}
} }
} }
@ -1317,7 +1354,7 @@ CL_UpdateUserinfo
collect userinfo from all players collect userinfo from all players
================ ================
*/ */
void CL_UpdateUserinfo( sizebuf_t *msg ) void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy )
{ {
int slot, id; int slot, id;
qboolean active; qboolean active;
@ -1328,7 +1365,8 @@ void CL_UpdateUserinfo( sizebuf_t *msg )
if( slot >= MAX_CLIENTS ) if( slot >= MAX_CLIENTS )
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" ); Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" );
id = MSG_ReadLong( msg ); // unique user ID if( !legacy )
id = MSG_ReadLong( msg ); // unique user ID
player = &cl.players[slot]; player = &cl.players[slot];
active = MSG_ReadOneBit( msg ) ? true : false; active = MSG_ReadOneBit( msg ) ? true : false;
@ -1340,7 +1378,8 @@ void CL_UpdateUserinfo( sizebuf_t *msg )
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" )); player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" )); player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" )); player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey )); if( !legacy )
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t )); if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t ));
} }
@ -2230,13 +2269,13 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
break; break;
case svc_serverdata: case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData( msg ); CL_ParseServerData( msg, false );
break; break;
case svc_lightstyle: case svc_lightstyle:
CL_ParseLightStyle( msg ); CL_ParseLightStyle( msg );
break; break;
case svc_updateuserinfo: case svc_updateuserinfo:
CL_UpdateUserinfo( msg ); CL_UpdateUserinfo( msg, false );
break; break;
case svc_deltatable: case svc_deltatable:
Delta_ParseTableField( msg ); Delta_ParseTableField( msg );
@ -2266,7 +2305,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart; cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break; break;
case svc_spawnbaseline: case svc_spawnbaseline:
CL_ParseBaseline( msg ); CL_ParseBaseline( msg, false );
break; break;
case svc_temp_entity: case svc_temp_entity:
CL_ParseTempEntity( msg ); CL_ParseTempEntity( msg );
@ -2403,156 +2442,6 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
} }
} }
/*
==================
CL_ParseBaseline
==================
*/
void CL_LegacyParseBaseline( sizebuf_t *msg )
{
int i, newnum;
qboolean player;
cl_entity_t *ent;
Delta_InitClient (); // finalize client delta's
newnum = MSG_ReadWord( msg );
player = CL_IsPlayerIndex( newnum );
if( newnum >= clgame.maxEntities )
Host_Error( "CL_AllocEdict: no free edicts\n" );
ent = CL_EDICT_NUM( newnum );
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
ent->index = newnum;
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f );
}
/*
==================
CL_ParseServerData
==================
*/
void CL_ParseLegacyServerData( sizebuf_t *msg )
{
string gamefolder;
qboolean background;
int i;
Con_Reportf( "Legacy serverdata packet received.\n" );
cls.timestart = Sys_DoubleTime();
cls.demowaiting = false; // server is changed
//clgame.load_sequence++; // now all hud sprites are invalid
// wipe the client_t struct
if( !cls.changelevel && !cls.changedemo )
CL_ClearState ();
cls.state = ca_connected;
// parse protocol version number
i = MSG_ReadLong( msg );
//cls.serverProtocol = i;
if( i != PROTOCOL_LEGACY_VERSION )
Host_Error( "Server uses invalid protocol (%i should be %i)\n", i, PROTOCOL_LEGACY_VERSION );
cl.servercount = MSG_ReadLong( msg );
cl.checksum = MSG_ReadLong( msg );
cl.playernum = MSG_ReadByte( msg );
cl.maxclients = MSG_ReadByte( msg );
clgame.maxEntities = MSG_ReadWord( msg );
clgame.maxEntities = bound( 30, clgame.maxEntities, 4096 );
clgame.maxModels = 512;
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
background = MSG_ReadOneBit( msg );
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_STRING );
host.features = (uint)MSG_ReadLong( msg );
// Re-init hud video, especially if we changed game directories
clgame.dllFuncs.pfnVidInit();
if( Con_FixedFont( ))
{
// seperate the printfs so the server message can have a color
Con_Print( "\n\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" );
Con_Print( va( "%c%s\n\n", 2, clgame.maptitle ));
}
// multiplayer game?
if( cl.maxclients > 1 )
{
// allow console in multiplayer games
host.allow_console = true;
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
}
else Cvar_Reset( "r_decals" );
// set the background state
if( cls.demoplayback && ( cls.demonum != -1 ))
cl.background = true;
else cl.background = background;
if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
if( !cls.changelevel )
{
// continue playing if we are changing level
S_StopBackgroundTrack ();
}
if( !cls.changedemo )
UI_SetActiveMenu( cl.background );
else if( !cls.demoplayback )
Key_SetKeyDest( key_menu );
// don't reset cursor in background mode
if( cl.background )
IN_MouseRestorePos();
// will be changed later
cl.viewentity = cl.playernum + 1;
gameui.globals->maxClients = cl.maxclients;
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts
// get splash name
if( cls.demoplayback && ( cls.demonum != -1 ))
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, refState.wideScreen ? "16x9" : "4x3" ));
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
{
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
}
for( i = 0; i < MAX_CLIENTS; i++ )
COM_ClearCustomizationList( &cl.players[i].customdata, true );
CL_CreateCustomizationList();
memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
cl.video_prepped = false;
cl.audio_prepped = false;
}
/* /*
================== ==================
CL_ParseStaticEntity CL_ParseStaticEntity
@ -2628,8 +2517,6 @@ void CL_LegacyParseStaticEntity( sizebuf_t *msg )
R_AddEfrags( ent ); // add link R_AddEfrags( ent ); // add link
} }
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient ) void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{ {
vec3_t pos; vec3_t pos;
@ -2761,36 +2648,6 @@ void CL_LegacyPrecacheEvent( sizebuf_t *msg )
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex ); CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
} }
void CL_LegacyUpdateUserinfo( sizebuf_t *msg )
{
int slot, id = 0;
qboolean active;
player_info_t *player;
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
if( slot >= MAX_CLIENTS )
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" );
//id = MSG_ReadLong( msg ); // unique user ID
player = &cl.players[slot];
active = MSG_ReadOneBit( msg ) ? true : false;
if( active )
{
Q_strncpy( player->userinfo, MSG_ReadString( msg ), sizeof( player->userinfo ));
Q_strncpy( player->name, Info_ValueForKey( player->userinfo, "name" ), sizeof( player->name ));
Q_strncpy( player->model, Info_ValueForKey( player->userinfo, "model" ), sizeof( player->model ));
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
//MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t ));
}
else memset( player, 0, sizeof( *player ));
}
#if XASH_LOW_MEMORY == 0 #if XASH_LOW_MEMORY == 0
#define MAX_LEGACY_RESOURCES 2048 #define MAX_LEGACY_RESOURCES 2048
#elif XASH_LOW_MEMORY == 2 #elif XASH_LOW_MEMORY == 2
@ -2994,13 +2851,13 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
break; break;
case svc_serverdata: case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseLegacyServerData( msg ); CL_ParseServerData( msg, true );
break; break;
case svc_lightstyle: case svc_lightstyle:
CL_ParseLightStyle( msg ); CL_ParseLightStyle( msg );
break; break;
case svc_updateuserinfo: case svc_updateuserinfo:
CL_LegacyUpdateUserinfo( msg ); CL_UpdateUserinfo( msg, true );
break; break;
case svc_deltatable: case svc_deltatable:
Delta_ParseTableField( msg ); Delta_ParseTableField( msg );
@ -3030,7 +2887,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart; cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break; break;
case svc_spawnbaseline: case svc_spawnbaseline:
CL_LegacyParseBaseline( msg ); CL_ParseBaseline( msg, true );
break; break;
case svc_temp_entity: case svc_temp_entity:
CL_ParseTempEntity( msg ); CL_ParseTempEntity( msg );
@ -3050,7 +2907,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
break; break;
case svc_legacy_modelindex: case svc_legacy_modelindex:
CL_LegacyPrecacheModel( msg ); CL_LegacyPrecacheModel( msg );
break; break;
case svc_legacy_soundindex: case svc_legacy_soundindex:
CL_LegacyPrecacheSound( msg ); CL_LegacyPrecacheSound( msg );
@ -3066,7 +2922,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseRestore( msg ); CL_ParseRestore( msg );
break; break;
case svc_legacy_eventindex: case svc_legacy_eventindex:
//CL_ParseFinaleCutscene( msg, 3 );
CL_LegacyPrecacheEvent(msg); CL_LegacyPrecacheEvent(msg);
break; break;
case svc_weaponanim: case svc_weaponanim:

3
engine/common/protocol.h

@ -302,6 +302,9 @@ extern const char *clc_strings[clc_lastmsg+1];
#define MAX_LEGACY_TOTAL_CMDS 16 // 28 - 16 = 12 real legacy max backup #define MAX_LEGACY_TOTAL_CMDS 16 // 28 - 16 = 12 real legacy max backup
#define MAX_LEGACY_BACKUP_CMDS 12 #define MAX_LEGACY_BACKUP_CMDS 12
#define MAX_LEGACY_EDICTS (1 << MAX_LEGACY_ENTITY_BITS) // 4096 edicts
#define MIN_LEGACY_EDICTS 30
// Master Server protocol // Master Server protocol
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0" // TODO: implement IP filter #define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0" // TODO: implement IP filter

Loading…
Cancel
Save