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