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