2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // cl_parse.c -- parse a message received from the server
24 char *svc_strings[128] =
30 "svc_version", // [long] server version
31 "svc_setview", // [short] entity number
32 "svc_sound", // <see code>
33 "svc_time", // [float] server time
34 "svc_print", // [string] null terminated string
35 "svc_stufftext", // [string] stuffed into client's console buffer
36 // the string should be \n terminated
37 "svc_setangle", // [vec3] set the view angle to this absolute value
39 "svc_serverinfo", // [long] version
40 // [string] signon string
41 // [string]..[0]model cache [string]...[0]sounds cache
42 // [string]..[0]item cache
43 "svc_lightstyle", // [byte] [string]
44 "svc_updatename", // [byte] [string]
45 "svc_updatefrags", // [byte] [short]
46 "svc_clientdata", // <shortbits + data>
47 "svc_stopsound", // <see code>
48 "svc_updatecolors", // [byte] [byte]
49 "svc_particle", // [vec3] <variable>
50 "svc_damage", // [byte] impact [byte] blood [vec3] from
53 "OBSOLETE svc_spawnbinary",
56 "svc_temp_entity", // <variable>
62 "svc_spawnstaticsound",
64 "svc_finale", // [string] music [string] text
65 "svc_cdtrack", // [byte] track [byte] looptrack
68 "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y
69 "svc_hidelmp", // [string] iconlabel
70 "svc_skybox", // [string] skyname
85 "svc_effect", // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
86 "svc_effect2", // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
89 //=============================================================================
91 cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
93 void CL_Parse_Init(void)
95 // LordHavoc: added demo_nehahra cvar
96 Cvar_RegisterVariable (&demo_nehahra);
98 Cvar_SetValue("demo_nehahra", 1);
101 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
102 qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
108 This error checks and tracks the total number of entities
111 entity_t *CL_EntityNum (int num)
114 if (num >= cl.num_entities)
116 if (num >= MAX_EDICTS)
117 Host_Error ("CL_EntityNum: %i is an invalid number",num);
118 cl.num_entities = num;
119 // while (cl.num_entities <= num)
121 // cl_entities[cl.num_entities].colormap = -1; // no special coloring
122 // cl.num_entities++;
126 if (num >= MAX_EDICTS)
127 Host_Error ("CL_EntityNum: %i is an invalid number",num);
129 return &cl_entities[num];
135 CL_ParseStartSoundPacket
138 void CL_ParseStartSoundPacket(int largesoundindex)
148 field_mask = MSG_ReadByte();
150 if (field_mask & SND_VOLUME)
151 volume = MSG_ReadByte ();
153 volume = DEFAULT_SOUND_PACKET_VOLUME;
155 if (field_mask & SND_ATTENUATION)
156 attenuation = MSG_ReadByte () / 64.0;
158 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
160 channel = MSG_ReadShort ();
162 sound_num = (unsigned short) MSG_ReadShort ();
164 sound_num = MSG_ReadByte ();
166 if (sound_num >= MAX_SOUNDS)
167 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
172 if (ent > MAX_EDICTS)
173 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
175 for (i=0 ; i<3 ; i++)
176 pos[i] = MSG_ReadCoord ();
178 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
185 When the client is taking a long time to load stuff, send keepalive messages
186 so the server doesn't disconnect.
189 void CL_KeepaliveMessage (void)
192 static float lastmsg;
198 return; // no need if server is local
199 if (cls.demoplayback)
202 // read messages from server, should just be nops
204 memcpy (olddata, net_message.data, net_message.cursize);
208 ret = CL_GetMessage ();
212 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
214 break; // nothing waiting
216 Host_Error ("CL_KeepaliveMessage: received a message");
219 if (MSG_ReadByte() != svc_nop)
220 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
226 memcpy (net_message.data, olddata, net_message.cursize);
229 time = Sys_DoubleTime ();
230 if (time - lastmsg < 5)
235 Con_Printf ("--> client to server keepalive\n");
237 MSG_WriteByte (&cls.message, clc_nop);
238 NET_SendMessage (cls.netcon, &cls.message);
239 SZ_Clear (&cls.message);
242 void CL_ParseEntityLump(char *entdata)
245 char key[128], value[4096];
248 FOG_clear(); // LordHavoc: no fog until set
249 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
250 r_farclip.value = 6144; // LordHavoc: default farclip distance
254 data = COM_Parse(data);
256 return; // valid exit
257 if (com_token[0] != '{')
261 data = COM_Parse(data);
264 if (com_token[0] == '}')
265 return; // since we're just parsing the first ent (worldspawn), exit
266 strcpy(key, com_token);
267 while (key[strlen(key)-1] == ' ') // remove trailing spaces
268 key[strlen(key)-1] = 0;
269 data = COM_Parse(data);
272 strcpy(value, com_token);
273 if (!strcmp("sky", key))
275 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
277 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
279 else if (!strcmp("farclip", key))
281 r_farclip.value = atof(value);
282 if (r_farclip.value < 64)
283 r_farclip.value = 64;
285 else if (!strcmp("fog", key))
287 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
290 else if (!strcmp("fog_density", key))
291 fog_density = atof(value);
292 else if (!strcmp("fog_red", key))
293 fog_red = atof(value);
294 else if (!strcmp("fog_green", key))
295 fog_green = atof(value);
296 else if (!strcmp("fog_blue", key))
297 fog_blue = atof(value);
298 else if (!strcmp("wad", key)) // for HalfLife maps
303 for (i = 0;i < 4096;i++)
304 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
310 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
311 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
313 else if (value[i] == ';' || value[i] == 0)
317 strcpy(wadname, "textures/");
318 strcat(wadname, &value[j]);
319 W_LoadTextureWadFile (wadname, false);
336 void CL_ParseServerInfo (void)
340 int nummodels, numsounds;
341 char model_precache[MAX_MODELS][MAX_QPATH];
342 char sound_precache[MAX_SOUNDS][MAX_QPATH];
344 Con_DPrintf ("Serverinfo packet received.\n");
346 // wipe the client_state_t struct
350 // parse protocol version number
352 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
354 Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
357 Nehahrademcompatibility = false;
359 Nehahrademcompatibility = true;
360 if (cls.demoplayback && demo_nehahra.value)
361 Nehahrademcompatibility = true;
362 dpprotocol = i == DPPROTOCOL_VERSION;
365 cl.maxclients = MSG_ReadByte ();
366 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
368 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
371 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
374 cl.gametype = MSG_ReadByte ();
376 // parse signon message
377 str = MSG_ReadString ();
378 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
380 // seperate the printfs so the server message can have a color
381 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
383 Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
384 Con_Printf ("%c%s\n", 2, str);
388 // first we go through and touch all of the precache data that still
389 // happens to be in the cache, so precaching something else doesn't
390 // needlessly purge it
394 memset (cl.model_precache, 0, sizeof(cl.model_precache));
395 for (nummodels=1 ; ; nummodels++)
397 str = MSG_ReadString ();
400 if (nummodels==MAX_MODELS)
402 Con_Printf ("Server sent too many model precaches\n");
405 if (strlen(str) >= MAX_QPATH)
406 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
407 strcpy (model_precache[nummodels], str);
408 Mod_TouchModel (str);
412 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
413 for (numsounds=1 ; ; numsounds++)
415 str = MSG_ReadString ();
418 if (numsounds==MAX_SOUNDS)
420 Con_Printf ("Server sent too many sound precaches\n");
423 if (strlen(str) >= MAX_QPATH)
424 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
425 strcpy (sound_precache[numsounds], str);
430 // now we try to load everything else until a cache allocation fails
433 for (i=1 ; i<nummodels ; i++)
435 isworldmodel = i == 1; // LordHavoc: first model is the world model
436 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
437 if (cl.model_precache[i] == NULL)
439 Con_Printf("Model %s not found\n", model_precache[i]);
442 CL_KeepaliveMessage ();
445 S_BeginPrecaching ();
446 for (i=1 ; i<numsounds ; i++)
448 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
449 CL_KeepaliveMessage ();
455 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
459 Hunk_Check (); // make sure nothing is hurt
461 noclip_anglehack = false; // noclip is turned off at start
464 void CL_ValidateState(entity_state_t *s)
471 if (s->modelindex >= MAX_MODELS)
472 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
474 // colormap is client index + 1
475 if (s->colormap > cl.maxclients)
476 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
478 model = cl.model_precache[s->modelindex];
479 if (model && s->frame >= model->numframes)
481 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
490 Parse an entity update message from the server
491 If an entities model or origin changes from frame to frame, it must be
492 relinked. Other attributes can change without relinking.
495 byte entkill[MAX_EDICTS];
496 int bitprofile[32], bitprofilecount = 0;
497 void CL_ParseUpdate (int bits)
499 int i, num, deltadie;
502 if (cls.signon == SIGNONS - 1)
503 { // first update is the final signon stage
504 cls.signon = SIGNONS;
508 if (bits & U_MOREBITS)
509 bits |= (MSG_ReadByte()<<8);
510 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
512 bits |= MSG_ReadByte() << 16;
513 if (bits & U_EXTEND2)
514 bits |= MSG_ReadByte() << 24;
517 if (bits & U_LONGENTITY)
518 num = (unsigned) MSG_ReadShort ();
520 num = (unsigned) MSG_ReadByte ();
522 if (num >= MAX_EDICTS)
523 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
525 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
527 // mark as visible (no kill)
530 ent = CL_EntityNum (num);
532 for (i = 0;i < 32;i++)
537 ent->state_previous = ent->state_current;
541 if (!ent->state_current.active)
542 deltadie = true; // was not present in previous frame, leave hidden until next full update
545 ent->state_current = ent->state_baseline;
547 ent->state_current.time = cl.mtime[0];
549 ent->state_current.flags = 0;
550 ent->state_current.active = true;
551 if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
552 if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
553 if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte();
554 if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte();
555 if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
556 if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord();
557 if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle();
558 if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord();
559 if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle();
560 if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord();
561 if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle();
562 if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP;
563 if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte();
564 if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte();
565 if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
566 if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte();
567 if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
568 if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
569 if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte();
570 if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
571 if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
572 if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
573 if (bits & U_EXTERIORMODEL) ent->state_current.flags |= RENDER_EXTERIORMODEL;
575 // LordHavoc: to allow playback of the Nehahra movie
576 if (Nehahrademcompatibility && (bits & U_EXTEND1))
578 // LordHavoc: evil format
579 int i = MSG_ReadFloat();
580 int j = MSG_ReadFloat() * 255.0f;
584 ent->state_current.effects |= EF_FULLBRIGHT;
587 ent->state_current.alpha = 0;
588 else if (j == 0 || j >= 255)
589 ent->state_current.alpha = 255;
591 ent->state_current.alpha = j;
597 ent->state_current.active = false;
601 CL_ValidateState(&ent->state_current);
604 if (!ent->state_current.active)
609 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
611 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
616 Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
618 Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
625 char *bitprofilenames[32] =
661 void CL_BitProfile_f(void)
664 Con_Printf("bitprofile: %i updates\n");
666 for (i = 0;i < 32;i++)
667 // if (bitprofile[i])
668 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
670 for (i = 0;i < 32;i++)
675 void CL_EntityUpdateSetup(void)
677 memset(entkill, 1, MAX_EDICTS);
680 void CL_EntityUpdateEnd(void)
683 for (i = 1;i < MAX_EDICTS;i++)
685 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
693 void CL_ParseBaseline (entity_t *ent, int large)
697 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
698 ent->state_baseline.active = true;
701 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
702 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
706 ent->state_baseline.modelindex = MSG_ReadByte ();
707 ent->state_baseline.frame = MSG_ReadByte ();
709 ent->state_baseline.colormap = MSG_ReadByte();
710 ent->state_baseline.skin = MSG_ReadByte();
711 for (i = 0;i < 3;i++)
713 ent->state_baseline.origin[i] = MSG_ReadCoord ();
714 ent->state_baseline.angles[i] = MSG_ReadAngle ();
716 ent->state_baseline.alpha = 255;
717 ent->state_baseline.scale = 16;
718 ent->state_baseline.glowsize = 0;
719 ent->state_baseline.glowcolor = 254;
720 ent->state_baseline.colormod = 255;
721 ent->state_previous = ent->state_current = ent->state_baseline;
723 CL_ValidateState(&ent->state_baseline);
731 Server information pertaining to this client only
734 void CL_ParseClientdata (int bits)
739 if (bits & SU_EXTEND1)
740 bits |= (MSG_ReadByte() << 16);
741 if (bits & SU_EXTEND2)
742 bits |= (MSG_ReadByte() << 24);
744 if (bits & SU_VIEWHEIGHT)
745 cl.viewheight = MSG_ReadChar ();
747 cl.viewheight = DEFAULT_VIEWHEIGHT;
749 if (bits & SU_IDEALPITCH)
750 cl.idealpitch = MSG_ReadChar ();
754 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
755 for (i=0 ; i<3 ; i++)
757 if (bits & (SU_PUNCH1<<i) )
760 cl.punchangle[i] = MSG_ReadPreciseAngle();
762 cl.punchangle[i] = MSG_ReadChar();
765 cl.punchangle[i] = 0;
766 if (bits & (SU_PUNCHVEC1<<i))
767 cl.punchvector[i] = MSG_ReadFloatCoord();
769 cl.punchvector[i] = 0;
770 if (bits & (SU_VELOCITY1<<i) )
771 cl.mvelocity[0][i] = MSG_ReadChar()*16;
773 cl.mvelocity[0][i] = 0;
779 for (j=0 ; j<32 ; j++)
780 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
781 cl.item_gettime[j] = cl.time;
785 cl.onground = (bits & SU_ONGROUND) != 0;
786 cl.inwater = (bits & SU_INWATER) != 0;
788 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
789 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
790 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
791 cl.stats[STAT_HEALTH] = MSG_ReadShort();
792 cl.stats[STAT_AMMO] = MSG_ReadByte();
794 cl.stats[STAT_SHELLS] = MSG_ReadByte();
795 cl.stats[STAT_NAILS] = MSG_ReadByte();
796 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
797 cl.stats[STAT_CELLS] = MSG_ReadByte();
802 cl.stats[STAT_ACTIVEWEAPON] = i;
804 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
808 =====================
810 =====================
812 void CL_ParseStatic (int large)
816 if (cl.num_statics >= MAX_STATIC_ENTITIES)
817 Host_Error ("Too many static entities");
818 ent = &cl_static_entities[cl.num_statics++];
819 CL_ParseBaseline (ent, large);
821 // copy it to the current state
822 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
823 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
824 ent->render.framelerp = 0;
825 ent->render.lerp_starttime = -1;
826 // make torchs play out of sync
827 ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
828 ent->render.colormap = -1; // no special coloring
829 ent->render.skinnum = ent->state_baseline.skin;
830 ent->render.effects = ent->state_baseline.effects;
831 ent->render.alpha = 1;
832 ent->render.scale = 1;
833 ent->render.alpha = 1;
834 ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
836 VectorCopy (ent->state_baseline.origin, ent->render.origin);
837 VectorCopy (ent->state_baseline.angles, ent->render.angles);
845 void CL_ParseStaticSound (int large)
848 int sound_num, vol, atten;
852 sound_num = (unsigned short) MSG_ReadShort ();
854 sound_num = MSG_ReadByte ();
855 vol = MSG_ReadByte ();
856 atten = MSG_ReadByte ();
858 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
861 void CL_ParseEffect (void)
864 int modelindex, startframe, framecount, framerate;
867 modelindex = MSG_ReadByte ();
868 startframe = MSG_ReadByte ();
869 framecount = MSG_ReadByte ();
870 framerate = MSG_ReadByte ();
872 CL_Effect(org, modelindex, startframe, framecount, framerate);
875 void CL_ParseEffect2 (void)
878 int modelindex, startframe, framecount, framerate;
881 modelindex = MSG_ReadShort ();
882 startframe = MSG_ReadShort ();
883 framecount = MSG_ReadByte ();
884 framerate = MSG_ReadByte ();
886 CL_Effect(org, modelindex, startframe, framecount, framerate);
890 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
893 =====================
894 CL_ParseServerMessage
895 =====================
897 void CL_ParseServerMessage (void)
900 int i, entitiesupdated;
902 char *cmdlogname[32], *temp;
903 int cmdindex, cmdcount = 0;
906 // if recording demos, copy the message out
908 if (cl_shownet.value == 1)
909 Con_Printf ("%i ",net_message.cursize);
910 else if (cl_shownet.value == 2)
911 Con_Printf ("------------------\n");
913 cl.onground = false; // unless the server says otherwise
919 entitiesupdated = false;
920 CL_EntityUpdateSetup();
925 Host_Error ("CL_ParseServerMessage: Bad server message");
927 cmd = MSG_ReadByte ();
931 SHOWNET("END OF MESSAGE");
932 break; // end of message
935 cmdindex = cmdcount & 31;
937 cmdlog[cmdindex] = cmd;
939 // if the high bit of the command byte is set, it is a fast update
942 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
944 cmdlogname[cmdindex] = temp;
945 SHOWNET("fast update");
946 CL_ParseUpdate (cmd&127);
950 SHOWNET(svc_strings[cmd]);
951 cmdlogname[cmdindex] = svc_strings[cmd];
952 if (!cmdlogname[cmdindex])
954 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
956 cmdlogname[cmdindex] = temp;
964 char description[32*64], temp[64];
966 strcpy(description, "packet dump: ");
970 count = cmdcount - i;
974 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
975 strcat(description, temp);
980 description[strlen(description)-1] = '\n'; // replace the last space with a newline
981 Con_Printf(description);
982 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
987 // Con_Printf ("svc_nop\n");
991 // handle old protocols which do not have entity update ranges
992 entitiesupdated = true;
993 cl.mtime[1] = cl.mtime[0];
994 cl.mtime[0] = MSG_ReadFloat ();
998 i = MSG_ReadShort ();
999 CL_ParseClientdata (i);
1003 i = MSG_ReadLong ();
1004 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
1005 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
1006 Nehahrademcompatibility = false;
1008 Nehahrademcompatibility = true;
1009 if (cls.demoplayback && demo_nehahra.value)
1010 Nehahrademcompatibility = true;
1011 dpprotocol = i == DPPROTOCOL_VERSION;
1014 case svc_disconnect:
1015 Host_EndGame ("Server disconnected\n");
1018 Con_Printf ("%s", MSG_ReadString ());
1021 case svc_centerprint:
1022 SCR_CenterPrint (MSG_ReadString ());
1026 Cbuf_AddText (MSG_ReadString ());
1033 case svc_serverinfo:
1034 CL_ParseServerInfo ();
1035 vid.recalc_refdef = true; // leave intermission full screen
1039 for (i=0 ; i<3 ; i++)
1040 cl.viewangles[i] = MSG_ReadAngle ();
1044 cl.viewentity = MSG_ReadShort ();
1047 case svc_lightstyle:
1048 i = MSG_ReadByte ();
1049 if (i >= MAX_LIGHTSTYLES)
1050 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1051 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1052 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1053 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1057 CL_ParseStartSoundPacket(false);
1061 CL_ParseStartSoundPacket(true);
1065 i = MSG_ReadShort();
1066 S_StopSound(i>>3, i&7);
1069 case svc_updatename:
1070 i = MSG_ReadByte ();
1071 if (i >= cl.maxclients)
1072 Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD");
1073 strcpy (cl.scores[i].name, MSG_ReadString ());
1076 case svc_updatefrags:
1077 i = MSG_ReadByte ();
1078 if (i >= cl.maxclients)
1079 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
1080 cl.scores[i].frags = MSG_ReadShort ();
1083 case svc_updatecolors:
1084 i = MSG_ReadByte ();
1085 if (i >= cl.maxclients)
1086 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
1087 cl.scores[i].colors = MSG_ReadByte ();
1091 R_ParseParticleEffect ();
1102 case svc_spawnbaseline:
1103 i = MSG_ReadShort ();
1104 // must use CL_EntityNum() to force cl.num_entities up
1105 CL_ParseBaseline (CL_EntityNum(i), false);
1107 case svc_spawnbaseline2:
1108 i = MSG_ReadShort ();
1109 // must use CL_EntityNum() to force cl.num_entities up
1110 CL_ParseBaseline (CL_EntityNum(i), true);
1112 case svc_spawnstatic:
1113 CL_ParseStatic (false);
1115 case svc_spawnstatic2:
1116 CL_ParseStatic (true);
1118 case svc_temp_entity:
1123 cl.paused = MSG_ReadByte ();
1131 i = MSG_ReadByte ();
1132 if (i <= cls.signon)
1133 Host_Error ("Received signon %i when at %i", i, cls.signon);
1138 case svc_killedmonster:
1139 cl.stats[STAT_MONSTERS]++;
1142 case svc_foundsecret:
1143 cl.stats[STAT_SECRETS]++;
1146 case svc_updatestat:
1147 i = MSG_ReadByte ();
1148 if (i < 0 || i >= MAX_CL_STATS)
1149 Host_Error ("svc_updatestat: %i is invalid", i);
1150 cl.stats[i] = MSG_ReadLong ();
1153 case svc_spawnstaticsound:
1154 CL_ParseStaticSound (false);
1157 case svc_spawnstaticsound2:
1158 CL_ParseStaticSound (true);
1162 cl.cdtrack = MSG_ReadByte ();
1163 cl.looptrack = MSG_ReadByte ();
1164 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1165 CDAudio_Play ((byte)cls.forcetrack, true);
1167 CDAudio_Play ((byte)cl.cdtrack, true);
1170 case svc_intermission:
1171 cl.intermission = 1;
1172 cl.completed_time = cl.time;
1173 vid.recalc_refdef = true; // go to full screen
1177 cl.intermission = 2;
1178 cl.completed_time = cl.time;
1179 vid.recalc_refdef = true; // go to full screen
1180 SCR_CenterPrint (MSG_ReadString ());
1184 cl.intermission = 3;
1185 cl.completed_time = cl.time;
1186 vid.recalc_refdef = true; // go to full screen
1187 SCR_CenterPrint (MSG_ReadString ());
1190 case svc_sellscreen:
1191 Cmd_ExecuteString ("help", src_command);
1194 SHOWLMP_decodehide();
1197 SHOWLMP_decodeshow();
1200 R_SetSkyBox(MSG_ReadString());
1205 if (entitiesupdated)
1206 CL_EntityUpdateEnd();