1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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     $Id$
20 */
21 // cl_parse.c  -- parse a message received from the server
22 
23 #include "defs.h"
24 
25 char *svc_strings[] =
26 	{
27 		"svc_bad",
28 		"svc_nop",
29 		"svc_disconnect",
30 		"svc_updatestat",
31 		"svc_version",		// [long] server version
32 		"svc_setview",		// [short] entity number
33 		"svc_sound",		// <see code>
34 		"svc_time",		// [float] server time
35 		"svc_print",		// [string] null terminated string
36 		"svc_stufftext",	// [string] stuffed into client's console buffer
37 		// the string should be \n terminated
38 		"svc_setangle",		// [vec3] set the view angle to this absolute value
39 
40 		"svc_serverdata",	// [long] version ...
41 		"svc_lightstyle",	// [byte] [string]
42 		"svc_updatename",	// [byte] [string]
43 		"svc_updatefrags",	// [byte] [short]
44 		"svc_clientdata",	// <shortbits + data>
45 		"svc_stopsound",	// <see code>
46 		"svc_updatecolors",	// [byte] [byte]
47 		"svc_particle",		// [vec3] <variable>
48 		"svc_damage",		// [byte] impact [byte] blood [vec3] from
49 
50 		"svc_spawnstatic",
51 		"OBSOLETE svc_spawnbinary",
52 		"svc_spawnbaseline",
53 
54 		"svc_temp_entity",	// <variable>
55 		"svc_setpause",
56 		"svc_signonnum",
57 		"svc_centerprint",
58 		"svc_killedmonster",
59 		"svc_foundsecret",
60 		"svc_spawnstaticsound",
61 		"svc_intermission",
62 		"svc_finale",
63 
64 		"svc_cdtrack",
65 		"svc_sellscreen",
66 
67 		"svc_smallkick",
68 		"svc_bigkick",
69 
70 		"svc_updateping",
71 		"svc_updateentertime",
72 
73 		"svc_updatestatlong",
74 		"svc_muzzleflash",
75 		"svc_updateuserinfo",
76 		"svc_download",
77 		"svc_playerinfo",
78 		"svc_nails",
79 		"svc_choke",
80 		"svc_modellist",
81 		"svc_soundlist",
82 		"svc_packetentities",
83 		"svc_deltapacketentities",
84 		"svc_maxspeed",
85 		"svc_entgravity",
86 
87 		"svc_setinfo",
88 		"svc_serverinfo",
89 		"svc_updatepl",
90 		"svc_nails2",
91 		"NEW PROTOCOL",
92 		"NEW PROTOCOL",
93 		"NEW PROTOCOL",
94 		"NEW PROTOCOL",
95 		"NEW PROTOCOL",
96 		"NEW PROTOCOL",
97 		"NEW PROTOCOL",
98 		"NEW PROTOCOL",
99 		"NEW PROTOCOL",
100 		"NEW PROTOCOL",
101 		"NEW PROTOCOL",
102 		"NEW PROTOCOL"
103     };
104 
105 #define	svc_qizmomsg	83		// qizmo voice message
106 
107 int	parsecountmod;
108 double	parsecounttime;
109 
110 int	cl_spikeindex, cl_playerindex, cl_flagindex;
111 int	cl_telemin = 9999, cl_telemax = 0;
112 
113 int	cl_num_projectiles;
114 projectile_t cl_projectiles[MAX_PROJECTILES];
115 
116 //=============================================================================
117 
118 int msg_startcount;
119 //double parsecounttime;
120 
To(void)121 int To(void)
122 {
123 	if (!from->spectator)
124 		return from->to;
125 
126 	if (from->spec_track == -1)
127 		return from->to;
128 
129 	return from->spec_track;
130 }
131 
132 
133 /*
134 =====================
135 Dem_ParseDownload
136 
137 A download message has been received from the server
138 =====================
139 */
Dem_ParseDownload(void)140 void Dem_ParseDownload (void)
141 {
142 	int size, percent;
143 
144 	msg_startcount = msg_readcount;
145 	// read the data
146 	size = MSG_ReadShort ();
147 	percent = MSG_ReadByte ();
148 
149 	if (size > 0)
150 		msg_readcount += size;
151 
152 	MVDWrite_Begin(from->type, from->to, msg_readcount - msg_startcount + 1);
153 	MSG_WriteByte(msgbuf,svc_download);
154 	MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
155 }
156 
157 /*
158 =====================================================================
159 
160   SERVER CONNECTING MESSAGES
161 
162 =====================================================================
163 */
164 
165 /*
166 ==================
167 Dem_ParseServerData
168 ==================
169 */
Dem_ParseServerData(void)170 void Dem_ParseServerData (void)
171 {
172 	char	str[1024];  // gamedir
173 	char    str2[1024]; // full level name, may be pretty long
174 	int	protover, count;
175 
176 	count = 0;
177 
178 	// parse protocol version number
179 	// allow 2.2 and 2.29 demos to play
180 	for (;;) {
181 		protover = MSG_ReadLong();
182 		count += 4;
183 		if (protover == PROTOCOL_VERSION_FTE) {
184 			from->extensions_fte1 = MSG_ReadLong();
185 			count += 4;
186 			continue;
187 		}
188 		if (protover == PROTOCOL_VERSION_FTE2) {
189 			from->extensions_fte2 = MSG_ReadLong();
190 			count += 4;
191 			continue;
192 		}
193 		if (protover == PROTOCOL_VERSION_MVD1) {
194 			from->extensions_mvd1 = MSG_ReadLong();
195 			count += 4;
196 			continue;
197 		}
198 
199 		if (protover != PROTOCOL_VERSION && !(protover == 26 || protover == 27 || protover == 28)) {
200 			Sys_Printf("Incompatible demo version: %i\n", protover);
201 			Dem_Stop(from);
202 			return;
203 		}
204 		break;
205 	}
206 
207 	from->servercount = MSG_ReadLong ();
208 	count += 4;
209 
210 	// game directory
211 	strlcpy(str, MSG_ReadString(), sizeof(str));
212 	count += strlen(str)+1;
213 
214 	if (from->format == mvd)
215 	{
216 		//world.time = world.frames[0].time = from->time = realtime = demo.time = from->lastframe = MSG_ReadFloat();
217 		from->basetime = from->worldtime = from->time = from->lastframe = MSG_ReadFloat();
218 		from->worldtime += from->sync;
219 		from->playernum = 31;
220 	}
221 	else
222 	{
223 		// parse player slot, high bit means spectator
224 		from->playernum = MSG_ReadByte ();
225 		from->spectator = false;
226 		if (from->playernum & 128)
227 		{
228 			from->playernum &= ~128;
229 			from->spectator = true;
230 		}
231 		from->type = dem_single;
232 		from->to = from->playernum;
233 		//world.time = world.frames[0].time = demo.time = from->lastframe;
234 		from->worldtime = from->time = from->lastframe;
235 		from->worldtime += from->sync;
236 	}
237 
238 	count += 4;
239 
240 	// get the full level name
241 	strlcpy(str2,MSG_ReadString (), sizeof(str2));
242 	count += strlen(str2)+1;
243 
244 	MVDWrite_Begin(dem_all, 0, count + 40+1);
245 	MSG_WriteByte(msgbuf, svc_serverdata);
246 	if (from->extensions_fte1) {
247 		MSG_WriteLong(msgbuf, PROTOCOL_VERSION_FTE);
248 		MSG_WriteLong(msgbuf, from->extensions_fte1);
249 	}
250 	if (from->extensions_fte2) {
251 		MSG_WriteLong(msgbuf, PROTOCOL_VERSION_FTE2);
252 		MSG_WriteLong(msgbuf, from->extensions_fte2);
253 	}
254 	if (from->extensions_mvd1) {
255 		MSG_WriteLong(msgbuf, PROTOCOL_VERSION_MVD1);
256 		MSG_WriteLong(msgbuf, from->extensions_mvd1 & MVD_PEXT1_INCLUDEINMVD);
257 	}
258 	MSG_WriteLong(msgbuf, protover);
259 	MSG_WriteLong(msgbuf, from->servercount);
260 	MSG_WriteString(msgbuf, str);
261 	MSG_WriteFloat(msgbuf, from->time + from->sync);
262 	MSG_WriteString(msgbuf, str2);
263 	MSG_Forward(msgbuf, msg_readcount, 40);
264 
265 	// check if marging is possible
266 	if (sworld.options & O_QWDSYNC)
267 		return;
268 
269 	if (from == sources)
270 	{
271 		world.servercount = from->servercount;
272 		strlcpy(world.mapname, str2, sizeof(world.mapname));
273 	}
274 	else
275 	{
276 		if (from->servercount != world.servercount || strcmp(world.mapname, str2))
277 		{
278 			Sys_Printf("Warning: demo %s comes from different game\n", sworld.from[from - sources].name);
279 			//Dem_Stop(from);
280 		}
281 	}
282 }
283 
284 /*
285 ==================
286 Dem_Parselist
287 ==================
288 */
Dem_Parselist(byte type)289 void Dem_Parselist (byte type)
290 {
291 	char *str;
292 	int n;
293 
294 	msg_startcount = msg_readcount;
295 	n = MSG_ReadByte();
296 
297 	for (;;)
298 	{
299 		str = MSG_ReadString ();
300 		if (!str[0])
301 			break;
302 		n++;
303 		if (!strcmp(str,"progs/spike.mdl"))
304 			cl_spikeindex = n;
305 		if (!strcmp(str,"progs/player.mdl"))
306 			cl_playerindex = n;
307 		if (!strcmp(str,"progs/flag.mdl"))
308 			cl_flagindex = n;
309 		if (!strncmp(str,"misc/r_tele",11))
310 		{
311 			if (n < cl_telemin)
312 				cl_telemin = n;
313 			if (n > cl_telemax)
314 				cl_telemax = n;
315 		}
316 	}
317 
318 	n = MSG_ReadByte();
319 
320 	MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
321 	MSG_WriteByte(msgbuf, type);
322 	MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
323 }
324 
325 
326 /*
327 =====================================================================
328 
329 ACTION MESSAGES
330 
331 =====================================================================
332 */
333 
334 /*
335 ==================
336 Dem_ParseStartSoundPacket
337 ==================
338 */
Dem_ParseStartSoundPacket(void)339 void Dem_ParseStartSoundPacket(void)
340 {
341 	int		channel, sound_num, i, j, k;
342 	vec3_t	pos, dist;
343 	qbool found = false;
344 
345 	msg_startcount = msg_readcount;
346 	channel = MSG_ReadShort();
347 
348 	if (channel & SND_VOLUME)
349 		MSG_ReadByte();
350 	if (channel & SND_ATTENUATION)
351 		MSG_ReadByte();
352 
353 	sound_num = MSG_ReadByte();
354 
355 	for (i=0 ; i<3 ; i++)
356 		pos[i] = MSG_ReadCoord ();
357 
358 	if (cl_telemax && sound_num >= cl_telemin && sound_num <= cl_telemax)
359 	{
360 		j = from->parsecount;
361 		k = world.parsecount;
362 		do
363 		{
364 			if (from->frames[j&UPDATE_MASK].time < world.frames[k&UPDATE_MASK].time)
365 				k = k == 0 ? 0 : k - 1;
366 
367 			for (i = 0; i < MAX_CLIENTS; i++)
368 			{
369 				if (!from->players[i].name[0])
370 					continue;
371 				if (from->players[i].spectator)
372 					continue;
373 
374 				//Sys_Printf("%d sound:%d\n", i, sound_num);
375 				VectorSubtract(pos, from->frames[j&UPDATE_MASK].playerstate[i].origin, dist);
376 				//Sys_Printf("%d:dist:%f\n", i, dist);
377 				if (VectorLength(dist) < 30.0 && world.frames[k&UPDATE_MASK].fixangle[i] == false)
378 				{
379 					found = true;
380 					world.frames[k&UPDATE_MASK].fixangle[i] = true;
381 					if (sworld.options & O_DEBUG)
382 						fprintf(sworld.debug.file, "fixangle:%d, %d\n", i, k);
383 				}
384 			}
385 			j--;
386 		}
387 		while (!found && j >= from->parsecount && j >= 0);
388 	}
389 
390 	MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
391 	MSG_WriteByte(msgbuf, svc_sound);
392 	MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
393 }
394 
395 
396 /*
397 ==================
398 Dem_ParseClientdata
399 
400 Server information pertaining to this client only, sent every frame
401 ==================
402 */
403 
Dem_ParseClientdata(void)404 void Dem_ParseClientdata (void)
405 {
406 	int			i;
407 	frame_t		*frame;
408 	float		latency;
409 
410 	// calculate simulated time of message
411 
412 	i = from->netchan.incoming_acknowledged;
413 	from->parsecount = i;
414 	i &= UPDATE_MASK;
415 	from->parsecountmod = i;
416 	frame = &from->frames[i];
417 	if (from->format == qwd)
418 		parsecounttime = from->frames[i].senttime + from->sync;
419 	else
420 	{
421 		from->frames[i].senttime = from->time + from->sync;
422 		parsecounttime = from->time  + from->sync;
423 	}
424 
425 	frame->receivedtime = from->time + from->sync;
426 
427 	// calculate latency
428 	latency = frame->receivedtime - frame->senttime;
429 
430 	if (latency < 0 || latency > 1.0)
431 	{
432 		//		Con_Printf ("Odd latency: %5.2f\n", latency);
433 	}
434 	else
435 	{
436 		// drift the average latency towards the observed latency
437 		if (latency <= from->latency)
438 			from->latency = latency;
439 		else
440 			from->latency += 0.001f;
441 
442 		//Sys_Printf("%f %f\n", latency, from->latency);
443 	}
444 
445 	//world.time = frame->senttime + from->latency;
446 	//from->latency = latency;
447 	frame->latency = from->latency;
448 	from->worldtime = frame->receivedtime - from->latency;
449 	frame->time = frame->receivedtime - from->latency;
450 
451 }
452 
453 
454 /*
455 ====================
456 CleanName_Init
457 
458 sets chararcter table to translate quake texts to more friendly texts
459 ====================
460 */
461 
462 char chartbl[256];
463 
CleanName_Init()464 void CleanName_Init ()
465 {
466 	int i;
467 
468 	for (i = 0; i < 256; i++)
469 		chartbl[i] = (i&127) < 32 ? ' ' : i&127;
470 
471 	chartbl[13] = 13;
472 	chartbl[10] = 10;
473 	// special cases
474 
475 	// numbers
476 	for (i = 18; i < 28; i++)
477 		chartbl[i] = chartbl[i + 128] = i + 30;
478 
479 	// brackets
480 	chartbl[29] = chartbl[29 + 128] = chartbl[128] = '(';
481 	chartbl[31] = chartbl[31 + 128] = chartbl[130] = ')';
482 	chartbl[16] = chartbl[16 + 128]= '[';
483 	chartbl[17] = chartbl[17 + 128] = ']';
484 
485 	// hash
486 	for (i = 1; i < 5; i++)
487 		chartbl[i] = chartbl[i + 128] = '#';
488 	for (i = 6; i < 10; i++)
489 		chartbl[i] = chartbl[i + 128] = '#';
490 
491 	chartbl[11] = chartbl[11 + 128] = '#';
492 
493 	// dot
494 	chartbl[5] = chartbl[14] = chartbl[15] = chartbl[28] = chartbl[46] = '.';
495 	chartbl[5 + 128] = chartbl[14 + 128] = chartbl[15 + 128] = chartbl[28 + 128] = chartbl[46 + 128] = '.';
496 
497 	// left arrow
498 	chartbl[127] = '>';
499 
500 	// right arrow
501 	chartbl[141] = '<';
502 
503 	// '='
504 	chartbl[30] = chartbl[129] = chartbl[30 + 128] = '=';
505 
506 	// whitespaces
507 	chartbl[12] = chartbl[12 + 128] = chartbl[138] = ' ';
508 
509 	chartbl[33] = chartbl[33 + 128]= '!';
510 }
511 
CleanName(unsigned char * name)512 char *CleanName (unsigned char *name)
513 {
514 	char *out;
515 	static char text[2048];
516 
517 	out = text;
518 
519 	while (*name)
520 		*out++ = chartbl[*name++];
521 
522 	*out = 0;
523 
524 	return text;
525 }
526 
findPlayer(char * name)527 qbool findPlayer(char *name)
528 {
529 	int i;
530 
531 	if (!*name)
532 		return false;
533 
534 	for (i=0; i < MAX_CLIENTS; i++)
535 		if (!strcmp(name, world.players[i].name))
536 			return true;
537 	return false;
538 }
539 
540 /*
541 ==============
542 Dem_ParsePrint
543 ==============
544 */
545 
Dem_ParsePrint(void)546 void Dem_ParsePrint (void)
547 {
548 	char	*s, str[128];
549 	byte	level;
550 	byte	desttype = dem_all;
551 	int	destto = 0;
552 	static	char logbuf[2048] = "";
553 
554 	msg_startcount = msg_readcount;
555 
556 	level = MSG_ReadByte ();
557 	s = MSG_ReadString ();
558 
559 	// filters
560 
561 	if (level < sworld.msglevel)
562 		return;
563 
564 	if (level < PRINT_CHAT && from->format == qwd)
565 	{
566 		desttype = from->type;
567 		destto = from->to;
568 	}
569 
570 
571 	if (sworld.options & O_FC && level == PRINT_CHAT)
572 		return;
573 	if (sworld.options & O_FS && level == PRINT_CHAT && !strncmp(s, "[SPEC] ", 7))
574 		return;
575 	if (sworld.options & O_FQ && level == PRINT_CHAT && s[0] == '[' && strstr(s, "]: ") != NULL)
576 		return;
577 	if (level == PRINT_CHAT && s[0] == '(' && strstr(s, "): ") != NULL)
578 	{
579 		strlcpy(str, s + 1, sizeof(str));
580 		*(str + ((strstr(s, "): ") - s))) = 0;
581 		if (findPlayer(str))
582 		{
583 			if (sworld.options & O_FT)
584 				return;
585 			if (from->format == qwd)
586 			{
587 				desttype = from->type;
588 				destto = from->to;
589 			}
590 		}
591 	}
592 
593 	if (sworld.options & O_LOG)
594 	{
595 		strlcat(logbuf, CleanName((unsigned char *) s), sizeof(logbuf)); //FIXME
596 		if (logbuf[strlen(logbuf)-1] == '\n')
597 		{
598 			char *p = logbuf;
599 
600 			// add 7 whitespaces after every \n character to make log looks nice:)
601 			while ((p = strstr(p, "\n")) != NULL && p[1])
602 			{
603 				memmove(p+8, p + 1, strlen(p));
604 				memcpy(p+1, "       ", 7);
605 				p++;
606 			}
607 			fprintf(sworld.log.file, "%2d:%.2d> %s", (int)(world.time/60), (int) world.time % 60, logbuf);
608 			logbuf[0] = 0;
609 		}
610 	}
611 
612 	if (from->format == mvd)
613 	{
614 		desttype = from->type;
615 		destto = from->to;
616 	}
617 
618 	MVDWrite_Begin(desttype, destto, msg_readcount - msg_startcount + 1);
619 	MSG_WriteByte(msgbuf, svc_print);
620 	MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
621 }
622 
623 /*
624 ==============
625 Dem_UpdateUserinfo
626 ==============
627 */
628 
Dem_UpdateUserinfo(void)629 void Dem_UpdateUserinfo (void)
630 {
631 	int slot;
632 	player_info_t *player;
633 
634 	msg_startcount = msg_readcount;
635 
636 	slot = MSG_ReadByte ();
637 	if (slot >= MAX_CLIENTS)
638 	{
639 		Sys_Printf ("ERROR: Dem_ParseDemoMessage: svc_updateuserinfo > MAX_CLIENTS\n");
640 		Dem_Stop(from);
641 		return;
642 	}
643 
644 	player = &from->players[slot];
645 	/*player->userid = */MSG_ReadLong ();
646 
647 	strlcpy (player->userinfo, MSG_ReadString(), sizeof(player->userinfo));
648 	strlcpy (player->name, Info_ValueForKey (player->userinfo, "name"), sizeof(player->name));
649 
650 	if (Info_ValueForKey (player->userinfo, "*spectator")[0])
651 		player->spectator = true;
652 	else
653 		player->spectator = false;
654 
655 	MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
656 	MSG_WriteByte(msgbuf, svc_updateuserinfo);
657 	MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
658 	strlcpy(world.players[slot].name, player->name, MAX_SCOREBOARDNAME);
659 	strlcpy(world.players[slot].userinfo, player->userinfo, sizeof(world.players[0].userinfo));
660 	world.players[slot].spectator = player->spectator;
661 }
662 
663 /*
664 ==================
665 Dem_ParseDelta
666 
667 Can go from either a baseline or a previous packet_entity
668 ==================
669 */
670 int	bitcounts[32]; // just for protocol profiling
Dem_ParseDelta(entity_state_t * efrom,entity_state_t * eto,int bits)671 void Dem_ParseDelta (entity_state_t *efrom, entity_state_t *eto, int bits)
672 {
673 	int i, morebits = 0;
674 
675 	// set everything to the state we are delta'ing from
676 	*eto = *efrom;
677 
678 	eto->number = bits & 511;
679 	bits &= ~511;
680 
681 	if (bits & U_MOREBITS)
682 	{
683 		// read in the low order bits
684 		i = MSG_ReadByte ();
685 		bits |= i;
686 	}
687 
688 	if ((bits & U_FTE_EVENMORE) && from->extensions_fte1) {
689 		morebits = MSG_ReadByte();
690 		if (morebits & U_FTE_YETMORE) {
691 			morebits |= MSG_ReadByte() << 8;
692 		}
693 	}
694 	else {
695 		morebits = 0;
696 	}
697 
698 	// count the bits for net profiling
699 	for (i=0 ; i<16 ; i++)
700 		if (bits&(1<<i))
701 			bitcounts[i]++;
702 
703 	eto->flags = bits;
704 
705 	if (bits & U_MODEL)
706 		eto->modelindex = MSG_ReadByte ();
707 
708 	if (bits & U_FRAME)
709 		eto->frame = MSG_ReadByte ();
710 
711 	if (bits & U_COLORMAP)
712 		eto->colormap = MSG_ReadByte();
713 
714 	if (bits & U_SKIN)
715 		eto->skinnum = MSG_ReadByte();
716 
717 	if (bits & U_EFFECTS)
718 		eto->effects = MSG_ReadByte();
719 
720 	if (bits & U_ORIGIN1) {
721 		if (from->extensions_mvd1 & MVD_PEXT1_FLOATCOORDS) {
722 			eto->origin[0] = MSG_ReadLongCoord();
723 		}
724 		else {
725 			eto->origin[0] = MSG_ReadCoord();
726 		}
727 	}
728 
729 	if (bits & U_ANGLE1)
730 		eto->angles[0] = MSG_ReadAngle();
731 
732 	if (bits & U_ORIGIN2) {
733 		if (from->extensions_mvd1 & MVD_PEXT1_FLOATCOORDS) {
734 			eto->origin[1] = MSG_ReadLongCoord();
735 		}
736 		else {
737 			eto->origin[1] = MSG_ReadCoord();
738 		}
739 	}
740 
741 	if (bits & U_ANGLE2)
742 		eto->angles[1] = MSG_ReadAngle();
743 
744 	if (bits & U_ORIGIN3) {
745 		if (from->extensions_mvd1 & MVD_PEXT1_FLOATCOORDS) {
746 			eto->origin[2] = MSG_ReadLongCoord();
747 		}
748 		else {
749 			eto->origin[2] = MSG_ReadCoord();
750 		}
751 	}
752 
753 	if (bits & U_ANGLE3)
754 		eto->angles[2] = MSG_ReadAngle();
755 
756 	if (bits & U_SOLID)
757 	{
758 		// FIXME
759 	}
760 
761 	if ((morebits & U_FTE_TRANS) && from->extensions_fte1 & FTE_PEXT_TRANS) {
762 		//eto->trans = MSG_ReadByte();
763 		MSG_ReadByte();
764 	}
765 
766 	if (morebits & U_FTE_ENTITYDBL) {
767 		eto->number += 512;
768 	}
769 
770 	if (morebits & U_FTE_ENTITYDBL2) {
771 		eto->number += 1024;
772 	}
773 
774 	if (morebits & U_FTE_MODELDBL) {
775 		eto->modelindex += 256;
776 	}
777 }
778 
779 /*
780 =================
781 FlushEntityPacket
782 =================
783 */
784 
FlushEntityPacket(void)785 void FlushEntityPacket (void)
786 {
787 	int word;
788 	entity_state_t olde, newe;
789 
790 	memset (&olde, 0, sizeof(olde));
791 
792 	//world.validsequence = 0;		// can't render a frame
793 	from->frames[from->netchan.incoming_sequence&UPDATE_MASK].invalid = true;
794 
795 	// read it all, but ignore it
796 	while (1)
797 	{
798 		word = (unsigned short)MSG_ReadShort ();
799 		if (msg_badread)
800 		{	// something didn't parse right...
801 			Sys_Printf ("ERROR:msg_badread in packetentities\n");
802 			Dem_Stop(from);
803 			return;
804 		}
805 
806 		if (!word)
807 			break;	// done
808 
809 		Dem_ParseDelta (&olde, &newe, word);
810 	}
811 }
812 
813 
814 /*
815 ==================
816 Dem_ParsePacketEntities
817 
818 An svc_packetentities has just been parsed, deal with the
819 rest of the data stream.
820 ==================
821 */
822 
Dem_ParsePacketEntities(qbool delta)823 void Dem_ParsePacketEntities (qbool delta)
824 {
825 	int			oldpacket, newpacket;
826 	packet_entities_t	*oldp, *newp, dummy;
827 	int			oldindex, newindex;
828 	int			word, newnum, oldnum;
829 	qbool		full;
830 	byte		deltafrom;
831 
832 	newpacket = from->netchan.incoming_sequence&UPDATE_MASK;
833 	newp = &from->frames[newpacket].packet_entities;
834 	from->frames[newpacket].invalid = false;
835 
836 	if (delta)
837 	{
838 		deltafrom = MSG_ReadByte ();
839 
840 		oldpacket = from->frames[newpacket].delta_sequence;
841 		if (from->format == mvd)
842 		{
843 			oldpacket = (from->netchan.incoming_sequence-1);
844 		}
845 		else
846 		{
847 			if (from->netchan.outgoing_sequence - from->netchan.incoming_sequence >= UPDATE_BACKUP-1)
848 			{	// there are no valid frames left, so drop it
849 				FlushEntityPacket ();
850 				return;
851 			}
852 
853 			if (from->netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP-1)
854 			{	// we can't use this, it is too old
855 				FlushEntityPacket ();
856 				return;
857 			}
858 		}
859 
860 		from->validsequence = from->netchan.incoming_sequence;
861 		oldp = &from->frames[oldpacket&UPDATE_MASK].packet_entities;
862 		full = false;
863 	}
864 	else
865 	{	// this is a full update that we can start delta compressing from now
866 		oldp = &dummy;
867 		dummy.num_entities = 0;
868 		from->validsequence = from->netchan.incoming_sequence;
869 		full = true;
870 	}
871 
872 	oldindex = 0;
873 	newindex = 0;
874 	newp->num_entities = 0;
875 
876 	world.validsequence = 1;
877 
878 	while (1)
879 	{
880 		word = (unsigned short)MSG_ReadShort ();
881 		if (msg_badread)
882 		{	// something didn't parse right...
883 			Sys_Printf ("ERROR:msg_badread in packetentities\n");
884 			Dem_Stop(from);
885 			return;
886 		}
887 
888 		if (!word)
889 		{
890 			while (oldindex < oldp->num_entities)
891 			{	// copy all the rest of the entities from the old packet
892 				if (newindex >= MAX_MVD_PACKET_ENTITIES)
893 				{
894 					Sys_Printf ("Dem_ParsePacketEntities: newindex == MAX_MVD_PACKET_ENTITIES\n");
895 					Dem_Stop(from);
896 					return;
897 				}
898 				newp->entities[newindex] = oldp->entities[oldindex];
899 				newindex++;
900 				oldindex++;
901 			}
902 			break;
903 		}
904 		newnum = word&511;
905 
906 		if ((word & U_MOREBITS) && (from->extensions_fte1 & FTE_PEXT_ENTITYDBL)) {
907 			// Fte extensions for huge entity counts
908 			int oldpos = msg_readcount;
909 			int excessive;
910 			excessive = MSG_ReadByte();
911 
912 			if (excessive & U_FTE_EVENMORE) {
913 				excessive = MSG_ReadByte();
914 				if (excessive & U_FTE_ENTITYDBL) {
915 					newnum += 512;
916 				}
917 
918 				if (excessive & U_FTE_ENTITYDBL2) {
919 					newnum += 1024;
920 				}
921 			}
922 
923 			msg_readcount = oldpos; // undo the read...
924 		}
925 
926 		oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
927 
928 		while (newnum > oldnum)
929 		{
930 			if (full)
931 			{
932 				//Con_Printf ("WARNING: oldcopy on full update");
933 				FlushEntityPacket ();
934 				return;
935 			}
936 
937 			// copy one of the old entities over to the new packet unchanged
938 			if (newindex >= MAX_MVD_PACKET_ENTITIES)
939 			{
940 				Sys_Printf ("ERROR:Dem_ParsePacketEntities: newindex == MAX_MVD_PACKET_ENTITIES\n");
941 				Dem_Stop(from);
942 				return;
943 			}
944 			newp->entities[newindex] = oldp->entities[oldindex];
945 			newindex++;
946 			oldindex++;
947 			oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
948 		}
949 
950 		if (newnum < oldnum)
951 		{	// new from baseline
952 			if (word & U_REMOVE)
953 			{
954 				// read past extra bytes
955 				if ((word & U_MOREBITS) && (from->extensions_fte1 & FTE_PEXT_ENTITYDBL)) {
956 					if (MSG_ReadByte() & U_FTE_EVENMORE) {
957 						MSG_ReadByte();
958 					}
959 				}
960 
961 				if (full)
962 				{
963 					//world.validsequence = 0;
964 					//Con_Printf ("WARNING: U_REMOVE on full update\n");
965 					FlushEntityPacket ();
966 					return;
967 				}
968 				continue;
969 			}
970 			if (newindex >= MAX_MVD_PACKET_ENTITIES)
971 			{
972 				Sys_Printf ("ERROR:Dem_ParsePacketEntities: newindex == MAX_MVD_PACKET_ENTITIES\n");
973 				Dem_Stop(from);
974 				return;
975 			}
976 			Dem_ParseDelta (&baselines[newnum], &newp->entities[newindex], word);
977 			newindex++;
978 			continue;
979 		}
980 
981 		if (newnum == oldnum)
982 		{	// delta from previous
983 			if (full)
984 			{
985 				//world.validsequence = 0;
986 				//Con_Printf ("WARNING: delta on full update");
987 			}
988 			if (word & U_REMOVE)
989 			{
990 				// read past extra bytes
991 				if ((word & U_MOREBITS) && (from->extensions_fte1 & FTE_PEXT_ENTITYDBL)) {
992 					if (MSG_ReadByte() & U_FTE_EVENMORE) {
993 						MSG_ReadByte();
994 					}
995 				}
996 
997 				oldindex++;
998 				continue;
999 			}
1000 
1001 			Dem_ParseDelta (&oldp->entities[oldindex], &newp->entities[newindex], word);
1002 			newindex++;
1003 			oldindex++;
1004 		}
1005 
1006 	}
1007 
1008 	newp->num_entities = newindex;
1009 	if (sworld.options & O_DEBUG)
1010 		fprintf(sworld.debug.file, "num_entities:%d\n", newp->num_entities);
1011 }
1012 
TranslateFlags(int src,int to)1013 int TranslateFlags(int src, int to)
1014 {
1015 	int dst = 0;
1016 
1017 	if (to == qwd)
1018 	{
1019 		if (src & DF_EFFECTS)
1020 			dst |= PF_EFFECTS;
1021 		if (src & DF_SKINNUM)
1022 			dst |= PF_SKINNUM;
1023 		if (src & DF_DEAD)
1024 			dst |= PF_DEAD;
1025 		if (src & DF_GIB)
1026 			dst |= PF_GIB;
1027 		if (src & DF_WEAPONFRAME)
1028 			dst |= PF_WEAPONFRAME;
1029 		if (src & DF_MODEL)
1030 			dst |= PF_MODEL;
1031 
1032 		return dst;
1033 	}
1034 
1035 	if (src & PF_EFFECTS)
1036 		dst |= DF_EFFECTS;
1037 	if (src & PF_SKINNUM)
1038 		dst |= DF_SKINNUM;
1039 	if (src & PF_DEAD)
1040 		dst |= DF_DEAD;
1041 	if (src & PF_GIB)
1042 		dst |= DF_GIB;
1043 	if (src & PF_WEAPONFRAME)
1044 		dst |= DF_WEAPONFRAME;
1045 	if (src & PF_MODEL)
1046 		dst |= DF_MODEL;
1047 
1048 	return dst;
1049 }
1050 
Dem_ParsePlayerinfo(void)1051 void Dem_ParsePlayerinfo (void)
1052 {
1053 	int			msec = 0;
1054 	int			flags;
1055 	player_state_t	*state, *prevstate, dummy;
1056 	int			num;
1057 	int			i;
1058 	//static int model = 0;
1059 
1060 	num = MSG_ReadByte ();
1061 	//Sys_Printf("%d:parse:%d\n",from->parsecount, num);
1062 	if (num >= MAX_CLIENTS)
1063 	{
1064 		Sys_Printf ("ERROR:Dem_ParsePlayerinfo: bad num\n");
1065 		Dem_Stop(from);
1066 		return;
1067 	}
1068 
1069 	memset(&dummy, 0, sizeof(dummy));
1070 
1071 	state = &from->frames[from->parsecountmod].playerstate[num];
1072 	if (from->prevnum[num] > from->parsecount)
1073 	{
1074 		from->prevnum[num] = 0;
1075 		prevstate = &dummy;
1076 	}
1077 	else
1078 	{
1079 		if (from->prevnum[num] - from->parsecount >= UPDATE_BACKUP-1)
1080 			prevstate = &dummy;
1081 		else
1082 			prevstate = &from->frames[from->prevnum[num]&UPDATE_MASK].playerstate[num];
1083 	}
1084 
1085 	from->prevnum[num] = from->parsecount;
1086 
1087 	if (from->format == mvd)
1088 	{
1089 		memcpy(state, prevstate, sizeof(player_state_t));
1090 		flags = MSG_ReadShort ();
1091 		state->flags = 0;
1092 
1093 		state->flags = TranslateFlags(flags, qwd);
1094 
1095 		//Con_Printf("flags:%i\n", flags);
1096 		state->messagenum = from->parsecount;
1097 		state->command.msec = 0;
1098 
1099 		state->frame = MSG_ReadByte ();
1100 		state->command.msec = 0;
1101 
1102 		for (i = 0; i < 3; i++) {
1103 			if (flags & (DF_ORIGIN << i)) {
1104 				if (from->extensions_mvd1 & MVD_PEXT1_FLOATCOORDS) {
1105 					state->origin[i] = MSG_ReadLongCoord();
1106 				}
1107 				else {
1108 					state->origin[i] = MSG_ReadCoord();
1109 				}
1110 			}
1111 		}
1112 
1113 		for (i = 0; i < 3; i++) {
1114 			if (flags & (DF_ANGLES << i)) {
1115 				state->command.angles[i] = MSG_ReadAngle16();
1116 			}
1117 		}
1118 
1119 		if (flags & DF_MODEL) {
1120 			state->modelindex = MSG_ReadByte ();
1121 		}
1122 
1123 		if (flags & DF_SKINNUM)
1124 		{
1125 			state->skinnum = MSG_ReadByte ();
1126 		}
1127 
1128 		if (flags & DF_EFFECTS)
1129 		{
1130 			state->effects = MSG_ReadByte ();
1131 		}
1132 
1133 		if (flags & DF_WEAPONFRAME)
1134 		{
1135 			state->weaponframe = MSG_ReadByte ();
1136 		}
1137 
1138 		if (from->spectator && num == from->playernum)
1139 			state->messagenum = -1;
1140 		return;
1141 	}
1142 
1143 	flags = state->flags = MSG_ReadShort ();
1144 
1145 	state->messagenum = from->parsecount;
1146 	if (from->extensions_mvd1 & MVD_PEXT1_FLOATCOORDS) {
1147 		state->origin[0] = MSG_ReadLongCoord();
1148 		state->origin[1] = MSG_ReadLongCoord();
1149 		state->origin[2] = MSG_ReadLongCoord();
1150 	}
1151 	else {
1152 		state->origin[0] = MSG_ReadCoord();
1153 		state->origin[1] = MSG_ReadCoord();
1154 		state->origin[2] = MSG_ReadCoord();
1155 	}
1156 
1157 	state->frame = MSG_ReadByte ();
1158 
1159 	// the other player's last move was likely some time
1160 	// before the packet was sent out, so accurately track
1161 	// the exact time it was valid at
1162 	if (flags & PF_MSEC)
1163 	{
1164 		msec = MSG_ReadByte ();
1165 	}
1166 
1167 	if (flags & PF_COMMAND)
1168 		MSG_ReadDeltaUsercmd (&nullcmd, &state->command);
1169 
1170 	state->command.msec = msec;
1171 
1172 	for (i=0 ; i<3 ; i++)
1173 	{
1174 		if (flags & (PF_VELOCITY1<<i) )
1175 		{
1176 			state->velocity[i] = MSG_ReadShort();
1177 		}
1178 		else
1179 			state->velocity[i] = 0;
1180 	}
1181 	if (flags & PF_MODEL)
1182 	{
1183 		state->modelindex = MSG_ReadByte ();
1184 	}
1185 	else
1186 		state->modelindex = cl_playerindex;
1187 
1188 	if (flags & PF_SKINNUM)
1189 	{
1190 		state->skinnum = MSG_ReadByte ();
1191 	}
1192 	else
1193 		state->skinnum = 0;
1194 
1195 	if (flags & PF_EFFECTS)
1196 	{
1197 		state->effects = MSG_ReadByte ();
1198 	}
1199 	else
1200 		state->effects = 0;
1201 
1202 	if (flags & PF_WEAPONFRAME)
1203 	{
1204 		state->weaponframe = MSG_ReadByte ();
1205 	}
1206 	else
1207 		state->weaponframe = 0;
1208 
1209 	if (from->spectator && num == from->playernum)
1210 		state->messagenum = -1;
1211 }
1212 
1213 /*
1214 =====================
1215 Dem_ParseProjectiles
1216 
1217 Nails are passed as efficient temporary entities
1218 =====================
1219 */
Dem_ParseProjectiles(qbool nails2)1220 void Dem_ParseProjectiles (qbool nails2)
1221 {
1222 	int		i, c, j, num;
1223 	byte	bits[6];
1224 	projectile_t	*pr;
1225 	frame_t	*frame;
1226 
1227 	frame = &from->frames[from->parsecountmod];
1228 
1229 	c = MSG_ReadByte ();
1230 	for (i=0 ; i<c ; i++)
1231 	{
1232 		if (nails2)
1233 			num = MSG_ReadByte();
1234 		else
1235 			num = 0;
1236 
1237 		for (j=0 ; j<6 ; j++)
1238 			bits[j] = MSG_ReadByte ();
1239 
1240 		if (frame->num_projectiles == MAX_PROJECTILES)
1241 			continue;
1242 
1243 		pr = &frame->projectiles[frame->num_projectiles];
1244 		frame->num_projectiles++;
1245 
1246 		pr->modelindex = cl_spikeindex;
1247 		pr->origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096;
1248 		pr->origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096;
1249 		pr->origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096;
1250 		pr->angles[0] = 360*(bits[4]>>4)/16;
1251 		pr->angles[1] = 360*bits[5]/256;
1252 		pr->num = num;
1253 	}
1254 }
1255 
1256 /*
1257 =================
1258 CL_ParseTEnt
1259 =================
1260 */
Dem_ParseTEnt(void)1261 void Dem_ParseTEnt (void)
1262 {
1263 	int		type;
1264 
1265 	type = MSG_ReadByte ();
1266 
1267 	switch (type)
1268 	{
1269 	case TE_LIGHTNING1:
1270 	case TE_LIGHTNING2:
1271 	case TE_LIGHTNING3:
1272 		MVDWrite_Begin(dem_all, 0, 16);
1273 		MSG_WriteByte(msgbuf, svc_temp_entity);
1274 		MSG_WriteByte(msgbuf, type);
1275 		MSG_Forward(msgbuf, msg_readcount, 14);
1276 		break;
1277 	case TE_GUNSHOT:
1278 	case TE_BLOOD:
1279 		MVDWrite_Begin(dem_all, 0, 9);
1280 		MSG_WriteByte(msgbuf, svc_temp_entity);
1281 		MSG_WriteByte(msgbuf, type);
1282 		MSG_Forward(msgbuf, msg_readcount, 7);
1283 		break;
1284 	default:
1285 		MVDWrite_Begin(dem_all, 0, 8);
1286 		MSG_WriteByte(msgbuf, svc_temp_entity);
1287 		MSG_WriteByte(msgbuf, type);
1288 		MSG_Forward(msgbuf, msg_readcount, 6);
1289 		break;
1290 	}
1291 }
1292 
1293 /*
1294 ==================
1295 Dem_ParseBaseline
1296 ==================
1297 */
1298 
Dem_ParseBaseline(entity_state_t * es)1299 void Dem_ParseBaseline (entity_state_t *es)
1300 {
1301 	int			i;
1302 
1303 	es->modelindex = MSG_ReadByte ();
1304 	es->frame = MSG_ReadByte ();
1305 	es->colormap = MSG_ReadByte();
1306 	es->skinnum = MSG_ReadByte();
1307 	for (i=0 ; i<3 ; i++)
1308 	{
1309 		es->origin[i] = MSG_ReadCoord ();
1310 		es->angles[i] = MSG_ReadAngle ();
1311 	}
1312 }
1313 
1314 #define SHOWNET(x) \
1315 { \
1316 	if (sworld.options & O_DEBUG) { \
1317 		if (cmd < 60) { \
1318 			fprintf(sworld.debug.file, "%3i:%s\n", msg_readcount-1, x); \
1319 		} \
1320 		else { \
1321 			fprintf(sworld.debug.file, "%3i:%s\n", msg_readcount-1, "unknown message"); \
1322 		} \
1323 	} \
1324 }
1325 /*
1326 =====================
1327 Dem_ParseServerMessage
1328 =====================
1329 */
1330 int received_framecount;
Dem_ParseDemoMessage(void)1331 void Dem_ParseDemoMessage (void)
1332 {
1333 	int			cmd = 0, oldcmd;
1334 	int			i,j;
1335 	char		*s;
1336 	extern sizebuf_t stats_msg;
1337 
1338 	//
1339 	// if recording demos, copy the message out
1340 	//
1341 
1342 	Dem_ParseClientdata ();
1343 	if (from->format == qwd)
1344 		from->frames[from->parsecountmod].num_projectiles = 0;
1345 
1346 	//
1347 	// parse the message
1348 	//
1349 	while (1)
1350 	{
1351 		if (!from->running)
1352 			return;
1353 
1354 		if (msg_badread)
1355 		{
1356 			Sys_Printf ("ERROR:Dem_ParseDemoMessage: Bad demo message\n");
1357 			Dem_Stop(from);
1358 			return;
1359 		}
1360 
1361 		oldcmd = cmd;
1362 
1363 		cmd = MSG_ReadByte ();
1364 
1365 		if (cmd == -1)
1366 		{
1367 			msg_readcount++;	// so the EOM showner has the right value
1368 			SHOWNET("END OF MESSAGE");
1369 			break;
1370 		}
1371 
1372 		SHOWNET(svc_strings[cmd]);
1373 
1374 		// other commands
1375 		switch (cmd)
1376 		{
1377 		default:
1378 			Sys_Printf ("ERROR:Dem_ParseDemoMessage: Illegible demo message %d(prev=%d)\n", cmd, oldcmd);
1379 			Dem_Stop(from);
1380 			return;
1381 
1382 		case svc_nop:
1383 			MVDWrite_Begin(dem_all, 0, 1);
1384 			MSG_WriteByte(msgbuf, cmd);
1385 			break;
1386 
1387 		case svc_disconnect:
1388 			Dem_Stop(from);
1389 			return;
1390 
1391 		case svc_print:
1392 			Dem_ParsePrint ();
1393 			break;
1394 
1395 		case svc_centerprint:
1396 			s = MSG_ReadString();
1397 
1398 			MVDWrite_Begin(from->type, To(), strlen(s)+2);
1399 			//Sys_Printf("%d, %d, %s\n", from->type, To(), s);
1400 			MSG_WriteByte(msgbuf, cmd);
1401 			MSG_WriteString(msgbuf, s);
1402 			break;
1403 
1404 		case svc_stufftext:
1405 			msg_startcount = msg_readcount;
1406 
1407 			s = MSG_ReadString ();
1408 
1409 			if (sworld.options & O_DEBUG)
1410 				fprintf(sworld.debug.file, "text(%d):%s\n", (int) strlen(s), s);
1411 
1412 			if (!strncmp(s, "reconnect", 9))
1413 			{
1414 				Dem_Stop(from);
1415 				return;
1416 			}
1417 
1418 			if (!strncmp(s, "changing", 8))
1419 			{
1420 				break;
1421 			}
1422 
1423 			if (!world.signonloaded)
1424 				MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
1425 			else
1426 				MVDWrite_Begin(from->type, from->to, msg_readcount - msg_startcount + 1);
1427 			MSG_WriteByte(msgbuf, svc_stufftext);
1428 			MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
1429 			break;
1430 
1431 		case svc_damage:
1432 			MVDWrite_Begin(from->type, To(), 9);
1433 			MSG_WriteByte(msgbuf, cmd);
1434 			MSG_Forward(msgbuf, msg_readcount, 8);
1435 			break;
1436 
1437 		case svc_serverdata:
1438 			Dem_ParseServerData ();
1439 			break;
1440 
1441 		case svc_setangle:
1442 			MVDWrite_Begin(dem_all, 0, 5);
1443 			MSG_WriteByte(msgbuf, cmd);
1444 			if (from->format == qwd)
1445 			{
1446 				if (from->extensions_mvd1 & MVD_PEXT1_HIGHLAGTELEPORT) {
1447 					MSG_ReadByte(); // flag to indicate if this was a teleport or a spawn
1448 				}
1449 				MSG_WriteByte(msgbuf, To());
1450 				for (i=0 ; i<3 ; i++)
1451 					from->frames[from->parsecountmod].playerstate[from->to].command.angles[i] = MSG_ReadAngle ();
1452 
1453 				//world7.frames[world.parsecount&UPDATE_MASK].fixangle[from->to] = true;
1454 
1455 				for (i=0 ; i<3 ; i++)
1456 					MSG_WriteAngle(msgbuf, from->frames[from->parsecountmod].playerstate[from->to].command.angles[i]);
1457 
1458 				//MSG_Forward(msgbuf, msg_readcount, 3);
1459 			}
1460 			else
1461 			{
1462 				MSG_Forward(msgbuf, msg_readcount, 4);
1463 			}
1464 			world.frames[world.parsecount&UPDATE_MASK].fixangle[from->to] = -1;
1465 
1466 			//world.players[from->to].fixangle = false;
1467 			if (sworld.options & O_DEBUG)
1468 				fprintf(sworld.debug.file, "setangle:%d\n", from->to);
1469 			break;
1470 
1471 		case svc_lightstyle:
1472 			msg_startcount = msg_readcount;
1473 			i = MSG_ReadByte ();
1474 			if (i >= MAX_LIGHTSTYLES)
1475 			{
1476 				Sys_Printf ("svc_lightstyle > MAX_LIGHTSTYLES\n");
1477 				Dem_Stop(from);
1478 				return;
1479 			}
1480 			strlcpy (lightstyle[i].map,  MSG_ReadString(), MAX_STYLESTRING);
1481 			lightstyle[i].length = strlen(lightstyle[i].map);
1482 
1483 			MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
1484 			MSG_WriteByte(msgbuf, cmd);
1485 			MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
1486 			break;
1487 
1488 		case svc_sound:
1489 			Dem_ParseStartSoundPacket();
1490 			break;
1491 
1492 		case svc_stopsound:
1493 			MVDWrite_Begin(dem_all, 0, 3);
1494 			MSG_WriteByte(msgbuf, cmd);
1495 			MSG_Forward(msgbuf, msg_readcount, 2);
1496 			break;
1497 
1498 		case svc_updatefrags:
1499 			MVDWrite_Begin(dem_all, 0, 4);
1500 			MSG_WriteByte(msgbuf, cmd);
1501 			MSG_Forward(msgbuf, msg_readcount, 3);
1502 			break;
1503 
1504 		case svc_updateping:
1505 			MVDWrite_Begin(dem_all, 0, 4);
1506 			MSG_WriteByte(msgbuf, cmd);
1507 			MSG_Forward(msgbuf, msg_readcount, 3);
1508 			break;
1509 
1510 		case svc_updatepl:
1511 			MVDWrite_Begin(dem_all, 0, 3);
1512 			MSG_WriteByte(msgbuf, cmd);
1513 			MSG_Forward(msgbuf, msg_readcount, 2);
1514 			break;
1515 
1516 		case svc_updateentertime:
1517 			MVDWrite_Begin(dem_all, 0, 6);
1518 			MSG_WriteByte(msgbuf, cmd);
1519 			MSG_Forward(msgbuf, msg_readcount, 5);
1520 			break;
1521 
1522 		case svc_spawnbaseline:
1523 			msg_startcount = msg_readcount;
1524 			i = MSG_ReadShort ();
1525 			Dem_ParseBaseline (&baselines[i]);
1526 
1527 			MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
1528 			MSG_WriteByte(msgbuf, cmd);
1529 			MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
1530 			break;
1531 		case svc_spawnstatic:
1532 			MVDWrite_Begin(dem_all, 0, 14);
1533 			MSG_WriteByte(msgbuf, cmd);
1534 			MSG_Forward(msgbuf, msg_readcount, 13);
1535 			break;
1536 		case svc_temp_entity:
1537 			Dem_ParseTEnt ();
1538 			break;
1539 
1540 		case svc_killedmonster:
1541 			MVDWrite_Begin(from->type, To(), 1);
1542 			MSG_WriteByte(msgbuf, cmd);
1543 			break;
1544 
1545 		case svc_foundsecret:
1546 			MVDWrite_Begin(from->type, To(), 1);
1547 			MSG_WriteByte(msgbuf, cmd);
1548 			break;
1549 
1550 		case svc_updatestat:
1551 			if (from->spectator)
1552 			{
1553 				MSG_WriteByte(&stats_msg, cmd);
1554 				MSG_Forward(&stats_msg, msg_readcount, 2);
1555 				break;
1556 			}
1557 
1558 			if (!world.signonstats)
1559 			{
1560 				MVDWrite_Begin(dem_stats, To(), 3);
1561 				MSG_WriteByte(msgbuf, cmd);
1562 				MSG_Forward(msgbuf, msg_readcount, 2);
1563 				break;
1564 			}
1565 
1566 			/*if (world.signonstats)
1567 			{
1568 				sizebuf_t *tmp;
1569 
1570 				tmp = msgbuf;
1571 				msgbuf = &from->signon_stats;
1572 				MVDWrite_Begin(dem_stats, To(), 3);
1573 				MSG_WriteByte(msgbuf, cmd);
1574 				MSG_Forward(msgbuf, msg_readcount, 2);
1575 				msgbuf = tmp;
1576 				break;
1577 			}
1578 
1579 			if (from->spectator) {
1580 				MSG_WriteByte(&stats_msg, cmd);
1581 				MSG_Forward(&stats_msg, msg_readcount, 2);
1582 				break;
1583 			}
1584 			*/
1585 
1586 			i = MSG_ReadByte();
1587 			j = MSG_ReadByte();
1588 
1589 			if (i < 0 || i >= MAX_CL_STATS)
1590 			{
1591 				Sys_Printf("Dem_SetStat: %i is invalid", i);
1592 				Dem_Stop(from);
1593 				return;
1594 			}
1595 
1596 			from->players[To()].stats[i]=j;
1597 
1598 
1599 			/*MVDWrite_Begin(dem_stats, To(), 3);
1600 			MSG_WriteByte(msgbuf, cmd);
1601 			MSG_Forward(msgbuf, msg_readcount, 2);
1602 			*/
1603 			break;
1604 		case svc_updatestatlong:
1605 			if (from->spectator)
1606 			{
1607 				MSG_WriteByte(&stats_msg, cmd);
1608 				MSG_Forward(&stats_msg, msg_readcount, 5);
1609 				break;
1610 			}
1611 
1612 			if (!world.signonstats)
1613 			{
1614 				MVDWrite_Begin(dem_stats, To(), 6);
1615 				MSG_WriteByte(msgbuf, cmd);
1616 				MSG_Forward(msgbuf, msg_readcount, 5);
1617 				break;
1618 			}
1619 
1620 			i = MSG_ReadByte();
1621 			j = MSG_ReadLong();
1622 
1623 			if (i < 0 || i >= MAX_CL_STATS)
1624 			{
1625 				Sys_Printf("Dem_SetStat: %i is invalid", i);
1626 				Dem_Stop(from);
1627 				return;
1628 			}
1629 
1630 			from->players[To()].stats[i]=j;
1631 
1632 			/*
1633 			if (world.signonstats)
1634 			{
1635 				sizebuf_t *tmp;
1636 
1637 				tmp = msgbuf;
1638 				msgbuf = &from->signon_stats;
1639 				MVDWrite_Begin(dem_stats, To(), 6);
1640 				MSG_WriteByte(msgbuf, cmd);
1641 				MSG_Forward(msgbuf, msg_readcount, 5);
1642 				msgbuf = tmp;
1643 				break;
1644 			}
1645 			*/
1646 			/*
1647 			MVDWrite_Begin(dem_stats, To(), 6);
1648 			MSG_WriteByte(msgbuf, cmd);
1649 			MSG_WriteByte(msgbuf, i);
1650 			MSG_WriteLong(msgbuf, j);
1651 			//MSG_Forward(msgbuf, msg_readcount, 5);
1652 			*/
1653 			break;
1654 
1655 		case svc_spawnstaticsound:
1656 			MVDWrite_Begin(dem_all, 0, 10);
1657 			MSG_WriteByte(msgbuf, cmd);
1658 			MSG_Forward(msgbuf, msg_readcount, 9);
1659 			break;
1660 
1661 		case svc_cdtrack:
1662 			MVDWrite_Begin(dem_all, 0, 2);
1663 			MSG_WriteByte(msgbuf, cmd);
1664 			MSG_Forward(msgbuf, msg_readcount, 1);
1665 			break;
1666 
1667 		case svc_intermission:
1668 			MVDWrite_Begin(dem_all, 0, 10);
1669 			MSG_WriteByte(msgbuf, cmd);
1670 			MSG_Forward(msgbuf, msg_readcount, 9);
1671 			break;
1672 
1673 		case svc_finale:
1674 			s = MSG_ReadString();
1675 
1676 			MVDWrite_Begin(dem_all, 0, strlen(s)+2);
1677 			MSG_WriteByte(msgbuf, cmd);
1678 			MSG_WriteString(msgbuf, s);
1679 			break;
1680 
1681 		case svc_sellscreen:
1682 			MVDWrite_Begin(dem_all, 0, 1);
1683 			MSG_WriteByte(msgbuf, cmd);
1684 			break;
1685 
1686 		case svc_smallkick:
1687 			MVDWrite_Begin(from->type, To(), 1);
1688 			MSG_WriteByte(msgbuf, cmd);
1689 			break;
1690 		case svc_bigkick:
1691 			MVDWrite_Begin(from->type, To(), 1);
1692 			MSG_WriteByte(msgbuf, cmd);
1693 			break;
1694 
1695 		case svc_muzzleflash:
1696 			MVDWrite_Begin(dem_all, 0, 3);
1697 			MSG_WriteByte(msgbuf, cmd);
1698 			MSG_Forward(msgbuf, msg_readcount, 2);
1699 			break;
1700 
1701 		case svc_updateuserinfo:
1702 			Dem_UpdateUserinfo();
1703 			break;
1704 
1705 		case svc_setinfo:
1706 			msg_startcount = msg_readcount;
1707 
1708 			MSG_ReadByte ();
1709 			MSG_ReadString();
1710 			MSG_ReadString();
1711 
1712 			MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
1713 			MSG_WriteByte(msgbuf, cmd);
1714 			MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
1715 			break;
1716 
1717 		case svc_serverinfo:
1718 			msg_startcount = msg_readcount;
1719 
1720 			MSG_ReadString();
1721 			MSG_ReadString();
1722 
1723 			MVDWrite_Begin(dem_all, 0, msg_readcount - msg_startcount + 1);
1724 			MSG_WriteByte(msgbuf, cmd);
1725 			MSG_Forward(msgbuf, msg_startcount, msg_readcount - msg_startcount);
1726 			break;
1727 
1728 		case svc_download:
1729 			Dem_ParseDownload ();
1730 			break;
1731 
1732 		case svc_playerinfo:
1733 			Dem_ParsePlayerinfo ();
1734 			break;
1735 
1736 		case svc_nails:
1737 			Dem_ParseProjectiles (false);
1738 			break;
1739 		case svc_nails2:
1740 			Dem_ParseProjectiles (true);
1741 			break;
1742 
1743 		case svc_chokecount:		// some preceding packets were choked
1744 			MVDWrite_Begin(from->type, from->to, 2);
1745 			MSG_WriteByte(msgbuf, cmd);
1746 			MSG_Forward(msgbuf, msg_readcount, 1);
1747 			break;
1748 
1749 		case svc_modellist:
1750 			Dem_Parselist ((byte)cmd);
1751 			break;
1752 
1753 		case svc_soundlist:
1754 			Dem_Parselist ((byte)cmd);
1755 			break;
1756 
1757 		case svc_packetentities:
1758 			Dem_ParsePacketEntities (false);
1759 			break;
1760 
1761 		case svc_deltapacketentities:
1762 			Dem_ParsePacketEntities (true);
1763 			break;
1764 
1765 		case svc_maxspeed :
1766 			MVDWrite_Begin(dem_all, 0, 5);
1767 			MSG_WriteByte(msgbuf, cmd);
1768 			MSG_Forward(msgbuf, msg_readcount, 4);
1769 			break;
1770 
1771 		case svc_entgravity :
1772 			MVDWrite_Begin(dem_all, 0, 5);
1773 			MSG_WriteByte(msgbuf, cmd);
1774 			MSG_Forward(msgbuf, msg_readcount, 4);
1775 			break;
1776 
1777 		case svc_setpause:
1778 			MVDWrite_Begin(dem_all, 0, 2);
1779 			MSG_WriteByte(msgbuf, cmd);
1780 			MSG_Forward(msgbuf, msg_readcount, 1);
1781 			break;
1782 
1783 		case svc_qizmomsg:
1784 			MSG_ReadByte();
1785 			MSG_ReadByte();
1786 
1787 			for (i = 0; i < 32; i++)
1788 				MSG_ReadByte();
1789 			return;
1790 		}
1791 	}
1792 }
1793