Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/engine/client/cl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,24 @@ void CL_Record(std::string demo_name)
MSG_WriteByte( &buf, svc_configstring );
MSG_WriteShort( &buf, i );
MSG_WriteBigString( &buf, cl.gameState[i].c_str() );

if ( MAX_MSGLEN - buf.cursize < 128 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A configstring can be up to 8k so this isn't enough to guarantee there is space

// We have too much configstring data to put it all into one msg_t, so split it here
MSG_WriteByte( &buf, svc_partial );

int len = LittleLong( clc.serverMessageSequence - 1 );
FS_Write( &len, 4, clc.demofile );

len = LittleLong( buf.cursize );
FS_Write( &len, 4, clc.demofile );
FS_Write( buf.data, buf.cursize, clc.demofile );

MSG_Init( &buf, bufData, sizeof( bufData ) );
MSG_Bitstream( &buf );
MSG_WriteLong( &buf, clc.reliableSequence );
MSG_WriteByte( &buf, svc_gamestate );
MSG_WriteLong( &buf, clc.serverCommandSequence );
}
}

// baselines
Expand Down
30 changes: 20 additions & 10 deletions src/engine/client/cl_parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ MESSAGE PARSING

// TODO(kangz) if we can make sure that the baseline entities have the correct entity
// number, then we could grab the entity number from old directly, simplifying code a bit.
void CL_DeltaEntity( msg_t *msg, clSnapshot_t *snapshot, int entityNum, const entityState_t &oldEntity)
bool CL_DeltaEntity( msg_t *msg, clSnapshot_t *snapshot, int entityNum, const entityState_t &oldEntity)
{
entityState_t entity;
MSG_ReadDeltaEntity(msg, &oldEntity, &entity, entityNum);
if ( MSG_ReadDeltaEntity( msg, &oldEntity, &entity, entityNum ) ) {
return true;
}

if (entity.number != MAX_GENTITIES - 1) {
snapshot->entities.push_back(entity);
}

return false;
}

/*
Expand Down Expand Up @@ -136,7 +140,9 @@ void CL_ParsePacketEntities( msg_t *msg, const clSnapshot_t *oldSnapshot, clSnap

// (2) there is an entry for an entity in the old snapshot, apply the delta
if (oldEntityNum == newEntityNum) {
CL_DeltaEntity(msg, newSnapshot, newEntityNum, oldEntities[oldIndex]);
if ( CL_DeltaEntity( msg, newSnapshot, newEntityNum, oldEntities[oldIndex] ) ) {
break;
}

oldIndex ++;
if (oldIndex >= oldEntities.size()) {
Expand All @@ -149,7 +155,9 @@ void CL_ParsePacketEntities( msg_t *msg, const clSnapshot_t *oldSnapshot, clSnap
// from the baseline
ASSERT_GT(oldEntityNum, newEntityNum);

CL_DeltaEntity(msg, newSnapshot, newEntityNum, cl.entityBaselines[newEntityNum]);
if ( CL_DeltaEntity( msg, newSnapshot, newEntityNum, cl.entityBaselines[newEntityNum] ) ) {
break;
}
}
}

Expand Down Expand Up @@ -421,7 +429,11 @@ void CL_ParseGamestate( msg_t *msg )
break;
}

if ( cmd == svc_configstring )
if ( cmd == svc_partial ) {
cl.reading = true;
break;
}
else if ( cmd == svc_configstring )
{
i = MSG_ReadShort( msg );

Expand All @@ -448,11 +460,6 @@ void CL_ParseGamestate( msg_t *msg )

cl.reading = false;
}
else if ( cmd == svc_gamestatePartial )
{
cl.reading = true;
break;
}
else
{
Sys::Drop( "CL_ParseGamestate: bad command byte" );
Expand Down Expand Up @@ -588,6 +595,9 @@ void CL_ParseServerMessage( msg_t *msg )
case svc_download:
CL_ParseDownload( msg );
break;

case svc_partial:
break;
}
}
}
14 changes: 11 additions & 3 deletions src/engine/qcommon/msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ void MSG_WriteDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, b

MSG_WriteBits( msg, from->number, GENTITYNUM_BITS );
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, 0, 1 );
return;
}

Expand Down Expand Up @@ -1061,7 +1062,7 @@ Can go from either a baseline or a previous packet_entity
*/
extern cvar_t *cl_shownet;

void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number )
bool MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number )
{
int i, lc;
int numFields;
Expand All @@ -1088,6 +1089,11 @@ void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *
// check for a remove
if ( MSG_ReadBits( msg, 1 ) == 1 )
{
// partial snapshot; this is not an actual entity, the next entity had to be put into a different msg
if ( MSG_ReadBits( msg, 1 ) == 1 ) {
return true;
}

*to = {};
to->number = MAX_GENTITIES - 1;

Expand All @@ -1096,15 +1102,15 @@ void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *
Log::Notice( "%3i: #%-3i remove", msg->readcount, number );
}

return;
return false;
}

// check for no delta
if ( MSG_ReadBits( msg, 1 ) == 0 )
{
*to = *from;
to->number = number;
return;
return false;
}

numFields = ARRAY_LEN( entityStateFields );
Expand Down Expand Up @@ -1216,6 +1222,8 @@ void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *

Log::Notice( " (%i bits)", endBit - startBit );
}

return false;
}

/*
Expand Down
4 changes: 2 additions & 2 deletions src/engine/qcommon/qcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to );
void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to );

void MSG_WriteDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, bool force );
void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number );
bool MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number );

void MSG_InitNetcodeTables(NetcodeTable playerStateTable, int playerStateSize);
void MSG_WriteDeltaPlayerstate( msg_t *msg, const OpaquePlayerState *from, const OpaquePlayerState *to );
Expand Down Expand Up @@ -248,12 +248,12 @@ enum svc_ops_e
svc_bad,
svc_nop,
svc_gamestate,
svc_gamestatePartial,
svc_configstring, // [short] [string] only in gamestate messages
svc_baseline, // only in gamestate messages
svc_serverCommand, // [string] to be executed by client game module
svc_download, // [short] size [size bytes]
svc_snapshot,
svc_partial,
svc_EOF
};

Expand Down
13 changes: 12 additions & 1 deletion src/engine/server/sv_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,17 @@ void SV_SendClientGameState( client_t *client )
MSG_WriteByte( &msg, svc_configstring );
MSG_WriteShort( &msg, start );
MSG_WriteBigString( &msg, sv.configstrings[ start ] );

if ( MAX_MSGLEN - msg.cursize < 128 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A configstring can be up to 8k so this isn't enough to guarantee there is space

// We have too much configstring data to put it all into one msg_t, so split it here
MSG_WriteByte( &msg, svc_partial );
SV_SendMessageToClient( &msg, client );

MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
MSG_WriteLong( &msg, client->lastClientCommand );
MSG_WriteByte( &msg, svc_gamestate );
MSG_WriteLong( &msg, client->reliableSequence );
}
}
}

Expand All @@ -388,7 +399,7 @@ void SV_SendClientGameState( client_t *client )

if ( MAX_MSGLEN - msg.cursize < 128 ) {
// We have too many entities to put them all into one msg_t, so split it here
MSG_WriteByte( &msg, svc_gamestatePartial );
MSG_WriteByte( &msg, svc_partial );
SV_SendMessageToClient( &msg, client );

MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
Expand Down
49 changes: 47 additions & 2 deletions src/engine/server/sv_snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ SV_EmitPacketEntities
Writes a delta update of an entityState_t list to the message.
=============
*/
static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg )
static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg,
client_t* client, int lastframe, int snapFlags )
{
entityState_t *oldent, *newent;
int oldindex, newindex;
Expand Down Expand Up @@ -97,6 +98,42 @@ static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_

while ( newindex < to->num_entities || oldindex < from_num_entities )
{

if ( MAX_MSGLEN - msg->cursize < 128 ) {
MSG_WriteBits( msg, 0, GENTITYNUM_BITS );
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, 1, 1 );

SV_SendMessageToClient( msg, client );

MSG_Init( msg, msg->data, msg->maxsize );
MSG_WriteByte( msg, svc_snapshot );

MSG_WriteLong( msg, sv.time );

// what we are delta'ing from
MSG_WriteByte( msg, lastframe );

snapFlags = svs.snapFlagServerBit;

MSG_WriteByte( msg, snapFlags );

// send over the areabits
MSG_WriteByte( msg, to->areabytes );
MSG_WriteData( msg, to->areabits, to->areabytes );

{
// delta encode the playerstate
if ( from ) {
MSG_WriteDeltaPlayerstate( msg, &from->ps, &to->ps );
} else {
MSG_WriteDeltaPlayerstate( msg, nullptr, &to->ps );
}
}

MSG_WriteShort( msg, to->num_entities - newindex );
}

if ( newindex >= to->num_entities )
{
newnum = MAX_GENTITIES;
Expand Down Expand Up @@ -236,7 +273,7 @@ static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg )
}

// delta encode the entities
SV_EmitPacketEntities( oldframe, frame, msg );
SV_EmitPacketEntities( oldframe, frame, msg, client, lastframe, snapFlags );

// padding for rate debugging
if ( sv_padPackets.Get() )
Expand Down Expand Up @@ -265,6 +302,14 @@ void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg )
MSG_WriteByte( msg, svc_serverCommand );
MSG_WriteLong( msg, i );
MSG_WriteString( msg, client->reliableCommands[ i & ( MAX_RELIABLE_COMMANDS - 1 ) ] );

if ( MAX_MSGLEN - msg->cursize < 128 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think commands could be longer than 128 bytes.

MSG_WriteByte( msg, svc_partial );
SV_SendMessageToClient( msg, client );

MSG_Init( msg, msg->data, msg->maxsize );
MSG_WriteLong( msg, client->lastClientCommand );
}
}

client->reliableSent = client->reliableSequence;
Expand Down
Loading