1 /*
2 Copyright (C) 2003-2006 Andrey Nazarov
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 //
22 // mvd_parse.c
23 //
24
25 #include "server.h"
26 #include "mvd.h"
27
28 #define MVD_ShowSVC( cmd ) do { \
29 Com_Printf( "%3i:%s\n", msg_read.readcount - 1, \
30 MSG_ServerCommandString( cmd ) ); \
31 } while( 0 )
32
33 /* frame being currently parsed, valid for each packet */
34 static mvdFrame_t *parseFrame;
35
36 /* latest valid gamestate, delta decompression code gets
37 * it's baselines from it */
38 static mvdGamestate_t *parseGS;
39
MVD_LinkEntity(entityStateEx_t * ent)40 static void MVD_LinkEntity( entityStateEx_t *ent ) {
41 vec3_t mins, maxs;
42 cleaf_t *leafs[MAX_TOTAL_ENT_LEAFS];
43 int clusters[MAX_TOTAL_ENT_LEAFS];
44 int num_leafs;
45 int i, j;
46 int area;
47 cnode_t *topnode;
48 int modelindex;
49 cmodel_t *cm;
50 int x, zd, zu;
51 cmcache_t *cache;
52
53 cache = parseGS->cm.cache;
54 if( !cache ) {
55 return;
56
57 }
58 if( ent->s.solid == 31 ) {
59 modelindex = ent->s.modelindex;
60 if( modelindex < 1 || modelindex > cache->numcmodels ) {
61 Com_WPrintf( "MVD_LinkEntity: entity %d: "
62 "bad inline model index: %d\n",
63 ent->s.number, modelindex );
64 ent->linked = qfalse;
65 return;
66 }
67 cm = &cache->cmodels[ modelindex - 1 ];
68 VectorCopy( cm->mins, mins );
69 VectorCopy( cm->maxs, maxs );
70 } else if( ent->s.solid ) {
71 x = 8 * ( ent->s.solid & 31 );
72 zd = 8 * ( ( ent->s.solid >> 5 ) & 31 );
73 zu = 8 * ( ( ent->s.solid >> 10 ) & 63 ) - 32;
74
75 mins[0] = mins[1] = -x;
76 maxs[0] = maxs[1] = x;
77 mins[2] = -zd;
78 maxs[2] = zu;
79 } else {
80 VectorClear( mins );
81 VectorClear( maxs );
82 }
83
84 // set the abs box
85 if( ent->s.solid == 31 &&
86 ( ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2] ) )
87 { // expand for rotation
88 float max, v;
89 int i;
90
91 max = 0;
92 for( i = 0; i < 3; i++ ) {
93 v = fabs( mins[i] );
94 if( v > max )
95 max = v;
96 v = fabs( maxs[i] );
97 if( v > max )
98 max = v;
99 }
100 for( i = 0; i < 3; i++ ) {
101 mins[i] = ent->s.origin[i] - max;
102 maxs[i] = ent->s.origin[i] + max;
103 }
104 } else {
105 // normal
106 VectorAdd( mins, ent->s.origin, mins );
107 VectorAdd( maxs, ent->s.origin, maxs );
108 }
109
110 // because movement is clipped an epsilon away from an actual edge,
111 // we must fully check even when bounding boxes don't quite touch
112 mins[0] -= 1;
113 mins[1] -= 1;
114 mins[2] -= 1;
115 maxs[0] += 1;
116 maxs[1] += 1;
117 maxs[2] += 1;
118
119 // link to PVS leafs
120 ent->num_clusters = 0;
121 ent->areanum = 0;
122 ent->areanum2 = 0;
123
124 // get all leafs, including solids
125 num_leafs = CM_BoxLeafs( &parseGS->cm, mins, maxs,
126 leafs, MAX_TOTAL_ENT_LEAFS, &topnode );
127
128 // set areas
129 for( i = 0; i < num_leafs; i++ ) {
130 clusters[i] = CM_LeafCluster( leafs[i] );
131 area = CM_LeafArea( leafs[i] );
132 if( area ) {
133 // doors may legally straggle two areas,
134 // but nothing should evern need more than that
135 if( ent->areanum && ent->areanum != area ) {
136 ent->areanum2 = area;
137 } else {
138 ent->areanum = area;
139 }
140 }
141 }
142
143 if( num_leafs >= MAX_TOTAL_ENT_LEAFS ) {
144 // assume we missed some leafs, and mark by headnode
145 ent->num_clusters = -1;
146 ent->headnode = topnode;
147 } else {
148 ent->num_clusters = 0;
149 for( i = 0; i < num_leafs; i++ ) {
150 if( clusters[i] == -1 )
151 continue; // not a visible leaf
152 for( j = 0; j < i; j++ )
153 if( clusters[j] == clusters[i] )
154 break;
155 if( j == i ) {
156 if ( ent->num_clusters == MAX_ENT_CLUSTERS ) {
157 // assume we missed some leafs, and mark by headnode
158 ent->num_clusters = -1;
159 ent->headnode = topnode;
160 break;
161 }
162
163 ent->clusternums[ent->num_clusters++] = clusters[i];
164 }
165 }
166 }
167
168 ent->linked = qtrue;
169 }
170
MVD_ParseBaseline(void)171 static void MVD_ParseBaseline( void ) {
172 entityStateEx_t *base, **chunk;
173 int entnum, bits;
174
175 if( !mvd.nextGS ) {
176 Com_Error( ERR_DROP, "MVD_ParseBaseline: not parsing a gamestate" );
177 }
178
179 entnum = MSG_ParseEntityBits( &bits );
180 if( entnum < 1 || entnum >= MAX_EDICTS ) {
181 Com_Error( ERR_DROP, "MVD_ParseBaseline: bad number: %d", entnum );
182 }
183
184 chunk = &mvd.nextGS->baselines[entnum >> SV_BASELINES_SHIFT];
185 if( *chunk == NULL ) {
186 *chunk = MVD_Mallocz( sizeof( *base ) * SV_BASELINES_PER_CHUNK );
187 }
188
189 base = *chunk + ( entnum & SV_BASELINES_MASK );
190 MSG_ParseDeltaEntity( NULL, &base->s, entnum, bits );
191 }
192
MVD_ParseEntityString(void)193 static void MVD_ParseEntityString( void ) {
194 const char *data, *p;
195 char key[MAX_STRING_CHARS];
196 char value[MAX_STRING_CHARS];
197 char classname[MAX_QPATH];
198 vec3_t origin;
199 vec3_t angles;
200
201 parseGS->spawnSet = qfalse;
202
203 data = ( const char * )parseGS->cm.cache->entitystring;
204 if( !data || !data[0] ) {
205 return;
206 }
207
208 while( data ) {
209 p = COM_Parse( &data );
210 if( !p[0] ) {
211 break;
212 }
213 if( p[0] != '{' ) {
214 Com_Error( ERR_DROP, "expected '{', found '%s'", p );
215 }
216
217 classname[0] = 0;
218 VectorClear( origin );
219 VectorClear( angles );
220 while( 1 ) {
221 p = COM_Parse( &data );
222 if( p[0] == '}' ) {
223 break;
224 }
225 if( p[0] == '{' ) {
226 Com_Error( ERR_DROP, "expected key, found '{'" );
227 }
228
229 Q_strncpyz( key, p, sizeof( key ) );
230
231 p = COM_Parse( &data );
232 if( !data ) {
233 Com_Error( ERR_DROP, "expected key/value pair, found EOF" );
234 }
235 if( p[0] == '}' || p[0] == '{' ) {
236 Com_Error( ERR_DROP, "expected value, found '%s'", p );
237 }
238
239 if( !strcmp( key, "classname" ) ) {
240 Q_strncpyz( classname, p, sizeof( classname ) );
241 continue;
242 }
243
244 Q_strncpyz( value, p, sizeof( value ) );
245
246 p = value;
247 if( !strcmp( key, "origin" ) ) {
248 origin[0] = atof( COM_Parse( &p ) );
249 origin[1] = atof( COM_Parse( &p ) );
250 origin[2] = atof( COM_Parse( &p ) );
251 } else if( !strncmp( key, "angle", 5 ) ) {
252 if( key[5] == 0 ) {
253 angles[0] = 0;
254 angles[1] = atof( COM_Parse( &p ) );
255 angles[2] = 0;
256 } else if( key[5] == 's' && key[6] == 0 ) {
257 angles[0] = atof( COM_Parse( &p ) );
258 angles[1] = atof( COM_Parse( &p ) );
259 angles[2] = atof( COM_Parse( &p ) );
260 }
261 }
262 }
263
264 if( !classname[0] ) {
265 Com_Error( ERR_DROP, "entity with no classname" );
266 }
267
268 if( strncmp( classname, "info_player_", 12 ) ) {
269 continue;
270 }
271
272 if( !strcmp( classname + 12, "intermission" ) ) {
273 VectorCopy( origin, parseGS->spawnOrigin );
274 VectorCopy( angles, parseGS->spawnAngles );
275 parseGS->spawnSet = qtrue;
276 continue;
277 }
278
279 if( parseGS->spawnSet ) {
280 continue;
281 }
282
283 if( !strcmp( classname + 12, "start" ) ||
284 !strcmp( classname + 12, "deathmatch" ) )
285 {
286 VectorCopy( origin, parseGS->spawnOrigin );
287 VectorCopy( angles, parseGS->spawnAngles );
288 parseGS->spawnSet = qtrue;
289 }
290
291 }
292
293 if( !parseGS->spawnSet ) {
294 Com_WPrintf( "Couldn't find spawn point for MVD spectators\n" );
295 }
296 }
297
MVD_Precache_f(void)298 static void MVD_Precache_f( void ) {
299 client_t *client;
300 mvdClient_t *mvdcl;
301 entityStateEx_t *base;
302 int i, j;
303 uint32 checksum, check;
304 char *s;
305
306 if( !mvd.nextGS ) {
307 Com_Error( ERR_DROP, "MVD_Precache_f: not parsing a gamestate" );
308 }
309
310 /* parse mapname */
311 if( !mvd.nextGS->mapname[0] ) {
312 Com_Error( ERR_DROP, "MVD_Precache_f: no world model specified" );
313 }
314
315 /* we have completely parsed the gamestate */
316 mvd.nextGS->serverPacketNum = mvd.serverPacketNum;
317 mvd.gamestateSequence++;
318
319 MVD_ClientCommand( va( "begin %d\n", mvd.servercount ) );
320 mvd.validPacketNum = -1;
321
322 if( mvd.netchan &&
323 mvd.serverProtocol > PROTOCOL_VERSION_DEFAULT &&
324 mvd.serverProtocol < PROTOCOL_VERSION_MVD )
325 {
326 MSG_WriteByte( clc_setting );
327 MSG_WriteShort( CLS_RECORDING );
328 MSG_WriteShort( 1 );
329 MSG_FlushTo( &mvd.netchan->message );
330 }
331
332 mvd.lastLayoutPacket = mvd.serverPacketNum - LAYOUT_TIMEOUT / 2;
333
334 if( mvd.state < MVD_PRIMED ) {
335 int maxPlayers = mvd.nextGS->maxclients;
336
337 if( !maxPlayers ) {
338 if( mvd.serverProtocol != PROTOCOL_VERSION_OLD ) {
339 Com_Error( ERR_DROP, "MVD_Precache_f: no maxclients specified" );
340 }
341 maxPlayers = 1; /* ugly hack */
342 } else if( maxPlayers < 0 || maxPlayers > CLIENTNUM_RESERVED ) {
343 Com_Error( ERR_DROP, "MVD_Precache_f: bad maxclients: %d",
344 maxPlayers );
345 }
346
347 if( mvd.serverProtocol == PROTOCOL_VERSION_MVD ) {
348 if( mvd.clientNum != CLIENTNUM_NONE && mvd.clientNum >= maxPlayers ) {
349 Com_Error( ERR_DROP, "MVD_Precache_f: bad clientNum: %d >= %d",
350 mvd.clientNum, maxPlayers );
351 }
352 mvd.maxPlayers = maxPlayers;
353 SV_InitGame( maxPlayers );
354 } else {
355 /* non-MVD protocol needs exactly one player slot */
356 mvd.maxPlayers = 1;
357 SV_InitGame( 1 );
358 svs.maxGameClients = maxPlayers;
359 }
360 MVD_TransitionGamestate( mvd.gamestateSequence );
361
362 parseFrame = &mvd.frames[mvd.serverPacketNum % mvd.frameBackup];
363 parseFrame->serverPacketNum = mvd.serverPacketNum;
364
365 mvd.state = MVD_PRIMED;
366 }
367
368 /* tell all unbuffered clients to reconnect */
369 MSG_WriteByte( svc_stufftext );
370 MSG_WriteString( "reconnect\n" );
371
372 FOR_EACH_CLIENT( client ) {
373 if( client->state < cs_connected ) {
374 continue;
375 }
376 if( client->protocol != PROTOCOL_VERSION_MVD ) {
377 mvdcl = ( mvdClient_t * )client->edict->client;
378 if( !mvdcl->admin ) {
379 continue;
380 }
381 }
382
383 SV_ClientAddMessage( client, MSG_RELIABLE );
384 }
385
386 SZ_Clear( &msg_write );
387
388 parseFrame->gamestateSequence = mvd.gamestateSequence;
389 parseFrame->flags |= MFF_GAMESTATE;
390
391 parseGS = mvd.nextGS;
392 mvd.nextGS = NULL;
393
394 /* load the map and link the baselines */
395 if( mvd.serverProtocol == PROTOCOL_VERSION_MVD ) {
396 CM_LoadMap( &parseGS->cm, parseGS->mapname, CM_LOAD_VISONLY, &checksum );
397
398 check = atoi( mvd.configstrings[CS_MAPCHECKSUM] );
399 if( check != checksum ) {
400 Com_Error( ERR_DROP, "MVD_Precache_f: local map version differs from server" );
401 }
402
403 for( i = 1; i < parseGS->cm.cache->numcmodels; i++ ) {
404 s = mvd.configstrings[ CS_MODELS + 1 + i ];
405 if( *s != '*' ) {
406 Com_Error( ERR_DROP, "MVD_Precache_f: bad inline model %d: %s", i, s );
407 }
408 if( atoi( s + 1 ) != i ) {
409 Com_Error( ERR_DROP, "MVD_Precache_f: mismatched inline model %d: %s", i, s );
410 }
411 }
412
413 MVD_ParseEntityString();
414
415 for( i = 0; i < SV_BASELINES_CHUNKS; i++ ) {
416 base = parseGS->baselines[i];
417 if( !base ) {
418 continue;
419 }
420 for( j = 0; j < SV_BASELINES_PER_CHUNK; j++, base++ ) {
421 if( base->s.number ) {
422 MVD_LinkEntity( base );
423 }
424 }
425 }
426 }
427 }
428
MVD_ParseServerData(void)429 static void MVD_ParseServerData( void ) {
430 int protocol, i;
431 char *gamedir;
432
433 if( mvd.gamestateSequence - mvd.activeGamestateSequence >= MAX_GAMESTATES - 1 ) {
434 Com_Error( ERR_DROP, "MVD_ParseServerData: dropped gamestate" );
435 }
436
437 mvd.nextGS = &mvd.gamestates[( mvd.gamestateSequence + 1 ) & GAMESTATE_MASK];
438 memset( mvd.nextGS, 0, sizeof( *mvd.nextGS ) );
439
440 memset( mvd.configstrings, 0, sizeof( mvd.configstrings ) );
441
442 /* parse protocol version */
443 protocol = MSG_ReadLong();
444 if( protocol != mvd.serverProtocol ) {
445 if( !mvd.demoplayback ) {
446 Com_Error( ERR_DROP,
447 "MVD client requested protocol %i, but "
448 "server returned %i (should not happen).",
449 mvd.serverProtocol, protocol );
450 }
451 if( protocol == PROTOCOL_VERSION_OLD ) {
452 Com_DPrintf( "Using protocol %i for compatibility with old demos\n",
453 PROTOCOL_VERSION_OLD );
454 } else if( protocol < PROTOCOL_VERSION_DEFAULT ||
455 protocol > PROTOCOL_VERSION_MVD )
456 {
457 Com_Error( ERR_DROP,
458 "Demo uses unsupported protocol version %i.\n"
459 "Supported protocols are %i, %i, %i and %i.",
460 protocol, PROTOCOL_VERSION_DEFAULT, PROTOCOL_VERSION_R1Q2,
461 PROTOCOL_VERSION_Q2PRO, PROTOCOL_VERSION_MVD );
462 }
463 mvd.serverProtocol = protocol;
464 }
465
466 mvd.servercount = MSG_ReadLong(); /* servercount */
467 MSG_ReadByte(); /* attractLoop */
468 gamedir = MSG_ReadString(); /* gamedir */
469 i = MSG_ReadShort(); /* clientNum */
470 if( ( unsigned )i >= MAX_CLIENTS ) {
471 i = CLIENTNUM_NONE;
472 }
473 if( mvd.clientNum != i ) {
474 if( mvd.state > MVD_PRIMED ) {
475 Com_Error( ERR_DROP, "Changed clientNum: %d != %d\n",
476 mvd.clientNum, i );
477 }
478 mvd.clientNum = i;
479 }
480 MSG_ReadString(); /* levelname */
481
482 /* change gamedir */
483 if( !mvd.demoplayback ) {
484 Cvar_UserSet( "game", gamedir );
485 }
486
487 if( mvd.serverProtocol == PROTOCOL_VERSION_R1Q2 ) {
488 i = MSG_ReadByte();
489 if( i ) {
490 Com_Error( ERR_DROP, "MVD_ParseServerData: 'enhanced' R1Q2 "
491 "servers are not supported" );
492 }
493 i = MSG_ReadShort();
494 if( i != PROTOCOL_VERSION_R1Q2_MINOR ) {
495 if( mvd.demoplayback ) {
496 Com_WPrintf(
497 "Demo uses different minor R1Q2 protocol version (%i instead of %i).\n"
498 "It may not play back properly.\n",
499 i, PROTOCOL_VERSION_R1Q2_MINOR );
500 } else {
501 if( i < PROTOCOL_VERSION_R1Q2_MINOR ) {
502 Com_Error( ERR_DROP,
503 "Server uses OLDER minor R1Q2 protocol version (%i < %i).\n"
504 "Try reconnecting using original Quake2 protocol.",
505 i, PROTOCOL_VERSION_R1Q2_MINOR );
506 } else {
507 Com_Error( ERR_DROP,
508 "Server uses NEWER minor R1Q2 protocol version (%i > %i).\n"
509 "Consider updating your MVD client or try reconnecting using "
510 "original Quake2 protocol.",
511 i, PROTOCOL_VERSION_R1Q2_MINOR );
512 }
513 }
514 }
515 MSG_ReadByte(); /* advancedDeltas */
516 MSG_ReadByte(); /* strafeHack */
517 } else if( mvd.serverProtocol == PROTOCOL_VERSION_Q2PRO ) {
518 i = MSG_ReadShort();
519 if( i != PROTOCOL_VERSION_Q2PRO_MINOR ) {
520 if( mvd.demoplayback ) {
521 Com_WPrintf(
522 "Demo uses different minor Q2PRO protocol version (%i instead of %i).\n"
523 "It may not play back properly.\n",
524 i, PROTOCOL_VERSION_Q2PRO_MINOR );
525 } else {
526 if( i < PROTOCOL_VERSION_Q2PRO_MINOR ) {
527 Com_Error( ERR_DROP,
528 "Server uses OLDER minor Q2PRO protocol version (%i < %i).\n"
529 "Try reconnecting using original Quake2 protocol or R1Q2 protocol.",
530 i, PROTOCOL_VERSION_Q2PRO_MINOR );
531 } else {
532 Com_Error( ERR_DROP,
533 "Server uses NEWER minor Q2PRO protocol version (%i > %i).\n"
534 "Consider updating your MVD client or try reconnecting using "
535 "original Quake2 protocol or R1Q2 protocol.",
536 i, PROTOCOL_VERSION_Q2PRO_MINOR );
537 }
538 }
539 }
540 MSG_ReadByte(); /* gametype */
541 MSG_ReadByte(); /* strafeHack */
542 MSG_ReadByte(); //atu QWMod
543 } else if( mvd.serverProtocol == PROTOCOL_VERSION_MVD ) {
544 i = MSG_ReadShort();
545 if( i != PROTOCOL_VERSION_MVD_MINOR ) {
546 if( mvd.demoplayback ) {
547 Com_WPrintf(
548 "Demo uses different minor MVD protocol version (%i instead of %i).\n"
549 "It may not play back properly.\n",
550 i, PROTOCOL_VERSION_MVD_MINOR );
551 } else {
552 if( i < PROTOCOL_VERSION_MVD_MINOR ) {
553 Com_Error( ERR_DROP,
554 "Server uses OLDER minor MVD protocol version (%i < %i).\n"
555 "Try reconnecting using non-MVD protocol.",
556 i, PROTOCOL_VERSION_MVD_MINOR );
557 } else {
558 Com_Error( ERR_DROP,
559 "Server uses NEWER minor MVD protocol version (%i > %i).\n"
560 "Consider updating your MVD client or try reconnecting using "
561 "non-MVD protocol.",
562 i, PROTOCOL_VERSION_MVD_MINOR );
563 }
564 }
565 }
566 }
567
568 mvd.validPacketNum = -1;
569 }
570
MVD_WriteFrameDatagram(byte * data,int length)571 static void MVD_WriteFrameDatagram( byte *data, int length ) {
572 int ofs, mask;
573
574 if( mvd.state < MVD_PRIMED ) {
575 Com_DPrintf( "MVD_WriteFrameDatagram: server data not yet received\n" );
576 return;
577 }
578
579 /* write complete message into the circular buffer */
580 ofs = mvd.nextMessageBytes;
581 mask = mvd.maxMessageBytes - 1;
582 parseFrame->numMessageBytes += length;
583 mvd.nextMessageBytes += length;
584 for( ; length; length--, ofs++ ) {
585 mvd.messageBytes[ofs & mask] = *data++;
586 }
587 }
588
MVD_WriteFrameReliableDatagram(byte * data,int length)589 static void MVD_WriteFrameReliableDatagram( byte *data, int length ) {
590 int ofs, mask;
591
592 if( mvd.state < MVD_PRIMED ) {
593 Com_DPrintf( "MVD_WriteFrameReliableDatagram: server data not yet received\n" );
594 return;
595 }
596
597 /* write complete message into the circular buffer */
598 ofs = mvd.nextReliableMessageBytes;
599 mask = mvd.maxReliableMessageBytes - 1;
600 parseFrame->numReliableMessageBytes += length;
601 parseFrame->flags |= MFF_RELIABLE;
602 mvd.nextReliableMessageBytes += length;
603 for( ; length; length--, ofs++ ) {
604 mvd.reliableMessageBytes[ofs & mask] = *data++;
605 }
606 }
607
608
MVD_ParseMulticast(void)609 static void MVD_ParseMulticast( void ) {
610 multicast_t to;
611 int length;
612 byte *data;
613 client_t *client;
614 union {
615 vec_t v[3];
616 uint32 l[3];
617 } origin;
618
619 /* including svc_multicast byte */
620 data = msg_read.data + msg_read.readcount - 1;
621
622 length = MSG_ReadShort();
623 to = ( length >> 12 ) & 7;
624 length &= 0xFFF;
625
626 if( to > MULTICAST_PVS_R ) {
627 Com_Error( ERR_DROP, "MVD_ParseMulticast: bad to" );
628 }
629
630 if( length < 1 ) {
631 Com_Error( ERR_DROP, "MVD_ParseMulticast: bad length" );
632 }
633
634 if( to != MULTICAST_ALL && to != MULTICAST_ALL_R ) {
635 origin.l[0] = MSG_ReadLong();
636 origin.l[1] = MSG_ReadLong();
637 origin.l[2] = MSG_ReadLong();
638 } else {
639 VectorClear( origin.v );
640 }
641
642 msg_read.readcount += length;
643 if( msg_read.readcount > msg_read.cursize ) {
644 Com_Error( ERR_DROP, "MVD_ParseMulticast: read past end of message" );
645 }
646
647 if( to != MULTICAST_ALL && to != MULTICAST_ALL_R ) {
648 length += 12;
649 }
650 length += 3;
651
652 if( to >= MULTICAST_ALL_R ) {
653 MVD_WriteFrameReliableDatagram( data, length );
654 } else {
655 MVD_WriteFrameDatagram( data, length );
656 }
657
658 /* add this immediately to MVD clients */
659 FOR_EACH_CLIENT( client ) {
660 if( client->state < cs_spawned ) {
661 continue;
662 }
663 if( client->protocol == PROTOCOL_VERSION_MVD ) {
664 client->AddMessage( client, data, length,
665 to >= MULTICAST_ALL_R ? qtrue : qfalse );
666 }
667 }
668
669 /* add this immediately to unbuffered clients */
670 MVD_Multicast( qtrue, origin.v, to );
671
672 }
673
MVD_ParseUnicast(void)674 static void MVD_ParseUnicast( void ) {
675 int length, clientNum;
676 byte *data;
677 client_t *client;
678
679 /* including svc_unicast byte */
680 data = msg_read.data + msg_read.readcount - 1;
681
682 clientNum = MSG_ReadByte(); /* skip clientNum */
683 length = MSG_ReadShort();
684 clientNum &= 0x7F;
685 if( ( unsigned )clientNum >= mvd.maxPlayers ) {
686 Com_Error( ERR_DROP, "MVD_ParseUnicast: bad clientNum" );
687 }
688 if( length < 1 ) {
689 Com_Error( ERR_DROP, "MVD_ParseUnicast: bad length" );
690 }
691
692 if( clientNum == mvd.clientNum && msg_read.data[msg_read.readcount] == svc_layout ) {
693 mvd.lastLayoutPacket = mvd.serverPacketNum;
694 }
695
696 msg_read.readcount += length;
697 if( msg_read.readcount > msg_read.cursize ) {
698 Com_Error( ERR_DROP, "MVD_ParseUnicast: read past end of message" );
699 }
700
701 length += 4;
702
703 MVD_WriteFrameReliableDatagram( data, length );
704
705 /* add this immediately to MVD clients */
706 FOR_EACH_CLIENT( client ) {
707 if( client->state < cs_connected ) {
708 continue;
709 }
710 if( client->protocol == PROTOCOL_VERSION_MVD ) {
711 client->AddMessage( client, data, length, qtrue );
712 }
713 }
714 }
715
MVD_ParseConfigstring(void)716 static void MVD_ParseConfigstring( void ) {
717 mvdConfigstring_t *cs;
718 int length, index, stringLength;
719 byte *data;
720 char *string;
721 client_t *client;
722 mvdClient_t *mvdcl;
723
724 /* including svc_configstring byte */
725 data = msg_read.data + msg_read.readcount - 1;
726
727 length = msg_read.readcount;
728 index = MSG_ReadShort();
729 if( index < 0 || index >= MAX_CONFIGSTRINGS ) {
730 Com_Error( ERR_DROP, "MVD_ParseConfigstring: bad index: %d", index );
731 }
732 string = MSG_ReadString();
733 length = msg_read.readcount - length + 1;
734
735 stringLength = strlen( string );
736 if( sizeof( mvd.configstrings[0] ) * index + stringLength >
737 sizeof( mvd.configstrings ) - 1 )
738 {
739 Com_Error( ERR_DROP, "MVD_ParseConfigstring: oversize configstring" );
740 }
741
742 /* archive in our latest configstrings array */
743 strcpy( mvd.configstrings[index], string );
744
745 if( !mvd.nextGS ) {
746 if( mvd.state < MVD_PRIMED ) {
747 Com_DPrintf( "Out-of-place CS %d: %s\n", index, string );
748 return;
749 }
750 /* add this stuff immediately for camera people */
751 FOR_EACH_CLIENT( client ) {
752 if( client->state < cs_connected ) {
753 continue;
754 }
755 if( client->protocol != PROTOCOL_VERSION_MVD ) {
756 mvdcl = ( mvdClient_t * )client->edict->client;
757 if( !mvdcl->admin ) {
758 continue;
759 }
760 }
761 client->AddMessage( client, data, length, qtrue );
762 }
763 MVD_WriteFrameReliableDatagram( data, length );
764 return;
765 }
766
767 /* assume server is smart enough and doesn't send dup. configstrings */
768 cs = MVD_Mallocz( sizeof( *cs ) + stringLength );
769 strcpy( cs->string, string );
770 cs->index = index;
771 if( mvd.nextGS->tailCS ) {
772 mvd.nextGS->tailCS->next = cs;
773 } else {
774 mvd.nextGS->headCS = cs;
775 }
776 mvd.nextGS->tailCS = cs;
777
778 /* parse additional data */
779 switch( index ) {
780 case CS_MODELS + 1:
781 Q_strncpyz( mvd.nextGS->mapname, string, MAX_QPATH );
782 break;
783 case CS_MAXCLIENTS:
784 mvd.nextGS->maxclients = atoi( string );
785 break;
786 case CS_NAME:
787 Q_strncpyz( mvd.nextGS->fullname, string, MAX_QPATH );
788 break;
789 default:
790 break;
791 }
792 }
793
MVD_FixEntityStates(mvdFrame_t * prevFrame,mvdFrame_t * currFrame)794 static void MVD_FixEntityStates( mvdFrame_t *prevFrame, mvdFrame_t *currFrame ) {
795 entityStateEx_t *prevStates[MAX_EDICTS];
796 entityStateEx_t *currStates[MAX_CLIENTS + 1];
797 entityStateEx_t *state, *prev;
798 playerStateEx_t *ps;
799 int i, j;
800
801 for( i = 0; i < MAX_EDICTS; i++ ) {
802 prevStates[i] = NULL;
803 }
804
805 for( i = 0; i < MAX_CLIENTS; i++ ) {
806 currStates[i] = NULL;
807 }
808
809 for( i = 0; i < prevFrame->numEntityStates; i++ ) {
810 j = ( prevFrame->firstEntityState + i ) % mvd.maxEntityStates;
811 state = &mvd.entityStates[j];
812
813 if( ( unsigned )state->s.number >= MAX_EDICTS ) {
814 Com_Error( ERR_DROP, "MVD_FixEntityStates: bad entity number: %d",
815 state->s.number );
816 }
817
818 prevStates[state->s.number] = state;
819 }
820
821 for( i = 0; i < currFrame->numEntityStates; i++ ) {
822 j = ( currFrame->firstEntityState + i ) % mvd.maxEntityStates;
823 state = &mvd.entityStates[j];
824
825 if( ( unsigned )state->s.number >= MAX_EDICTS ) {
826 Com_Error( ERR_DROP, "MVD_FixEntityStates: bad entity number: %d",
827 state->s.number );
828 }
829
830 if( state->s.number <= MAX_CLIENTS ) {
831 currStates[state->s.number] = state;
832 }
833 }
834
835 if( mvd.serverProtocol >= PROTOCOL_VERSION_Q2PRO ) {
836 for( i = 0; i < currFrame->numPlayerStates; i++ ) {
837 j = ( currFrame->firstPlayerState + i ) % mvd.maxPlayerStates;
838 ps = &mvd.playerStates[j];
839
840 if( ( unsigned )ps->number >= mvd.maxPlayers ) {
841 Com_Error( ERR_DROP, "MVD_FixEntityStates: bad player number: %d\n",
842 ps->number );
843 }
844 if( ( unsigned )ps->clientNum >= MAX_CLIENTS ) {
845 Com_Error( ERR_DROP, "MVD_FixEntityStates: bad clientNum: %d\n",
846 ps->clientNum );
847 }
848
849 if( ps->ps.pmove.pm_type >= PM_DEAD ) {
850 continue;
851 }
852 if( ps->clientNum == CLIENTNUM_NONE ) {
853 continue;
854 }
855 state = currStates[ ps->clientNum + 1 ];
856 if( !state ) {
857 continue;
858 }
859
860 VectorScale( ps->ps.pmove.origin, 0.125f, state->s.origin );
861 VectorCopy( ps->ps.viewangles, state->s.angles );
862
863 if( state->s.angles[PITCH] > 180 ) {
864 state->s.angles[PITCH] -= 360;
865 }
866
867 state->s.angles[PITCH] = state->s.angles[PITCH] / 3;
868
869 if( mvd.serverProtocol == PROTOCOL_VERSION_MVD ) {
870 MVD_LinkEntity( state );
871 }
872
873 }
874 }
875
876 for( i = 0; i < currFrame->numEntityStates; i++ ) {
877 j = ( currFrame->firstEntityState + i ) % mvd.maxEntityStates;
878 state = &mvd.entityStates[j];
879
880 if( ( unsigned )state->s.number >= MAX_EDICTS ) {
881 Com_Error( ERR_DROP, "MVD_FixEntityStates: bad entity number: %d",
882 state->s.number );
883 }
884
885 if( state->s.renderfx & RF_BEAM ) {
886 continue;
887 }
888
889 prev = prevStates[state->s.number];
890 if( prev ) {
891 VectorCopy( prev->s.origin, state->s.old_origin );
892 }
893 }
894
895 }
896
897
898 /*
899 ==================
900 MVD_ParseDeltaEntity
901 ==================
902 */
903
904 #define RELINK_MASK \
905 (U_MODEL|U_ORIGIN1|U_ORIGIN2|U_ORIGIN3|U_SOLID)
906
MVD_ParseDeltaEntity(mvdFrame_t * frame,int newnum,entityStateEx_t * old,int bits)907 static void MVD_ParseDeltaEntity( mvdFrame_t *frame, int newnum,
908 entityStateEx_t *old, int bits )
909 {
910 entityStateEx_t *state;
911 int i;
912
913 i = mvd.nextEntityStates % mvd.maxEntityStates;
914 state = &mvd.entityStates[i];
915 mvd.nextEntityStates++;
916 frame->numEntityStates++;
917
918 if( mvd_shownet->integer > 2 ) {
919 MSG_ShowDeltaEntityBits( bits );
920 }
921
922 MSG_ParseDeltaEntity( ( entity_state_t * )old, ( entity_state_t * )state, newnum, bits );
923
924 if( mvd.serverProtocol == PROTOCOL_VERSION_MVD && newnum > parseGS->maxclients ) {
925 if( !old || !old->linked || ( bits & RELINK_MASK ) ) {
926 MVD_LinkEntity( state );
927 } else {
928 state->linked = qtrue;
929 state->num_clusters = old->num_clusters;
930 state->headnode = old->headnode;
931 state->areanum = old->areanum;
932 state->areanum2 = old->areanum2;
933 for( i = 0; i < state->num_clusters; i++ ) {
934 state->clusternums[i] = old->clusternums[i];
935 }
936 }
937 }
938 }
939
940 /*
941 ==================
942 MVD_ParsePacketEntities
943 ==================
944 */
MVD_ParsePacketEntities(mvdFrame_t * oldframe,mvdFrame_t * frame)945 static void MVD_ParsePacketEntities( mvdFrame_t *oldframe,
946 mvdFrame_t *frame )
947 {
948 int newnum;
949 int bits;
950 entityStateEx_t *oldstate, *base;
951 int oldindex, oldnum;
952 int i;
953
954 frame->firstEntityState = mvd.nextEntityStates;
955 frame->numEntityStates = 0;
956
957 // delta from the entities present in oldframe
958 oldindex = 0;
959 oldstate = NULL;
960 if( !oldframe ) {
961 oldnum = 99999;
962 } else {
963 if( oldindex >= oldframe->numEntityStates ) {
964 oldnum = 99999;
965 } else {
966 i = oldframe->firstEntityState + oldindex;
967 i %= mvd.maxEntityStates;
968 oldstate = &mvd.entityStates[i];
969 oldnum = oldstate->s.number;
970 }
971 }
972
973 while( 1 ) {
974 newnum = MSG_ParseEntityBits( &bits );
975 if( newnum < 0 || newnum >= MAX_EDICTS ) {
976 Com_Error( ERR_DROP, "ParsePacketEntities: bad number %i",
977 newnum );
978 }
979
980 if( msg_read.readcount > msg_read.cursize ) {
981 Com_Error( ERR_DROP, "ParsePacketEntities: end of message" );
982 }
983
984 if( !newnum ) {
985 break;
986 }
987
988 while( oldnum < newnum ) {
989 // one or more entities from the old packet are unchanged
990 if( mvd_shownet->integer > 2 ) {
991 Com_Printf( " unchanged: %i\n", oldnum );
992 }
993 MVD_ParseDeltaEntity( frame, oldnum, oldstate, 0 );
994
995 oldindex++;
996
997 if( oldindex >= oldframe->numEntityStates ) {
998 oldnum = 99999;
999 } else {
1000 i = oldframe->firstEntityState + oldindex;
1001 i %= mvd.maxEntityStates;
1002 oldstate = &mvd.entityStates[i];
1003 oldnum = oldstate->s.number;
1004 }
1005 }
1006
1007 if( bits & U_REMOVE ) {
1008 // the entity present in oldframe is not in the current frame
1009 if( mvd_shownet->integer > 2 ) {
1010 Com_Printf( " remove: %i\n", newnum );
1011 }
1012 if( oldnum != newnum ) {
1013 Com_DPrintf( "U_REMOVE: oldnum != newnum\n" );
1014 }
1015 if( !oldframe ) {
1016 Com_Error( ERR_DROP, "U_REMOVE: NULL oldframe" );
1017 }
1018 if( !oldstate ) {
1019 Com_Error( ERR_DROP, "U_REMOVE: NULL oldstate" );
1020 }
1021
1022 oldindex++;
1023
1024 if( oldindex >= oldframe->numEntityStates ) {
1025 oldnum = 99999;
1026 } else {
1027 i = oldframe->firstEntityState + oldindex;
1028 i %= mvd.maxEntityStates;
1029 oldstate = &mvd.entityStates[i];
1030 oldnum = oldstate->s.number;
1031 }
1032 continue;
1033 }
1034
1035 if( oldnum == newnum ) {
1036 // delta from previous state
1037 if( mvd_shownet->integer > 2 ) {
1038 Com_Printf( " delta: %i ", newnum );
1039 }
1040 MVD_ParseDeltaEntity( frame, newnum, oldstate, bits );
1041 if( mvd_shownet->integer > 2 ) {
1042 Com_Printf( "\n" );
1043 }
1044
1045 oldindex++;
1046
1047 if( oldindex >= oldframe->numEntityStates ) {
1048 oldnum = 99999;
1049 } else {
1050 i = oldframe->firstEntityState + oldindex;
1051 i %= mvd.maxEntityStates;
1052 oldstate = &mvd.entityStates[i];
1053 oldnum = oldstate->s.number;
1054 }
1055 continue;
1056 }
1057
1058 if( oldnum > newnum ) {
1059 // delta from baseline
1060 if( mvd_shownet->integer > 2 ) {
1061 Com_Printf( " baseline: %i ", newnum );
1062 }
1063 base = parseGS->baselines[newnum >> SV_BASELINES_SHIFT];
1064 if( base ) {
1065 base += newnum & SV_BASELINES_MASK;
1066 }
1067 MVD_ParseDeltaEntity( frame, newnum, base, bits );
1068 if( mvd_shownet->integer > 2 ) {
1069 Com_Printf( "\n" );
1070 }
1071 continue;
1072 }
1073
1074 }
1075
1076 // any remaining entities in the old frame are copied over
1077 while( oldnum != 99999 ) {
1078 // one or more entities from the old packet are unchanged
1079 if( mvd_shownet->integer > 2 ) {
1080 Com_Printf( " unchanged: %i\n", oldnum );
1081 }
1082 MVD_ParseDeltaEntity( frame, oldnum, oldstate, 0 );
1083
1084 oldindex++;
1085
1086 if( oldindex >= oldframe->numEntityStates ) {
1087 oldnum = 99999;
1088 } else {
1089 i = oldframe->firstEntityState + oldindex;
1090 i %= mvd.maxEntityStates;
1091 oldstate = &mvd.entityStates[i];
1092 oldnum = oldstate->s.number;
1093 }
1094 }
1095 }
1096
1097 /*
1098 ==================
1099 MVD_ParseDeltaPlayer
1100 ==================
1101 */
MVD_ParseDeltaPlayer(mvdFrame_t * frame,int newnum,playerStateEx_t * old,int bits)1102 static void MVD_ParseDeltaPlayer( mvdFrame_t *frame, int newnum,
1103 playerStateEx_t *old, int bits )
1104 {
1105 playerStateEx_t *state;
1106 int i;
1107
1108 i = mvd.nextPlayerStates % mvd.maxPlayerStates;
1109 state = &mvd.playerStates[i];
1110 mvd.nextPlayerStates++;
1111 frame->numPlayerStates++;
1112
1113 if( mvd_shownet->integer > 2 ) {
1114 MSG_ShowDeltaPlayerstateBits_Enhanced( bits );
1115 }
1116 MSG_ParseDeltaPlayerstate_Enhanced( old, state, bits );
1117
1118 state->number = newnum;
1119 state->clientNum = newnum;
1120 }
1121
1122 /*
1123 ==================
1124 MVD_ParsePacketPlayers
1125 ==================
1126 */
MVD_ParsePacketPlayers(mvdFrame_t * oldframe,mvdFrame_t * frame)1127 static void MVD_ParsePacketPlayers( mvdFrame_t *oldframe, mvdFrame_t *frame ) {
1128 int newnum;
1129 int bits;
1130 playerStateEx_t *oldstate;
1131 int oldindex, oldnum;
1132 int i;
1133
1134 frame->firstPlayerState = mvd.nextPlayerStates;
1135 frame->numPlayerStates = 0;
1136
1137 // delta from the players present in oldframe
1138 oldindex = 0;
1139 oldstate = NULL;
1140 if( !oldframe ) {
1141 oldnum = 99999;
1142 } else {
1143 if( oldindex >= oldframe->numPlayerStates ) {
1144 oldnum = 99999;
1145 } else {
1146 i = oldframe->firstPlayerState + oldindex;
1147 i %= mvd.maxPlayerStates;
1148 oldstate = &mvd.playerStates[i];
1149 oldnum = oldstate->number;
1150 }
1151 }
1152
1153 while( 1 ) {
1154 newnum = MSG_ReadByte();
1155 if( newnum < 0 || newnum >= MAX_CLIENTS ) {
1156 Com_Error( ERR_DROP, "Delta_ParsePacketPlayers: bad number %i",
1157 newnum );
1158 }
1159
1160 if( msg_read.readcount > msg_read.cursize ) {
1161 Com_Error( ERR_DROP, "Delta_ParsePacketPlayers: end of message" );
1162 }
1163
1164 if( newnum == CLIENTNUM_NONE ) {
1165 break;
1166 }
1167
1168 bits = MSG_ReadShort();
1169 if( !( bits & PS_REMOVE ) ) {
1170 /* read extraflags */
1171 bits |= MSG_ReadByte() << PS_BITS;
1172 }
1173
1174 while( oldnum < newnum ) {
1175 // one or more players from the old packet are unchanged
1176 if( mvd_shownet->integer > 2 ) {
1177 Com_Printf( " unchanged: %i\n", oldnum );
1178 }
1179 MVD_ParseDeltaPlayer( frame, oldnum, oldstate, 0 );
1180
1181 oldindex++;
1182
1183 if( oldindex >= oldframe->numPlayerStates ) {
1184 oldnum = 99999;
1185 } else {
1186 i = oldframe->firstPlayerState + oldindex;
1187 i %= mvd.maxPlayerStates;
1188 oldstate = &mvd.playerStates[i];
1189 oldnum = oldstate->number;
1190 }
1191 }
1192
1193 if( bits & PS_REMOVE ) {
1194 // the entity present in oldframe is not in the current frame
1195 if( mvd_shownet->integer > 2 ) {
1196 Com_Printf( " remove: %i\n", newnum );
1197 }
1198 if( oldnum != newnum ) {
1199 Com_DPrintf( "U_REMOVE: oldnum != newnum\n" );
1200 }
1201 if( !oldframe ) {
1202 Com_Error( ERR_DROP, "U_REMOVE: NULL oldframe" );
1203 }
1204 if( !oldstate ) {
1205 Com_Error( ERR_DROP, "U_REMOVE: NULL oldstate" );
1206 }
1207
1208 oldindex++;
1209
1210 if( oldindex >= oldframe->numPlayerStates ) {
1211 oldnum = 99999;
1212 } else {
1213 i = oldframe->firstPlayerState + oldindex;
1214 i %= mvd.maxPlayerStates;
1215 oldstate = &mvd.playerStates[i];
1216 oldnum = oldstate->number;
1217 }
1218 continue;
1219 }
1220
1221 if( oldnum == newnum ) {
1222 // delta from previous state
1223 if( mvd_shownet->integer > 2 ) {
1224 Com_Printf( " delta: %i ", newnum );
1225 }
1226 MVD_ParseDeltaPlayer( frame, newnum, oldstate, bits );
1227 if( mvd_shownet->integer > 2 ) {
1228 Com_Printf( "\n" );
1229 }
1230
1231 oldindex++;
1232
1233 if( oldindex >= oldframe->numPlayerStates ) {
1234 oldnum = 99999;
1235 } else {
1236 i = oldframe->firstPlayerState + oldindex;
1237 i %= mvd.maxPlayerStates;
1238 oldstate = &mvd.playerStates[i];
1239 oldnum = oldstate->number;
1240 }
1241 continue;
1242 }
1243
1244 if( oldnum > newnum ) {
1245 // delta from baseline
1246 if( mvd_shownet->integer > 2 ) {
1247 Com_Printf( " baseline: %i ", newnum );
1248 }
1249 MVD_ParseDeltaPlayer( frame, newnum, NULL, bits );
1250 if( mvd_shownet->integer > 2 ) {
1251 Com_Printf( "\n" );
1252 }
1253 continue;
1254 }
1255
1256 }
1257
1258 while( oldnum != 99999 ) {
1259 if( mvd_shownet->integer > 2 ) {
1260 Com_Printf( " unchanged: %i\n", oldnum );
1261 }
1262 MVD_ParseDeltaPlayer( frame, oldnum, oldstate, 0 );
1263
1264 oldindex++;
1265
1266 if( oldindex >= oldframe->numPlayerStates ) {
1267 oldnum = 99999;
1268 } else {
1269 i = oldframe->firstPlayerState + oldindex;
1270 i %= mvd.maxPlayerStates;
1271 oldstate = &mvd.playerStates[i];
1272 oldnum = oldstate->number;
1273 }
1274 }
1275 }
1276
MVD_SpawnClients(void)1277 static void MVD_SpawnClients( void ) {
1278 client_t *client;
1279 mvdClient_t *mvdcl;
1280
1281 FOR_EACH_CLIENT( client ) {
1282 if( client->state != cs_ready ) {
1283 continue;
1284 }
1285 if( client->protocol != PROTOCOL_VERSION_MVD ) {
1286 mvdcl = ( mvdClient_t * )client->edict->client;
1287 if( !mvdcl->admin ) {
1288 continue;
1289 }
1290 }
1291 Com_DPrintf( "Going from cs_ready to cs_spawned for %s\n",
1292 client->name );
1293 client->state = cs_spawned;
1294 client->sendTime = 0;
1295 client->surpressCount = 0;
1296 client->commandMsec = 1800;
1297
1298 // call the game begin function
1299 sv_client = client;
1300 sv_player = client->edict;
1301 ge->ClientBegin( client->edict );
1302 sv_client = NULL;
1303 sv_player = NULL;
1304
1305 }
1306 }
1307
1308 /*
1309 ================
1310 MVD_ParseFrame
1311 ================
1312 */
MVD_ParseFrame(void)1313 static void MVD_ParseFrame( void ) {
1314 mvdFrame_t *oldframe;
1315 int currentframe, deltaframe, delta, deltaPacketNum;
1316 int length;
1317 uint32 bits;
1318
1319 if( mvd.state < MVD_PRIMED ) {
1320 Com_Error( ERR_DROP, "MVD_ParseFrame: server data not yet received" );
1321 }
1322
1323 if( parseFrame->serverFrame ) {
1324 Com_Error( ERR_DROP, "MVD_ParseFrame: duplicated frame in packet" );
1325 }
1326
1327 bits = MSG_ReadLong();
1328
1329 currentframe = bits & FRAMENUM_MASK;
1330 delta = bits >> FRAMENUM_BITS;
1331
1332 if( delta == 31 ) {
1333 deltaframe = -1;
1334 } else {
1335 deltaframe = currentframe - delta;
1336 }
1337
1338 mvd.packetNums[currentframe & UPDATE_MASK] = mvd.serverPacketNum;
1339
1340 parseFrame->serverFrame = currentframe;
1341 parseFrame->flags |= MFF_ACTIVE;
1342
1343 /*
1344 * If the frame is delta compressed from data that we
1345 * no longer have available, we must suck up the rest of
1346 * the frame, but not use it, then ask for a non-compressed
1347 * message
1348 */
1349 if( deltaframe > 0 ) {
1350 deltaPacketNum = mvd.packetNums[deltaframe & UPDATE_MASK];
1351 parseFrame->deltaPacketNum = deltaPacketNum;
1352
1353 oldframe = &mvd.frames[deltaPacketNum % mvd.frameBackup];
1354 if( deltaframe == currentframe ) {
1355 /* should never happen */
1356 Com_WPrintf( "Delta from current frame (should not happen).\n" );
1357 } else if( !( oldframe->flags & MFF_VALID ) ) {
1358 /* should never happen */
1359 Com_WPrintf( "Delta from invalid frame (should not happen).\n" );
1360 } else if( oldframe->serverPacketNum != deltaPacketNum ) {
1361 /* The frame that the server did the delta from
1362 * is too old, so we can't reconstruct it properly.
1363 */
1364 Com_WPrintf( "Delta frame too old.\n" );
1365 } else if(
1366 mvd.nextEntityStates -
1367 oldframe->firstEntityState >
1368 mvd.maxEntityStates - MAX_EDICTS )
1369 {
1370 Com_WPrintf( "Delta entityStates too old.\n" );
1371 } else if(
1372 mvd.nextPlayerStates -
1373 oldframe->firstPlayerState >
1374 mvd.maxPlayerStates - mvd.maxPlayers )
1375 {
1376 Com_WPrintf( "Delta playerStates too old.\n" );
1377 } else {
1378 parseFrame->flags |= MFF_VALID; /* valid delta parse */
1379 }
1380 } else {
1381 oldframe = NULL;
1382 mvd.demowaiting = qfalse;
1383 parseFrame->flags |= MFF_VALID; /* uncompressed frame */
1384 }
1385
1386 /* read portalbits */
1387 length = MSG_ReadByte();
1388 if( length ) {
1389 if( ( unsigned )length > sizeof( parseFrame->portalbytes ) ) {
1390 Com_Error( ERR_DROP, "MVD_ParseFrame: invalid portalbits length" );
1391 }
1392 if( msg_read.readcount + length > msg_read.cursize ) {
1393 Com_Error( ERR_DROP, "MVD_ParseFrame: read past end of message" );
1394 }
1395 MSG_ReadData( parseFrame->portalbytes, length );
1396 parseFrame->numPortalBytes = length;
1397 } else {
1398 memset( parseFrame->portalbytes, 255, sizeof( parseFrame->portalbytes ) );
1399 parseFrame->numPortalBytes = 0;
1400 }
1401
1402 if( mvd_shownet->integer > 1 ) {
1403 Com_Printf( "%3i:playerinfo\n", msg_read.readcount - 1 );
1404 }
1405
1406 MVD_ParsePacketPlayers( oldframe, parseFrame );
1407
1408 if( mvd_shownet->integer > 1 ) {
1409 Com_Printf( "%3i:packetentities\n", msg_read.readcount - 1 );
1410 }
1411
1412 MVD_ParsePacketEntities( oldframe, parseFrame );
1413
1414 if( mvd_shownet->integer > 1 ) {
1415 Com_Printf( "%3i: frame:%i delta:%i\n",
1416 msg_read.readcount - 1, parseFrame->serverPacketNum,
1417 parseFrame->deltaPacketNum );
1418 }
1419
1420 if( !( parseFrame->flags & MFF_VALID ) ) {
1421 return; /* do not change anything */
1422 }
1423
1424 if( mvd.validPacketNum == -1 ) {
1425 MVD_SpawnClients();
1426 }
1427 mvd.validPacketNum = mvd.serverPacketNum;
1428 mvd.lastServerFrame = currentframe;
1429
1430 if( mvd.state < MVD_BUFFERING ) {
1431 mvd.state = MVD_BUFFERING;
1432 Com_DPrintf( "Started buffering at frame %d\n", mvd.serverPacketNum );
1433 mvd.activePacketNum = mvd.serverPacketNum;
1434 }
1435
1436 oldframe = &mvd.frames[( mvd.serverPacketNum - 1 ) % mvd.frameBackup];
1437 MVD_FixEntityStates( oldframe, parseFrame );
1438 }
1439
1440
MVD_ParsePrint(void)1441 static void MVD_ParsePrint( void ) {
1442 int level;
1443 char *string;
1444
1445 level = MSG_ReadByte();
1446 string = MSG_ReadString();
1447
1448 Com_Printf( "[MVD] %s", string );
1449 }
1450
MVD_Reconnect_f(void)1451 static void MVD_Reconnect_f( void ) {
1452 MVD_ClientCommand( "new" );
1453 }
1454
MVD_Wait_f(void)1455 static void MVD_Wait_f( void ) {
1456 mvd_buffer.waitCount = 1;
1457 }
1458
MVD_Changing_f(void)1459 static void MVD_Changing_f( void ) {
1460 client_t *client;
1461 mvdClient_t *mvdcl;
1462
1463 MSG_WriteByte( svc_stufftext );
1464 MSG_WriteString( "changing\n" );
1465
1466 FOR_EACH_CLIENT( client ) {
1467 if( client->state < cs_connected ) {
1468 continue;
1469 }
1470 if( client->protocol != PROTOCOL_VERSION_MVD ) {
1471 mvdcl = ( mvdClient_t * )client->edict->client;
1472 if( !mvdcl->admin ) {
1473 continue;
1474 }
1475 }
1476 client->state = cs_connected;
1477 client->lastframe = -1;
1478 client->sendTime = 0;
1479 client->surpressCount = 0;
1480
1481 SV_ClientAddMessage( client, MSG_RELIABLE );
1482 }
1483
1484 SZ_Clear( &msg_write );
1485
1486 SV_SendAsyncPackets();
1487 }
1488
1489 static ucmd_t mvdcmds[] = {
1490 { "cmd", MVD_ForwardToServer_f },
1491 { "reconnect", MVD_Reconnect_f },
1492 { "precache", MVD_Precache_f },
1493
1494 { "connect", MVD_Connect_f },
1495 { "set", Cvar_Set_f },
1496 { "alias", Cmd_Alias_f },
1497
1498 { "changing", MVD_Changing_f },
1499 { "play", NULL },
1500 { "exec", NULL },
1501 { "wait", MVD_Wait_f },
1502
1503 { NULL, NULL }
1504 };
1505
MVD_ExecuteString(const char * line)1506 void MVD_ExecuteString( const char *line ) {
1507 char *cmd, *alias;
1508 ucmd_t *u;
1509
1510 if( !line[0] ) {
1511 return;
1512 }
1513
1514 Cmd_TokenizeString( line, qtrue );
1515
1516 cmd = Cmd_Argv( 0 );
1517 if( !cmd[0] ) {
1518 return;
1519 }
1520 for( u = mvdcmds; u->name; u++ ) {
1521 if( !strcmp( cmd, u->name ) ) {
1522 if( u->func ) {
1523 u->func();
1524 }
1525 return;
1526 }
1527 }
1528
1529 alias = Cmd_AliasCommand( cmd );
1530 if( alias ) {
1531 if( ++mvd_buffer.aliasCount == ALIAS_LOOP_COUNT ) {
1532 Com_WPrintf( "MVD_ExecuteString: runaway alias loop\n" );
1533 return;
1534 }
1535 Cbuf_InsertTextEx( &mvd_buffer, alias );
1536 return;
1537 }
1538
1539 if( Cvar_Command() ) {
1540 return;
1541 }
1542
1543 MVD_ClientCommand( Cmd_RawArgsFrom( 0 ) );
1544 }
1545
MVD_ParseStuffText(void)1546 static void MVD_ParseStuffText( void ) {
1547 char *string;
1548
1549 string = MSG_ReadString();
1550
1551 if( mvd.demoplayback ) {
1552 if( !strcmp( string, "precache\n" ) ) {
1553 MVD_Precache_f();
1554 }
1555 return;
1556 }
1557
1558 Com_DPrintf( "[MVD] stufftext: %s\n", string );
1559
1560 Cbuf_AddTextEx( &mvd_buffer, string );
1561 }
1562
1563 /* 'hard' reconnecting discards anything in delay buffer,
1564 * and starts buffering again from the beginning */
MVD_ParseReconnect(void)1565 static void MVD_ParseReconnect( void ) {
1566 netadr_t adr;
1567
1568 if( !mvd.netchan ) {
1569 SV_Nextserver();
1570 return;
1571 }
1572
1573 Com_Printf( "[MVD] Server disconnected, reconnecting...\n" );
1574
1575 adr = mvd.netchan->remote_address;
1576 SV_Shutdown( "MVD server restarted\n", KILL_RESTART );
1577
1578 mvd.state = MVD_CHALLENGING;
1579 mvd.connectTime = -9999;
1580 mvd.connectCount = 0;
1581 mvd.serverAddress = adr;
1582
1583 Cvar_SetInteger( "mvd_running", 1 );
1584 Cvar_SetInteger( "sv_running", ss_loading );
1585 }
1586
MVD_ParseMessage_r(void)1587 static void MVD_ParseMessage_r( void ) {
1588 int cmd;
1589
1590 if( mvd_shownet->integer == 1 ) {
1591 Com_Printf( "%i ", msg_read.cursize );
1592 } else if( mvd_shownet->integer > 1 ) {
1593 Com_Printf( "------------------\n" );
1594 }
1595
1596 //
1597 // parse the message
1598 //
1599 while( 1 ) {
1600 if( msg_read.readcount > msg_read.cursize ) {
1601 Com_Error( ERR_DROP, "MVD_ParseMessage: read past end of message" );
1602 }
1603
1604 if( ( cmd = MSG_ReadByte() ) == -1 ) {
1605 if( mvd_shownet->integer > 1 ) {
1606 Com_Printf( "%3i:END OF MESSAGE\n", msg_read.readcount - 1 );
1607 }
1608 break;
1609 }
1610
1611 if( mvd_shownet->integer > 1 ) {
1612 MVD_ShowSVC( cmd );
1613 }
1614
1615 switch( cmd ) {
1616 case svc_serverdata:
1617 MVD_ParseServerData();
1618 break;
1619 case svc_multicast:
1620 MVD_ParseMulticast();
1621 break;
1622 case svc_unicast:
1623 MVD_ParseUnicast();
1624 break;
1625 case svc_configstring:
1626 MVD_ParseConfigstring();
1627 break;
1628 case svc_spawnbaseline:
1629 MVD_ParseBaseline();
1630 break;
1631 case svc_frame:
1632 MVD_ParseFrame();
1633 break;
1634 case svc_stufftext:
1635 MVD_ParseStuffText();
1636 break;
1637 case svc_print:
1638 MVD_ParsePrint();
1639 break;
1640 case svc_zpacket:
1641 MSG_ParseZPacket( MVD_ParseMessage_r );
1642 break;
1643 case svc_reconnect:
1644 MVD_ParseReconnect();
1645 return;
1646 case svc_disconnect:
1647 Com_Error( ERR_DISCONNECT, "[MVD] Server disconnected" );
1648 break;
1649 default:
1650 Com_Error( ERR_DROP, "MVD_ParseMessage: illegible command: %d", cmd );
1651 break;
1652 }
1653 }
1654
1655 }
1656
1657 /*
1658 =====================================================================
1659
1660 DEFAULT PROTOCOL WORKAROUNDS
1661
1662 =====================================================================
1663 */
1664
1665 #define DEFAULT_PLAYER_NUMBER 0
1666
MVD_ParseDefaultFrame(int extrabits)1667 static void MVD_ParseDefaultFrame( int extrabits ) {
1668 uint32 bits, extraflags;
1669 int currentframe, deltaframe, delta, deltaPacketNum;
1670 mvdFrame_t *oldframe;
1671 playerStateEx_t *from, *to;
1672 int length;
1673
1674 if( mvd.state < MVD_PRIMED ) {
1675 Com_Error( ERR_DROP, "MVD_ParseDefaultFrame: server data not yet received" );
1676 }
1677
1678 if( parseFrame->serverFrame ) {
1679 Com_Error( ERR_DROP, "MVD_ParseDefaultFrame: duplicated frame in packet" );
1680 }
1681
1682 extraflags = 0;
1683 if( mvd.serverProtocol > PROTOCOL_VERSION_DEFAULT ) {
1684 bits = MSG_ReadLong();
1685
1686 currentframe = bits & FRAMENUM_MASK;
1687 delta = bits >> FRAMENUM_BITS;
1688
1689 if( delta == 31 ) {
1690 deltaframe = -1;
1691 } else {
1692 deltaframe = currentframe - delta;
1693 }
1694
1695 bits = MSG_ReadByte();
1696 extraflags = ( extrabits << 4 ) | ( bits >> SURPRESSCOUNT_BITS );
1697 } else {
1698 currentframe = MSG_ReadLong();
1699 deltaframe = MSG_ReadLong();
1700 if( mvd.serverProtocol != PROTOCOL_VERSION_OLD ) {
1701 MSG_ReadByte(); /* surpressCount */
1702 }
1703 }
1704
1705 mvd.packetNums[currentframe & UPDATE_MASK] = mvd.serverPacketNum;
1706
1707 parseFrame->serverFrame = currentframe;
1708 parseFrame->flags |= MFF_ACTIVE;
1709
1710 /* If the frame is delta compressed from data that we
1711 no longer have available, we must suck up the rest of
1712 the frame, but not use it, then ask for a non-compressed
1713 message
1714 */
1715 if( deltaframe > 0 ) {
1716 deltaPacketNum = mvd.packetNums[deltaframe & UPDATE_MASK];
1717 parseFrame->deltaPacketNum = deltaPacketNum;
1718
1719 oldframe = &mvd.frames[deltaPacketNum % mvd.frameBackup];
1720 from = &mvd.playerStates[oldframe->firstPlayerState % mvd.maxPlayerStates];
1721 if( deltaframe == currentframe ) {
1722 /* old buggy q2 servers still cause this on map change */
1723 Com_DPrintf( "Delta from current frame (should not happen).\n" );
1724 } else if( !( oldframe->flags & MFF_VALID ) ) {
1725 /* should never happen */
1726 Com_WPrintf( "Delta from invalid frame (should not happen).\n" );
1727 } else if( oldframe->serverPacketNum != deltaPacketNum ) {
1728 /* The frame that the server did the delta from
1729 is too old, so we can't reconstruct it properly.
1730 */
1731 Com_WPrintf( "Delta frame too old.\n" );
1732 } else if(
1733 mvd.nextEntityStates -
1734 oldframe->firstEntityState >
1735 mvd.maxEntityStates - MAX_EDICTS )
1736 {
1737 Com_WPrintf( "Delta entityStates too old.\n" );
1738 } else {
1739 parseFrame->flags |= MFF_VALID; /* valid delta parse */
1740 }
1741 } else {
1742 oldframe = NULL;
1743 from = NULL;
1744 mvd.demowaiting = qfalse;
1745 parseFrame->deltaPacketNum = -1;
1746 parseFrame->flags |= MFF_VALID; /* uncompressed frame */
1747 }
1748
1749 /* read areabits */
1750 length = MSG_ReadByte();
1751 if( length ) {
1752 if( ( unsigned )length > sizeof( parseFrame->portalbytes ) ) {
1753 Com_Error( ERR_DROP,
1754 "MVD_ParseDefaultFrame: invalid areabits length" );
1755 }
1756 if( msg_read.readcount + length > msg_read.cursize ) {
1757 Com_Error( ERR_DROP,
1758 "MVD_ParseDefaultFrame: read past end of message" );
1759 }
1760 MSG_ReadData( parseFrame->portalbytes, length );
1761 parseFrame->numPortalBytes = length;
1762 } else {
1763 memset( parseFrame->portalbytes, 255, sizeof( parseFrame->portalbytes ) );
1764 parseFrame->numPortalBytes = 0;
1765 }
1766
1767 if( mvd.serverProtocol <= PROTOCOL_VERSION_DEFAULT ) {
1768 if( MSG_ReadByte() != svc_playerinfo ) {
1769 Com_Error( ERR_DROP, "MVD_ParseDefaultFrame: not playerinfo" );
1770 }
1771 }
1772
1773 if( mvd_shownet->integer > 2 ) {
1774 Com_Printf( "%3i:playerinfo\n", msg_read.readcount - 1 );
1775 }
1776
1777 parseFrame->firstPlayerState = mvd.nextPlayerStates;
1778 to = &mvd.playerStates[mvd.nextPlayerStates % mvd.maxPlayerStates];
1779 mvd.nextPlayerStates++;
1780 parseFrame->numPlayerStates++;
1781
1782 /* parse playerstate */
1783 bits = MSG_ReadShort();
1784 if( mvd.serverProtocol > PROTOCOL_VERSION_DEFAULT ) {
1785 bits |= extraflags << PS_BITS; /* pass extra bits */
1786 if( mvd_shownet->integer > 2 ) {
1787 MSG_ShowDeltaPlayerstateBits_Enhanced( bits );
1788 Com_Printf( "\n" );
1789 }
1790 MSG_ParseDeltaPlayerstate_Enhanced( from, to, bits );
1791
1792 to->number = DEFAULT_PLAYER_NUMBER;
1793 if( mvd.serverProtocol != PROTOCOL_VERSION_Q2PRO ) {
1794 to->clientNum = mvd.clientNum;
1795 }
1796 } else {
1797 MSG_ParseDeltaPlayerstate_Default(
1798 ( player_state_t * )from,
1799 ( player_state_t * )to, bits );
1800 if( mvd_shownet->integer > 2 ) {
1801 MSG_ShowDeltaPlayerstateBits_Default( bits );
1802 Com_Printf( "\n" );
1803 }
1804 to->number = DEFAULT_PLAYER_NUMBER;
1805 to->clientNum = mvd.clientNum;
1806 }
1807
1808 /* parse packetentities */
1809 if( mvd.serverProtocol <= PROTOCOL_VERSION_DEFAULT ) {
1810 if( MSG_ReadByte() != svc_packetentities ) {
1811 Com_Error( ERR_DROP, "MVD_ParseDefaultFrame: not packetentities" );
1812 }
1813 }
1814
1815 if( mvd_shownet->integer > 2 ) {
1816 Com_Printf( "%3i:packetentities\n", msg_read.readcount - 1 );
1817 }
1818
1819 MVD_ParsePacketEntities( oldframe, parseFrame );
1820
1821 if( mvd_shownet->integer > 1 ) {
1822 Com_Printf( "%3i: frame:%i delta:%i\n",
1823 msg_read.readcount - 1, parseFrame->serverPacketNum,
1824 parseFrame->deltaPacketNum );
1825 }
1826
1827 if( !( parseFrame->flags & MFF_VALID ) ) {
1828 return; /* do not change anything */
1829 }
1830
1831 if( mvd.validPacketNum == -1 ) {
1832 MVD_SpawnClients();
1833 }
1834 mvd.validPacketNum = mvd.serverPacketNum;
1835 mvd.lastServerFrame = currentframe;
1836
1837 if( mvd.state < MVD_BUFFERING ) {
1838 mvd.state = MVD_BUFFERING;
1839 Com_DPrintf( "Started buffering at frame %d\n", mvd.serverPacketNum );
1840 mvd.activePacketNum = mvd.serverPacketNum;
1841 }
1842
1843 oldframe = &mvd.frames[( mvd.serverPacketNum - 1 ) % mvd.frameBackup];
1844 MVD_FixEntityStates( oldframe, parseFrame );
1845 }
1846
MVD_WriteDefaultMulticast(byte * data,int length,multicast_t type)1847 static void MVD_WriteDefaultMulticast( byte *data, int length, multicast_t type ) {
1848 int size;
1849 client_t *client;
1850 mvdClient_t *mvdcl;
1851
1852 size = ( type << 12 ) | ( length & 0xFFF );
1853 MSG_WriteByte( svc_multicast );
1854 MSG_WriteShort( size );
1855
1856 if( type >= MULTICAST_ALL_R ) {
1857 MVD_WriteFrameReliableDatagram( msg_write.data, msg_write.cursize );
1858 MVD_WriteFrameReliableDatagram( data, length );
1859 } else {
1860 MVD_WriteFrameDatagram( msg_write.data, msg_write.cursize );
1861 MVD_WriteFrameDatagram( data, length );
1862 }
1863
1864 SZ_Clear( &msg_write );
1865
1866 /* add this stuff immediately for camera people */
1867 FOR_EACH_CLIENT( client ) {
1868 if( client->state < cs_spawned ) {
1869 continue;
1870 }
1871 mvdcl = ( mvdClient_t * )client->edict->client;
1872 if( !mvdcl->admin ) {
1873 continue;
1874 }
1875 client->AddMessage( client, data, length,
1876 type >= MULTICAST_ALL_R ? qtrue : qfalse );
1877 }
1878 }
1879
MVD_WriteDefaultUnicast(byte * data,int length)1880 static void MVD_WriteDefaultUnicast( byte *data, int length ) {
1881 int clientNum;
1882 client_t *client;
1883 mvdClient_t *mvdcl;
1884
1885 clientNum = ( qtrue << 7 ) | DEFAULT_PLAYER_NUMBER;
1886
1887 MSG_WriteByte( svc_unicast );
1888 MSG_WriteByte( clientNum );
1889 MSG_WriteShort( length );
1890
1891 MVD_WriteFrameReliableDatagram( msg_write.data, msg_write.cursize );
1892 MVD_WriteFrameReliableDatagram( data, length );
1893
1894 SZ_Clear( &msg_write );
1895
1896 /* add this stuff immediately for camera people */
1897 FOR_EACH_CLIENT( client ) {
1898 if( client->state < cs_connected ) {
1899 continue;
1900 }
1901 mvdcl = ( mvdClient_t * )client->edict->client;
1902 if( !mvdcl->admin ) {
1903 continue;
1904 }
1905 client->AddMessage( client, data, length, qtrue );
1906 }
1907 }
1908
MVD_ParseDefaultPrint(void)1909 static void MVD_ParseDefaultPrint( void ) {
1910 int length;
1911 byte *data;
1912 char *string;
1913
1914 data = msg_read.data + msg_read.readcount - 1;
1915 length = msg_read.readcount;
1916 MSG_ReadByte();
1917 string = MSG_ReadString();
1918 length = msg_read.readcount - length + 1;
1919
1920 if( mvd.state < MVD_PRIMED ) {
1921 Com_Printf( "[MVD] %s", string );
1922 return;
1923 }
1924
1925 /* FIXME: broadcast all prints */
1926 MVD_WriteDefaultMulticast( data, length, MULTICAST_ALL_R );
1927 }
1928
MVD_ParseString(void)1929 static void MVD_ParseString( void ) {
1930 int length;
1931 byte *data;
1932
1933 data = msg_read.data + msg_read.readcount - 1;
1934 length = msg_read.readcount;
1935 MSG_ReadString();
1936 length = msg_read.readcount - length + 1;
1937
1938 if( *data == svc_layout ) {
1939 mvd.lastLayoutPacket = mvd.serverPacketNum;
1940 }
1941
1942 MVD_WriteDefaultUnicast( data, length );
1943 }
1944
MVD_ParseTempEntity(void)1945 static void MVD_ParseTempEntity( void ) {
1946 byte *data;
1947 int length;
1948
1949 data = msg_read.data + msg_read.readcount - 1;
1950 if( mvd_shownet->integer > 2 ) {
1951 Com_Printf( " type %d\n", data[1] );
1952 }
1953 switch( data[1] ) {
1954 case TE_BLOOD:
1955 case TE_GUNSHOT:
1956 case TE_SPARKS:
1957 case TE_BULLET_SPARKS:
1958 case TE_SCREEN_SPARKS:
1959 case TE_SHIELD_SPARKS:
1960 case TE_SHOTGUN:
1961 case TE_BLASTER:
1962 case TE_GREENBLOOD:
1963 case TE_BLASTER2:
1964 case TE_FLECHETTE:
1965 case TE_HEATBEAM_SPARKS:
1966 case TE_HEATBEAM_STEAM:
1967 case TE_ELECTRIC_SPARKS:
1968 case TE_MOREBLOOD:
1969 length = 7;
1970 break;
1971
1972 case TE_SPLASH:
1973 case TE_LASER_SPARKS:
1974 case TE_WELDING_SPARKS:
1975 case TE_TUNNEL_SPARKS:
1976 length = 9;
1977 break;
1978
1979 case TE_BLUEHYPERBLASTER:
1980 case TE_RAILTRAIL:
1981 case TE_BFG_LASER:
1982 case TE_BUBBLETRAIL:
1983 case TE_DEBUGTRAIL:
1984 case TE_BUBBLETRAIL2:
1985 length = 12;
1986 break;
1987
1988 case TE_EXPLOSION2:
1989 case TE_GRENADE_EXPLOSION:
1990 case TE_GRENADE_EXPLOSION_WATER:
1991 case TE_PLASMA_EXPLOSION:
1992 case TE_EXPLOSION1:
1993 case TE_EXPLOSION1_BIG:
1994 case TE_ROCKET_EXPLOSION:
1995 case TE_ROCKET_EXPLOSION_WATER:
1996 case TE_EXPLOSION1_NP:
1997 case TE_BFG_EXPLOSION:
1998 case TE_BFG_BIGEXPLOSION:
1999 case TE_BOSSTPORT:
2000 case TE_PLAIN_EXPLOSION:
2001 case TE_CHAINFIST_SMOKE:
2002 case TE_TRACKER_EXPLOSION:
2003 case TE_TELEPORT_EFFECT:
2004 case TE_DBALL_GOAL:
2005 case TE_WIDOWSPLASH:
2006 case TE_NUKEBLAST:
2007 length = 6;
2008 break;
2009
2010 case TE_PARASITE_ATTACK:
2011 case TE_MEDIC_CABLE_ATTACK:
2012 case TE_HEATBEAM:
2013 case TE_MONSTER_HEATBEAM:
2014 length = 14;
2015 break;
2016
2017 case TE_GRAPPLE_CABLE:
2018 length = 20;
2019 break;
2020
2021 case TE_LIGHTNING:
2022 length = 16;
2023 break;
2024
2025 case TE_FLASHLIGHT:
2026 case TE_WIDOWBEAMOUT:
2027 length = 8;
2028 break;
2029
2030 case TE_FORCEWALL:
2031 length = 13;
2032 break;
2033
2034 case TE_STEAM:
2035 length = 14;
2036 if( data[2] != 0xff && data[3] != 0xff ) {
2037 length += 4;
2038 }
2039 break;
2040
2041 default:
2042 Com_Error( ERR_DROP, "MVD_ParseTempEntity: bad entity type" );
2043 length = 0;
2044 break;
2045 }
2046
2047 length++;
2048 msg_read.readcount += length;
2049 if( msg_read.readcount > msg_read.cursize ) {
2050 Com_Error( ERR_DROP, "MVD_ParseTempEntity: read past end of message" );
2051 }
2052
2053 MVD_WriteDefaultMulticast( data, length + 1, MULTICAST_ALL );
2054 }
2055
MVD_ParseMuzzleFlash(void)2056 static void MVD_ParseMuzzleFlash( void ) {
2057 byte *data;
2058
2059 data = msg_read.data + msg_read.readcount - 1;
2060 msg_read.readcount += 3;
2061 if( msg_read.readcount > msg_read.cursize ) {
2062 Com_Error( ERR_DROP, "MVD_ParseMuzzleFlash: read past end of message" );
2063 }
2064
2065 MVD_WriteDefaultMulticast( data, 4, MULTICAST_ALL );
2066
2067 }
2068
MVD_ParseStartSound(void)2069 static void MVD_ParseStartSound( void ) {
2070 int flags, length;
2071 byte *data;
2072
2073 data = msg_read.data + msg_read.readcount - 1;
2074 flags = data[1];
2075
2076 length = 2;
2077 if( flags & SND_VOLUME ) {
2078 length++;
2079 }
2080 if( flags & SND_ATTENUATION ) {
2081 length++;
2082 }
2083 if( flags & SND_OFFSET ) {
2084 length++;
2085 }
2086 if( flags & SND_ENT ) {
2087 length += 2;
2088 }
2089 if( flags & SND_POS ) {
2090 length += 6;
2091 }
2092
2093 msg_read.readcount += length;
2094 if( msg_read.readcount > msg_read.cursize ) {
2095 Com_Error( ERR_DROP, "MVD_ParseStartSound: read past end of message" );
2096 }
2097
2098 MVD_WriteDefaultMulticast( data, length + 1, MULTICAST_ALL );
2099 }
2100
MVD_ParseInventory(void)2101 static void MVD_ParseInventory( void ) {
2102 byte *data;
2103
2104 data = msg_read.data + msg_read.readcount - 1;
2105
2106 msg_read.readcount += MAX_ITEMS*2;
2107 if( msg_read.readcount > msg_read.cursize ) {
2108 Com_Error( ERR_DROP, "MVD_ParseInventory: read past end of message" );
2109 }
2110
2111 MVD_WriteDefaultUnicast( data, MAX_ITEMS*2 + 1 );
2112 }
2113
2114
MVD_ParseDefaultMessage_r(void)2115 static void MVD_ParseDefaultMessage_r( void ) {
2116 int cmd;
2117 int extrabits;
2118
2119 if( mvd_shownet->integer == 1 ) {
2120 Com_Printf( "%i ", msg_read.cursize );
2121 } else if( mvd_shownet->integer > 1 ) {
2122 Com_Printf( "------------------\n" );
2123 }
2124
2125 //
2126 // parse the message
2127 //
2128 while( 1 ) {
2129 if( msg_read.readcount > msg_read.cursize ) {
2130 Com_Error( ERR_DROP, "MVD_ParseDefaultMessage: read past end of message" );
2131 }
2132
2133 if( ( cmd = MSG_ReadByte() ) == -1 ) {
2134 if( mvd_shownet->integer > 1 ) {
2135 Com_Printf( "%3i:END OF MESSAGE\n", msg_read.readcount - 1 );
2136 }
2137 break;
2138 }
2139
2140 extrabits = cmd >> SVCMD_BITS;
2141 cmd &= SVCMD_MASK;
2142
2143 if( mvd_shownet->integer > 1 ) {
2144 MVD_ShowSVC( cmd );
2145 }
2146
2147 switch( cmd ) {
2148 case svc_serverdata:
2149 MVD_ParseServerData();
2150 break;
2151 case svc_configstring:
2152 MVD_ParseConfigstring();
2153 break;
2154 case svc_spawnbaseline:
2155 MVD_ParseBaseline();
2156 break;
2157 case svc_frame:
2158 MVD_ParseDefaultFrame( extrabits );
2159 break;
2160 case svc_stufftext:
2161 MVD_ParseStuffText();
2162 break;
2163 case svc_print:
2164 MVD_ParseDefaultPrint();
2165 break;
2166 case svc_centerprint:
2167 case svc_layout:
2168 MVD_ParseString();
2169 break;
2170 case svc_sound:
2171 MVD_ParseStartSound();
2172 break;
2173 case svc_temp_entity:
2174 MVD_ParseTempEntity();
2175 break;
2176 case svc_muzzleflash:
2177 case svc_muzzleflash2:
2178 MVD_ParseMuzzleFlash();
2179 break;
2180 case svc_download:
2181 Com_Error( ERR_DROP, "MVD_ParseDefaultMessage: server sending download" );
2182 break;
2183 case svc_inventory:
2184 MVD_ParseInventory();
2185 break;
2186 case svc_zpacket:
2187 MSG_ParseZPacket( MVD_ParseDefaultMessage_r );
2188 break;
2189 case svc_reconnect:
2190 MVD_ParseReconnect();
2191 return;
2192 case svc_disconnect:
2193 Com_Error( ERR_DISCONNECT, "[MVD] Server disconnected" );
2194 break;
2195 default:
2196 Com_Error( ERR_DROP, "MVD_ParseDefaultMessage: illegible command: %d", cmd );
2197 break;
2198 }
2199 }
2200
2201 }
2202
2203 /*
2204 =====================================================================
2205
2206 ...
2207
2208 =====================================================================
2209 */
2210
MVD_ParseMessage(void)2211 void MVD_ParseMessage( void ) {
2212 /* each packet has a 'frame' associated with it,
2213 * even if there is no svc_frame within. */
2214 if( mvd.state < MVD_PRIMED ) {
2215 parseFrame = NULL;
2216 parseGS = NULL;
2217 } else {
2218 parseFrame = &mvd.frames[mvd.serverPacketNum % mvd.frameBackup];
2219 memset( parseFrame, 0, sizeof( *parseFrame ) );
2220 parseFrame->firstMessageByte = mvd.nextMessageBytes;
2221 parseFrame->numMessageBytes = 0;
2222 parseFrame->firstReliableMessageByte = mvd.nextReliableMessageBytes;
2223 parseFrame->numReliableMessageBytes = 0;
2224 parseFrame->gamestateSequence = mvd.gamestateSequence;
2225 parseFrame->serverPacketNum = mvd.serverPacketNum;
2226 parseGS = &mvd.gamestates[mvd.gamestateSequence & GAMESTATE_MASK];
2227 }
2228
2229 if( mvd.serverProtocol == PROTOCOL_VERSION_MVD ) {
2230 MVD_ParseMessage_r();
2231 } else {
2232 MVD_ParseDefaultMessage_r();
2233 }
2234
2235 if( !mvd.demoplayback &&
2236 mvd.state > MVD_PRIMED &&
2237 mvd_autoscores->string[0] &&
2238 mvd.serverPacketNum - mvd.lastLayoutPacket > LAYOUT_TIMEOUT )
2239 {
2240 MVD_ClientCommand( mvd_autoscores->string );
2241 mvd.lastLayoutPacket = mvd.serverPacketNum;
2242
2243 }
2244 }
2245
MVD_ReadNextMessage(fileHandle_t f)2246 qboolean MVD_ReadNextMessage( fileHandle_t f ) {
2247 int msglen;
2248
2249 // read msglen
2250 if( FS_Read( &msglen, 4, f ) != 4 ) {
2251 return qfalse;
2252 }
2253
2254 if( msglen == -1 ) {
2255 return qfalse;
2256 }
2257
2258 msglen = LittleLong( msglen );
2259 if( ( unsigned )msglen >= msg_read.maxsize ) {
2260 Com_EPrintf( "MVD_ReadNextMessage: bad msglen: %d\n", msglen );
2261 return qfalse;
2262 }
2263
2264 msg_read.cursize = msglen;
2265 msg_read.readcount = 0;
2266
2267 // read packet data
2268 if( FS_Read( msg_read.data, msglen, f ) != msglen ) {
2269 return qfalse;
2270 }
2271
2272 return qtrue;
2273 }
2274
MVD_ParseNextMessage(void)2275 qboolean MVD_ParseNextMessage( void ) {
2276 int pos;
2277
2278 if( !MVD_ReadNextMessage( mvd.demofile ) ) {
2279 return qfalse;
2280 }
2281
2282 mvd.serverPacketNum++;
2283 MVD_ParseMessage();
2284
2285 if( mvd.demofileSize ) {
2286 pos = FS_Tell( mvd.demofile ) - mvd.demofileFrameOffset;
2287 if( pos < 0 ) {
2288 pos = 0;
2289 }
2290 mvd.demofilePercent = pos * 100 / mvd.demofileSize;
2291 }
2292
2293 return qtrue;
2294 }
2295
2296
2297
2298