Skip to content

Commit cc41cef

Browse files
committed
Fix remaining network message overflows
1 parent f6251c7 commit cc41cef

File tree

6 files changed

+110
-18
lines changed

6 files changed

+110
-18
lines changed

src/engine/client/cl_main.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,24 @@ void CL_Record(std::string demo_name)
420420
MSG_WriteByte( &buf, svc_configstring );
421421
MSG_WriteShort( &buf, i );
422422
MSG_WriteBigString( &buf, cl.gameState[i].c_str() );
423+
424+
if ( MAX_MSGLEN - buf.cursize < BIG_INFO_STRING ) {
425+
// We have too much configstring data to put it all into one msg_t, so split it here
426+
MSG_WriteByte( &buf, svc_partial );
427+
428+
int len = LittleLong( clc.serverMessageSequence - 1 );
429+
FS_Write( &len, 4, clc.demofile );
430+
431+
len = LittleLong( buf.cursize );
432+
FS_Write( &len, 4, clc.demofile );
433+
FS_Write( buf.data, buf.cursize, clc.demofile );
434+
435+
MSG_Init( &buf, bufData, sizeof( bufData ) );
436+
MSG_Bitstream( &buf );
437+
MSG_WriteLong( &buf, clc.reliableSequence );
438+
MSG_WriteByte( &buf, svc_gamestate );
439+
MSG_WriteLong( &buf, clc.serverCommandSequence );
440+
}
423441
}
424442

425443
// baselines

src/engine/client/cl_parse.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,18 @@ MESSAGE PARSING
6767

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

7577
if (entity.number != MAX_GENTITIES - 1) {
7678
snapshot->entities.push_back(entity);
7779
}
80+
81+
return false;
7882
}
7983

8084
/*
@@ -136,7 +140,9 @@ void CL_ParsePacketEntities( msg_t *msg, const clSnapshot_t *oldSnapshot, clSnap
136140

137141
// (2) there is an entry for an entity in the old snapshot, apply the delta
138142
if (oldEntityNum == newEntityNum) {
139-
CL_DeltaEntity(msg, newSnapshot, newEntityNum, oldEntities[oldIndex]);
143+
if ( CL_DeltaEntity( msg, newSnapshot, newEntityNum, oldEntities[oldIndex] ) ) {
144+
break;
145+
}
140146

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

152-
CL_DeltaEntity(msg, newSnapshot, newEntityNum, cl.entityBaselines[newEntityNum]);
158+
if ( CL_DeltaEntity( msg, newSnapshot, newEntityNum, cl.entityBaselines[newEntityNum] ) ) {
159+
break;
160+
}
153161
}
154162
}
155163

@@ -421,7 +429,11 @@ void CL_ParseGamestate( msg_t *msg )
421429
break;
422430
}
423431

424-
if ( cmd == svc_configstring )
432+
if ( cmd == svc_partial ) {
433+
cl.reading = true;
434+
break;
435+
}
436+
else if ( cmd == svc_configstring )
425437
{
426438
i = MSG_ReadShort( msg );
427439

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

449461
cl.reading = false;
450462
}
451-
else if ( cmd == svc_gamestatePartial )
452-
{
453-
cl.reading = true;
454-
break;
455-
}
456463
else
457464
{
458465
Sys::Drop( "CL_ParseGamestate: bad command byte" );
@@ -588,6 +595,9 @@ void CL_ParseServerMessage( msg_t *msg )
588595
case svc_download:
589596
CL_ParseDownload( msg );
590597
break;
598+
599+
case svc_partial:
600+
break;
591601
}
592602
}
593603
}

src/engine/qcommon/msg.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ void MSG_WriteDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, b
919919

920920
MSG_WriteBits( msg, from->number, GENTITYNUM_BITS );
921921
MSG_WriteBits( msg, 1, 1 );
922+
MSG_WriteBits( msg, 0, 1 );
922923
return;
923924
}
924925

@@ -1061,7 +1062,7 @@ Can go from either a baseline or a previous packet_entity
10611062
*/
10621063
extern cvar_t *cl_shownet;
10631064

1064-
void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number )
1065+
bool MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number )
10651066
{
10661067
int i, lc;
10671068
int numFields;
@@ -1088,6 +1089,11 @@ void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *
10881089
// check for a remove
10891090
if ( MSG_ReadBits( msg, 1 ) == 1 )
10901091
{
1092+
// partial snapshot; this is not an actual entity, the next entity had to be put into a different msg
1093+
if ( MSG_ReadBits( msg, 1 ) == 1 ) {
1094+
return true;
1095+
}
1096+
10911097
*to = {};
10921098
to->number = MAX_GENTITIES - 1;
10931099

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

1099-
return;
1105+
return false;
11001106
}
11011107

11021108
// check for no delta
11031109
if ( MSG_ReadBits( msg, 1 ) == 0 )
11041110
{
11051111
*to = *from;
11061112
to->number = number;
1107-
return;
1113+
return false;
11081114
}
11091115

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

12171223
Log::Notice( " (%i bits)", endBit - startBit );
12181224
}
1225+
1226+
return false;
12191227
}
12201228

12211229
/*

src/engine/qcommon/qcommon.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to );
9393
void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to );
9494

9595
void MSG_WriteDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, bool force );
96-
void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number );
96+
bool MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number );
9797

9898
void MSG_InitNetcodeTables(NetcodeTable playerStateTable, int playerStateSize);
9999
void MSG_WriteDeltaPlayerstate( msg_t *msg, const OpaquePlayerState *from, const OpaquePlayerState *to );
@@ -248,12 +248,12 @@ enum svc_ops_e
248248
svc_bad,
249249
svc_nop,
250250
svc_gamestate,
251-
svc_gamestatePartial,
252251
svc_configstring, // [short] [string] only in gamestate messages
253252
svc_baseline, // only in gamestate messages
254253
svc_serverCommand, // [string] to be executed by client game module
255254
svc_download, // [short] size [size bytes]
256255
svc_snapshot,
256+
svc_partial,
257257
svc_EOF
258258
};
259259

src/engine/server/sv_client.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,17 @@ void SV_SendClientGameState( client_t *client )
368368
MSG_WriteByte( &msg, svc_configstring );
369369
MSG_WriteShort( &msg, start );
370370
MSG_WriteBigString( &msg, sv.configstrings[ start ] );
371+
372+
if ( MAX_MSGLEN - msg.cursize < BIG_INFO_STRING ) {
373+
// We have too much configstring data to put it all into one msg_t, so split it here
374+
MSG_WriteByte( &msg, svc_partial );
375+
SV_SendMessageToClient( &msg, client );
376+
377+
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
378+
MSG_WriteLong( &msg, client->lastClientCommand );
379+
MSG_WriteByte( &msg, svc_gamestate );
380+
MSG_WriteLong( &msg, client->reliableSequence );
381+
}
371382
}
372383
}
373384

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

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

394405
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );

src/engine/server/sv_snapshot.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ SV_EmitPacketEntities
6868
Writes a delta update of an entityState_t list to the message.
6969
=============
7070
*/
71-
static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg )
71+
static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg,
72+
client_t* client, int lastframe, int snapFlags )
7273
{
7374
entityState_t *oldent, *newent;
7475
int oldindex, newindex;
@@ -97,6 +98,42 @@ static void SV_EmitPacketEntities( const clientSnapshot_t *from, clientSnapshot_
9798

9899
while ( newindex < to->num_entities || oldindex < from_num_entities )
99100
{
101+
102+
if ( MAX_MSGLEN - msg->cursize < 128 ) {
103+
MSG_WriteBits( msg, 0, GENTITYNUM_BITS );
104+
MSG_WriteBits( msg, 1, 1 );
105+
MSG_WriteBits( msg, 1, 1 );
106+
107+
SV_SendMessageToClient( msg, client );
108+
109+
MSG_Init( msg, msg->data, msg->maxsize );
110+
MSG_WriteByte( msg, svc_snapshot );
111+
112+
MSG_WriteLong( msg, sv.time );
113+
114+
// what we are delta'ing from
115+
MSG_WriteByte( msg, lastframe );
116+
117+
snapFlags = svs.snapFlagServerBit;
118+
119+
MSG_WriteByte( msg, snapFlags );
120+
121+
// send over the areabits
122+
MSG_WriteByte( msg, to->areabytes );
123+
MSG_WriteData( msg, to->areabits, to->areabytes );
124+
125+
{
126+
// delta encode the playerstate
127+
if ( from ) {
128+
MSG_WriteDeltaPlayerstate( msg, &from->ps, &to->ps );
129+
} else {
130+
MSG_WriteDeltaPlayerstate( msg, nullptr, &to->ps );
131+
}
132+
}
133+
134+
MSG_WriteShort( msg, to->num_entities - newindex );
135+
}
136+
100137
if ( newindex >= to->num_entities )
101138
{
102139
newnum = MAX_GENTITIES;
@@ -236,7 +273,7 @@ static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg )
236273
}
237274

238275
// delta encode the entities
239-
SV_EmitPacketEntities( oldframe, frame, msg );
276+
SV_EmitPacketEntities( oldframe, frame, msg, client, lastframe, snapFlags );
240277

241278
// padding for rate debugging
242279
if ( sv_padPackets.Get() )
@@ -265,6 +302,14 @@ void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg )
265302
MSG_WriteByte( msg, svc_serverCommand );
266303
MSG_WriteLong( msg, i );
267304
MSG_WriteString( msg, client->reliableCommands[ i & ( MAX_RELIABLE_COMMANDS - 1 ) ] );
305+
306+
if ( MAX_MSGLEN - msg->cursize < MAX_STRING_CHARS ) {
307+
MSG_WriteByte( msg, svc_partial );
308+
SV_SendMessageToClient( msg, client );
309+
310+
MSG_Init( msg, msg->data, msg->maxsize );
311+
MSG_WriteLong( msg, client->lastClientCommand );
312+
}
268313
}
269314

270315
client->reliableSent = client->reliableSequence;

0 commit comments

Comments
 (0)