1 /*
2 Copyright (C) 1996-2001 Id Software, Inc.
3 Copyright (C) 2002-2009 John Fitzgibbons and others
4 Copyright (C) 2007-2008 Kristian Duske
5 Copyright (C) 2010-2014 QuakeSpasm developers
6 Copyright (C) 2016      Spike
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 // cl_parse.c  -- parse a message received from the server
25 
26 #include "quakedef.h"
27 #include "bgmusic.h"
28 
29 const char *svc_strings[128] =
30 {
31 	"svc_bad",
32 	"svc_nop",
33 	"svc_disconnect",
34 	"svc_updatestat",
35 	"svc_version",		// [long] server version
36 	"svc_setview",		// [short] entity number
37 	"svc_sound",			// <see code>
38 	"svc_time",			// [float] server time
39 	"svc_print",			// [string] null terminated string
40 	"svc_stufftext",		// [string] stuffed into client's console buffer
41 						// the string should be \n terminated
42 	"svc_setangle",		// [vec3] set the view angle to this absolute value
43 
44 	"svc_serverinfo",		// [long] version
45 						// [string] signon string
46 						// [string]..[0]model cache [string]...[0]sounds cache
47 						// [string]..[0]item cache
48 	"svc_lightstyle",		// [byte] [string]
49 	"svc_updatename",		// [byte] [string]
50 	"svc_updatefrags",	// [byte] [short]
51 	"svc_clientdata",		// <shortbits + data>
52 	"svc_stopsound",		// <see code>
53 	"svc_updatecolors",	// [byte] [byte]
54 	"svc_particle",		// [vec3] <variable>
55 	"svc_damage",			// [byte] impact [byte] blood [vec3] from
56 
57 	"svc_spawnstatic",
58 	/*"OBSOLETE svc_spawnbinary"*/"21 svc_spawnstatic_fte",
59 	"svc_spawnbaseline",
60 
61 	"svc_temp_entity",		// <variable>
62 	"svc_setpause",
63 	"svc_signonnum",
64 	"svc_centerprint",
65 	"svc_killedmonster",
66 	"svc_foundsecret",
67 	"svc_spawnstaticsound",
68 	"svc_intermission",
69 	"svc_finale",			// [string] music [string] text
70 	"svc_cdtrack",			// [byte] track [byte] looptrack
71 	"svc_sellscreen",
72 	"svc_cutscene",
73 //johnfitz -- new server messages
74 	"svc_showpic_dp",	// 35
75 	"svc_hidepic_dp",	// 36
76 	"svc_skybox_fitz", // 37					// [string] skyname
77 	"38", // 38
78 	"39", // 39
79 	"svc_bf_fitz", // 40						// no data
80 	"svc_fog_fitz", // 41					// [byte] density [byte] red [byte] green [byte] blue [float] time
81 	"svc_spawnbaseline2_fitz", //42			// support for large modelindex, large framenum, alpha, using flags
82 	"svc_spawnstatic2_fitz", // 43			// support for large modelindex, large framenum, alpha, using flags
83 	"svc_spawnstaticsound2_fitz", //	44		// [coord3] [short] samp [byte] vol [byte] aten
84 	"45", // 45
85 	"46", // 46
86 	"47", // 47
87 	"48", // 48
88 	"49", // 49
89 //johnfitz
90 
91 //spike -- particle stuff, and padded to 128 to avoid possible crashes.
92 	"50 svc_downloaddata_dp", // 50
93 	"51 svc_updatestatbyte", // 51
94 	"52 svc_effect_dp", // 52
95 	"53 svc_effect2_dp", // 53
96 	"54 svc_precache", // 54	//[short] type+idx [string] name
97 	"55 svc_baseline2_dp", // 55
98 	"56 svc_spawnstatic2_dp", // 56
99 	"57 svc_entities_dp", // 57
100 	"58 svc_csqcentities", // 58
101 	"59 svc_spawnstaticsound2_dp", // 59
102 	"60 svc_trailparticles", // 60
103 	"61 svc_pointparticles", // 61
104 	"62 svc_pointparticles1", // 62
105 	"63 svc_particle2_fte", // 63
106 	"64 svc_particle3_fte", // 64
107 	"65 svc_particle4_fte", // 65
108 	"66 svc_spawnbaseline_fte", // 66
109 	"67 svc_customtempent_fte", // 67
110 	"68 svc_selectsplitscreen_fte", // 68
111 	"69 svc_showpic_fte", // 69
112 	"70 svc_hidepic_fte", // 70
113 	"71 svc_movepic_fte", // 71
114 	"72 svc_updatepic_fte", // 72
115 	"73", // 73
116 	"74", // 74
117 	"75", // 75
118 	"76 svc_csqcentities_fte", // 76
119 	"77", // 77
120 	"78 svc_updatestatstring_fte", // 78
121 	"79 svc_updatestatfloat_fte", // 79
122 	"80", // 80
123 	"81", // 81
124 	"82", // 82
125 	"83 svc_cgamepacket_fte", // 83
126 	"84 svc_voicechat_fte", // 84
127 	"85 svc_setangledelta_fte", // 85
128 	"86 svc_updateentities_fte", // 86
129 	"87 svc_brushedit_fte", // 87
130 	"88 svc_updateseats_fte", // 88
131 	"89", // 89
132 	"90", // 90
133 	"91", // 91
134 	"92", // 92
135 	"93", // 93
136 	"94", // 94
137 	"95", // 95
138 	"96", // 96
139 	"97", // 97
140 	"98", // 98
141 	"99", // 99
142 	"100", // 100
143 	"101", // 101
144 	"102", // 102
145 	"103", // 103
146 	"104", // 104
147 	"105", // 105
148 	"106", // 106
149 	"107", // 107
150 	"108", // 108
151 	"109", // 109
152 	"110", // 110
153 	"111", // 111
154 	"112", // 112
155 	"113", // 113
156 	"114", // 114
157 	"115", // 115
158 	"116", // 116
159 	"117", // 117
160 	"118", // 118
161 	"119", // 119
162 	"120", // 120
163 	"121", // 121
164 	"122", // 122
165 	"123", // 123
166 	"124", // 124
167 	"125", // 125
168 	"126", // 126
169 	"127", // 127
170 };
171 
172 qboolean warn_about_nehahra_protocol; //johnfitz
173 
174 extern vec3_t	v_punchangles[2]; //johnfitz
175 extern double	v_punchangles_times[2]; //spike -- don't assume 10fps...
176 
177 //=============================================================================
178 
179 /*
180 ===============
181 CL_EntityNum
182 
183 This error checks and tracks the total number of entities
184 ===============
185 */
CL_EntityNum(int num)186 entity_t	*CL_EntityNum (int num)
187 {
188 	//johnfitz -- check minimum number too
189 	if (num < 0)
190 		Host_Error ("CL_EntityNum: %i is an invalid number",num);
191 	//john
192 
193 	if (num >= cl.num_entities)
194 	{
195 		if (num >= cl.max_edicts) //johnfitz -- no more MAX_EDICTS
196 			Host_Error ("CL_EntityNum: %i is an invalid number",num);
197 		while (cl.num_entities<=num)
198 		{
199 			cl.entities[cl.num_entities].baseline = nullentitystate;
200 			cl.entities[cl.num_entities].lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; //johnfitz
201 			cl.num_entities++;
202 		}
203 	}
204 
205 	return &cl.entities[num];
206 }
207 
MSG_ReadSize16(sizebuf_t * sb)208 static int MSG_ReadSize16 (sizebuf_t *sb)
209 {
210 	unsigned short ssolid = MSG_ReadShort();
211 	if (ssolid == ES_SOLID_BSP)
212 		return ssolid;
213 	else
214 	{
215 		int solid = (((ssolid>>7) & 0x1F8) - 32+32768)<<16;	/*up can be negative*/
216 		solid|= ((ssolid & 0x1F)<<3);
217 		solid|= ((ssolid & 0x3E0)<<10);
218 		return solid;
219 	}
220 }
CLFTE_ReadDelta(unsigned int entnum,entity_state_t * news,const entity_state_t * olds,const entity_state_t * baseline)221 static unsigned int CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, const entity_state_t *olds, const entity_state_t *baseline)
222 {
223 	unsigned int predbits = 0;
224 	unsigned int bits;
225 
226 	bits = MSG_ReadByte();
227 	if (bits & UF_EXTEND1)
228 		bits |= MSG_ReadByte()<<8;
229 	if (bits & UF_EXTEND2)
230 		bits |= MSG_ReadByte()<<16;
231 	if (bits & UF_EXTEND3)
232 		bits |= MSG_ReadByte()<<24;
233 
234 	if (cl_shownet.value >= 3)
235 		Con_SafePrintf("%3i:     Update %4i 0x%x\n", msg_readcount, entnum, bits);
236 
237 	if (bits & UF_RESET)
238 	{
239 //		Con_Printf("%3i: Reset %i @ %i\n", msg_readcount, entnum, cls.netchan.incoming_sequence);
240 		*news = *baseline;
241 	}
242 	else if (!olds)
243 	{
244 		/*reset got lost, probably the data will be filled in later - FIXME: we should probably ignore this entity*/
245 		if (sv.active)
246 		{	//for extra debug info
247 			qcvm_t *old = qcvm;
248 			qcvm = NULL;
249 			PR_SwitchQCVM(&sv.qcvm);
250 			Con_DPrintf("New entity %i(%s / %s) without reset\n", entnum, PR_GetString(EDICT_NUM(entnum)->v.classname), PR_GetString(EDICT_NUM(entnum)->v.model));
251 			PR_SwitchQCVM(old);
252 		}
253 		else
254 			Con_DPrintf("New entity %i without reset\n", entnum);
255 		*news = nullentitystate;
256 	}
257 	else
258 		*news = *olds;
259 
260 	if (bits & UF_FRAME)
261 	{
262 		if (bits & UF_16BIT)
263 			news->frame = MSG_ReadShort();
264 		else
265 			news->frame = MSG_ReadByte();
266 	}
267 
268 	if (bits & UF_ORIGINXY)
269 	{
270 		news->origin[0] = MSG_ReadCoord(cl.protocolflags);
271 		news->origin[1] = MSG_ReadCoord(cl.protocolflags);
272 	}
273 	if (bits & UF_ORIGINZ)
274 		news->origin[2] = MSG_ReadCoord(cl.protocolflags);
275 
276 	if ((bits & UF_PREDINFO) && !(cl.protocol_pext2 & PEXT2_PREDINFO))
277 	{
278 		//predicted stuff gets more precise angles
279 		if (bits & UF_ANGLESXZ)
280 		{
281 			news->angles[0] = MSG_ReadAngle16(cl.protocolflags);
282 			news->angles[2] = MSG_ReadAngle16(cl.protocolflags);
283 		}
284 		if (bits & UF_ANGLESY)
285 			news->angles[1] = MSG_ReadAngle16(cl.protocolflags);
286 	}
287 	else
288 	{
289 		if (bits & UF_ANGLESXZ)
290 		{
291 			news->angles[0] = MSG_ReadAngle(cl.protocolflags);
292 			news->angles[2] = MSG_ReadAngle(cl.protocolflags);
293 		}
294 		if (bits & UF_ANGLESY)
295 			news->angles[1] = MSG_ReadAngle(cl.protocolflags);
296 	}
297 
298 	if ((bits & (UF_EFFECTS | UF_EFFECTS2)) == (UF_EFFECTS | UF_EFFECTS2))
299 		news->effects = MSG_ReadLong();
300 	else if (bits & UF_EFFECTS2)
301 		news->effects = (unsigned short)MSG_ReadShort();
302 	else if (bits & UF_EFFECTS)
303 		news->effects = MSG_ReadByte();
304 
305 //	news->movement[0] = 0;
306 //	news->movement[1] = 0;
307 //	news->movement[2] = 0;
308 	news->velocity[0] = 0;
309 	news->velocity[1] = 0;
310 	news->velocity[2] = 0;
311 	if (bits & UF_PREDINFO)
312 	{
313 		predbits = MSG_ReadByte();
314 
315 		if (predbits & UFP_FORWARD)
316 			/*news->movement[0] =*/ MSG_ReadShort();
317 		//else
318 		//	news->movement[0] = 0;
319 		if (predbits & UFP_SIDE)
320 			/*news->movement[1] =*/ MSG_ReadShort();
321 		//else
322 		//	news->movement[1] = 0;
323 		if (predbits & UFP_UP)
324 			/*news->movement[2] =*/ MSG_ReadShort();
325 		//else
326 		//	news->movement[2] = 0;
327 		if (predbits & UFP_MOVETYPE)
328 			news->pmovetype = MSG_ReadByte();
329 		if (predbits & UFP_VELOCITYXY)
330 		{
331 			news->velocity[0] = MSG_ReadShort();
332 			news->velocity[1] = MSG_ReadShort();
333 		}
334 		else
335 		{
336 			news->velocity[0] = 0;
337 			news->velocity[1] = 0;
338 		}
339 		if (predbits & UFP_VELOCITYZ)
340 			news->velocity[2] = MSG_ReadShort();
341 		else
342 			news->velocity[2] = 0;
343 		if (predbits & UFP_MSEC)	//the msec value is how old the update is (qw clients normally predict without the server running an update every frame)
344 			/*news->msec =*/ MSG_ReadByte();
345 		//else
346 		//	news->msec = 0;
347 
348 		if (cl.protocol_pext2 & PEXT2_PREDINFO)
349 		{
350 			if (predbits & UFP_VIEWANGLE)
351 			{
352 				if (bits & UF_ANGLESXZ)
353 				{
354 					/*news->vangle[0] =*/ MSG_ReadShort();
355 					/*news->vangle[2] =*/ MSG_ReadShort();
356 				}
357 				if (bits & UF_ANGLESY)
358 					/*news->vangle[1] =*/ MSG_ReadShort();
359 			}
360 		}
361 		else
362 		{
363 			if (predbits & UFP_WEAPONFRAME_OLD)
364 			{
365 				int wframe;
366 				wframe = MSG_ReadByte();
367 				if (wframe & 0x80)
368 					wframe = (wframe & 127) | (MSG_ReadByte()<<7);
369 			}
370 		}
371 	}
372 	else
373 	{
374 		//news->msec = 0;
375 	}
376 
377 	if (!(predbits & UFP_VIEWANGLE) || !(cl.protocol_pext2 & PEXT2_PREDINFO))
378 	{/*
379 		if (bits & UF_ANGLESXZ)
380 			news->vangle[0] = ANGLE2SHORT(news->angles[0] * ((bits & UF_PREDINFO)?-3:-1));
381 		if (bits & UF_ANGLESY)
382 			news->vangle[1] = ANGLE2SHORT(news->angles[1]);
383 		if (bits & UF_ANGLESXZ)
384 			news->vangle[2] = ANGLE2SHORT(news->angles[2]);
385 		*/
386 	}
387 
388 	if (bits & UF_MODEL)
389 	{
390 		if (bits & UF_16BIT)
391 			news->modelindex = MSG_ReadShort();
392 		else
393 			news->modelindex = MSG_ReadByte();
394 	}
395 	if (bits & UF_SKIN)
396 	{
397 		if (bits & UF_16BIT)
398 			news->skin = MSG_ReadShort();
399 		else
400 			news->skin = MSG_ReadByte();
401 	}
402 	if (bits & UF_COLORMAP)
403 		news->colormap = MSG_ReadByte();
404 
405 	if (bits & UF_SOLID)
406 		/*news->solidsize =*/ MSG_ReadSize16(&net_message);
407 
408 	if (bits & UF_FLAGS)
409 		news->eflags = MSG_ReadByte();
410 
411 	if (bits & UF_ALPHA)
412 		news->alpha = (MSG_ReadByte()+1)&0xff;
413 	if (bits & UF_SCALE)
414 		news->scale = MSG_ReadByte();
415 	if (bits & UF_BONEDATA)
416 	{
417 		unsigned char fl = MSG_ReadByte();
418 		if (fl & 0x80)
419 		{
420 			//this is NOT finalized
421 			int i;
422 			int bonecount = MSG_ReadByte();
423 			//short *bonedata = AllocateBoneSpace(newp, bonecount, &news->boneoffset);
424 			for (i = 0; i < bonecount*7; i++)
425 				/*bonedata[i] =*/ MSG_ReadShort();
426 			//news->bonecount = bonecount;
427 		}
428 		//else
429 			//news->bonecount = 0;	//oo, it went away.
430 		if (fl & 0x40)
431 		{
432 			/*news->basebone =*/ MSG_ReadByte();
433 			/*news->baseframe =*/ MSG_ReadShort();
434 		}
435 		/*else
436 		{
437 			news->basebone = 0;
438 			news->baseframe = 0;
439 		}*/
440 
441 		//fixme: basebone, baseframe, etc.
442 		if (fl & 0x3f)
443 			Host_EndGame("unsupported entity delta info\n");
444 	}
445 //	else if (news->bonecount)
446 //	{	//still has bone data from the previous frame.
447 //		short *bonedata = AllocateBoneSpace(newp, news->bonecount, &news->boneoffset);
448 //		memcpy(bonedata, oldp->bonedata+olds->boneoffset, sizeof(short)*7*news->bonecount);
449 //	}
450 
451 	if (bits & UF_DRAWFLAGS)
452 	{
453 		int drawflags = MSG_ReadByte();
454 		if ((drawflags & /*MLS_MASK*/7) == /*MLS_ABSLIGHT*/7)
455 			/*news->abslight =*/ MSG_ReadByte();
456 		//else
457 		//	news->abslight = 0;
458 		//news->drawflags = drawflags;
459 	}
460 	if (bits & UF_TAGINFO)
461 	{
462 		news->tagentity = MSG_ReadEntity(cl.protocol_pext2);
463 		news->tagindex = MSG_ReadByte();
464 	}
465 	if (bits & UF_LIGHT)
466 	{
467 		/*news->light[0] =*/ MSG_ReadShort();
468 		/*news->light[1] =*/ MSG_ReadShort();
469 		/*news->light[2] =*/ MSG_ReadShort();
470 		/*news->light[3] =*/ MSG_ReadShort();
471 		/*news->lightstyle =*/ MSG_ReadByte();
472 		/*news->lightpflags =*/ MSG_ReadByte();
473 	}
474 	if (bits & UF_TRAILEFFECT)
475 	{
476 		unsigned short v = MSG_ReadShort();
477 		/*news->emiteffectnum = 0;*/
478 		/*news->traileffectnum = v & 0x3fff;*/
479 		if (v & 0x8000)
480 			/*news->emiteffectnum = */MSG_ReadShort() /*& 0x3fff*/;
481 		/*if (news->traileffectnum >= MAX_PARTICLETYPES)
482 			news->traileffectnum = 0;
483 		if (news->emiteffectnum >= MAX_PARTICLETYPES)
484 			news->emiteffectnum = 0;*/
485 	}
486 
487 	if (bits & UF_COLORMOD)
488 	{
489 		news->colormod[0] = MSG_ReadByte();
490 		news->colormod[1] = MSG_ReadByte();
491 		news->colormod[2] = MSG_ReadByte();
492 	}
493 	if (bits & UF_GLOW)
494 	{
495 		/*news->glowsize =*/ MSG_ReadByte();
496 		/*news->glowcolour =*/ MSG_ReadByte();
497 		/*news->glowmod[0] =*/ MSG_ReadByte();
498 		/*news->glowmod[1] =*/ MSG_ReadByte();
499 		/*news->glowmod[2] =*/ MSG_ReadByte();
500 	}
501 	if (bits & UF_FATNESS)
502 		/*news->fatness =*/ MSG_ReadByte();
503 	if (bits & UF_MODELINDEX2)
504 	{
505 		if (bits & UF_16BIT)
506 			/*news->modelindex2 =*/ MSG_ReadShort();
507 		else
508 			/*news->modelindex2 =*/ MSG_ReadByte();
509 	}
510 	if (bits & UF_GRAVITYDIR)
511 	{
512 		/*news->gravitydir[0] =*/ MSG_ReadByte();
513 		/*news->gravitydir[1] =*/ MSG_ReadByte();
514 	}
515 	if (bits & UF_UNUSED2)
516 	{
517 		Host_EndGame("UF_UNUSED2 bit\n");
518 	}
519 	if (bits & UF_UNUSED1)
520 	{
521 		Host_EndGame("UF_UNUSED1 bit\n");
522 	}
523 	return bits;
524 }
CLFTE_ParseBaseline(entity_state_t * es)525 static void CLFTE_ParseBaseline(entity_state_t *es)
526 {
527 	CLFTE_ReadDelta(0, es, &nullentitystate, &nullentitystate);
528 }
529 
530 //called with both fte+dp deltas
CL_EntitiesDeltaed(void)531 static void CL_EntitiesDeltaed(void)
532 {
533 	int			newnum;
534 	qmodel_t	*model;
535 	qboolean	forcelink;
536 	entity_t	*ent;
537 	int			skin;
538 
539 	for (newnum = 1; newnum < cl.num_entities; newnum++)
540 	{
541 		ent = CL_EntityNum(newnum);
542 		if (!ent->update_type)
543 			continue;	//not interested in this one
544 
545 		if (ent->msgtime == cl.mtime[0])
546 			forcelink = false;	//update got fragmented, don't dirty anything.
547 		else
548 		{
549 			if (ent->msgtime != cl.mtime[1])
550 				forcelink = true;	// no previous frame to lerp from
551 			else
552 				forcelink = false;
553 
554 			//johnfitz -- lerping
555 			if (ent->msgtime + 0.2 < cl.mtime[0]) //more than 0.2 seconds since the last message (most entities think every 0.1 sec)
556 				ent->lerpflags |= LERP_RESETANIM; //if we missed a think, we'd be lerping from the wrong frame
557 
558 			ent->msgtime = cl.mtime[0];
559 
560 		// shift the known values for interpolation
561 			VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
562 			VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
563 
564 			VectorCopy (ent->netstate.origin, ent->msg_origins[0]);
565 			VectorCopy (ent->netstate.angles, ent->msg_angles[0]);
566 		}
567 		skin = ent->netstate.skin;
568 		if (skin != ent->skinnum)
569 		{
570 			ent->skinnum = skin;
571 			if (newnum > 0 && newnum <= cl.maxclients)
572 				R_TranslateNewPlayerSkin (newnum - 1); //johnfitz -- was R_TranslatePlayerSkin
573 		}
574 		ent->effects = ent->netstate.effects;
575 
576 		//johnfitz -- lerping for movetype_step entities
577 		if (ent->netstate.eflags & EFLAGS_STEP)
578 		{
579 			ent->lerpflags |= LERP_MOVESTEP;
580 			ent->forcelink = true;
581 		}
582 		else
583 			ent->lerpflags &= ~LERP_MOVESTEP;
584 
585 		ent->alpha = ent->netstate.alpha;
586 		ent->lerpflags &= ~LERP_FINISH;
587 
588 		model = cl.model_precache[ent->netstate.modelindex];
589 		if (model != ent->model)
590 		{
591 			ent->model = model;
592 			InvalidateTraceLineCache();
593 
594 		// automatic animation (torches, etc) can be either all together
595 		// or randomized
596 			if (model)
597 			{
598 				if (model->synctype == ST_FRAMETIME)
599 					ent->syncbase = -cl.time;
600 				else if (model->synctype == ST_RAND)
601 					ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
602 				else
603 					ent->syncbase = 0.0;
604 			}
605 			else
606 				forcelink = true;	// hack to make null model players work
607 			if (newnum > 0 && newnum <= cl.maxclients)
608 				R_TranslateNewPlayerSkin (newnum - 1); //johnfitz -- was R_TranslatePlayerSkin
609 
610 			ent->lerpflags |= LERP_RESETANIM; //johnfitz -- don't lerp animation across model changes
611 		}
612 		else if (model && model->synctype == ST_FRAMETIME && ent->frame != ent->netstate.frame)
613 			ent->syncbase = -cl.time;
614 		ent->frame = ent->netstate.frame;
615 
616 		if ( forcelink )
617 		{	// didn't have an update last message
618 			VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
619 			VectorCopy (ent->msg_origins[0], ent->origin);
620 			VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
621 			VectorCopy (ent->msg_angles[0], ent->angles);
622 			ent->forcelink = true;
623 		}
624 	}
625 }
626 
CLFTE_ParseEntitiesUpdate(void)627 static void CLFTE_ParseEntitiesUpdate(void)
628 {
629 	int newnum;
630 	qboolean removeflag;
631 	entity_t *ent;
632 	float newtime;
633 
634 	//so the server can know when we got it, and guess which frames we didn't get
635 	if (cls.netcon && cl.ackframes_count < sizeof(cl.ackframes)/sizeof(cl.ackframes[0]))
636 		cl.ackframes[cl.ackframes_count++] = NET_QSocketGetSequenceIn(cls.netcon);
637 
638 	if (cl.protocol_pext2 & PEXT2_PREDINFO)
639 	{
640 		int seq = (cl.movemessages&0xffff0000) | (unsigned short)MSG_ReadShort();	//an ack from our input sequences. strictly ascending-or-equal
641 		if (seq > cl.movemessages)
642 			seq -= 0x10000;	//check for cl.movemessages overflowing the low 16 bits, and compensate.
643 		cl.ackedmovemessages = seq;
644 	}
645 
646 	newtime = MSG_ReadFloat ();
647 	if (newtime != cl.mtime[0])
648 	{	//don't mess up lerps if the server is splitting entities into multiple packets.
649 		cl.mtime[1] = cl.mtime[0];
650 		cl.mtime[0] = newtime;
651 	}
652 
653 	for (;;)
654 	{
655 		newnum = (unsigned short)(short)MSG_ReadShort();
656 		removeflag = !!(newnum & 0x8000);
657 		if (newnum & 0x4000)
658 			newnum = (newnum & 0x3fff) | (MSG_ReadByte()<<14);
659 		else
660 			newnum &= ~0x8000;
661 
662 		if ((!newnum && !removeflag) || msg_badread)
663 			break;
664 
665 		ent = CL_EntityNum(newnum);
666 
667 		if (removeflag)
668 		{	//removal.
669 			if (cl_shownet.value >= 3)
670 				Con_SafePrintf("%3i:     Remove %i\n", msg_readcount, newnum);
671 
672 			if (!newnum)
673 			{
674 				/*removal of world - means forget all entities, aka a full reset*/
675 				if (cl_shownet.value >= 3)
676 					Con_SafePrintf("%3i:     Reset all\n", msg_readcount);
677 				for (newnum = 1; newnum < cl.num_entities; newnum++)
678 				{
679 					CL_EntityNum(newnum)->netstate.pmovetype = 0;
680 					CL_EntityNum(newnum)->model = NULL;
681 				}
682 				cl.requestresend = false;	//we got it.
683 				continue;
684 			}
685 			ent->update_type = false; //no longer valid
686 			ent->model = NULL;
687 			InvalidateTraceLineCache();
688 			continue;
689 		}
690 		else if (ent->update_type)
691 		{	//simple update
692 			CLFTE_ReadDelta(newnum, &ent->netstate, &ent->netstate, &ent->baseline);
693 		}
694 		else
695 		{	//we had no previous copy of this entity...
696 			ent->update_type = true;
697 			CLFTE_ReadDelta(newnum, &ent->netstate, NULL, &ent->baseline);
698 
699 			//stupid interpolation junk.
700 			ent->lerpflags |= LERP_RESETMOVE|LERP_RESETANIM;
701 		}
702 	}
703 
704 	CL_EntitiesDeltaed();
705 
706 	if (cl.protocol_pext2 & PEXT2_PREDINFO)
707 	{	//stats should normally be sent before the entity data.
708 		extern cvar_t v_gunkick;
709 		VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
710 		ent = CL_EntityNum(cl.viewentity);
711 		cl.mvelocity[0][0] = ent->netstate.velocity[0]*(1/8.0);
712 		cl.mvelocity[0][1] = ent->netstate.velocity[1]*(1/8.0);
713 		cl.mvelocity[0][2] = ent->netstate.velocity[2]*(1/8.0);
714 		cl.onground = (ent->netstate.eflags & EFLAGS_ONGROUND)?true:false;
715 
716 
717 		if (v_gunkick.value == 1)
718 		{	//truncate away any extra precision, like vanilla/qs would.
719 			cl.punchangle[0] = cl.stats[STAT_PUNCHANGLE_X];
720 			cl.punchangle[1] = cl.stats[STAT_PUNCHANGLE_Y];
721 			cl.punchangle[2] = cl.stats[STAT_PUNCHANGLE_Z];
722 		}
723 		else
724 		{	//woo, more precision
725 			cl.punchangle[0] = cl.statsf[STAT_PUNCHANGLE_X];
726 			cl.punchangle[1] = cl.statsf[STAT_PUNCHANGLE_Y];
727 			cl.punchangle[2] = cl.statsf[STAT_PUNCHANGLE_Z];
728 		}
729 		if (v_punchangles[0][0] != cl.punchangle[0] || v_punchangles[0][1] != cl.punchangle[1] || v_punchangles[0][2] != cl.punchangle[2])
730 		{
731 			v_punchangles_times[1] = v_punchangles_times[0];
732 			v_punchangles_times[0] = newtime;
733 
734 			VectorCopy (v_punchangles[0], v_punchangles[1]);
735 			VectorCopy (cl.punchangle, v_punchangles[0]);
736 		}
737 	}
738 
739 	if (!cl.requestresend)
740 	{
741 		if (cls.signon == SIGNONS - 1)
742 		{	// first update is the final signon stage
743 			cls.signon = SIGNONS;
744 			CL_SignonReply ();
745 		}
746 	}
747 }
748 
749 /*
750 ==================
751 CL_ParseStartSoundPacket
752 ==================
753 */
CL_ParseStartSoundPacket(void)754 static void CL_ParseStartSoundPacket(void)
755 {
756 	vec3_t	pos;
757 	int	channel, ent;
758 	int	sound_num;
759 	int	volume;
760 	int	field_mask;
761 	float	attenuation;
762 	int	i;
763 
764 	field_mask = MSG_ReadByte();
765 	if (field_mask & SND_FTE_MOREFLAGS)
766 		field_mask |= MSG_ReadByte()<<8;
767 
768 	if (field_mask & SND_VOLUME)
769 		volume = MSG_ReadByte ();
770 	else
771 		volume = DEFAULT_SOUND_PACKET_VOLUME;
772 
773 	if (field_mask & SND_ATTENUATION)
774 		attenuation = MSG_ReadByte () / 64.0;
775 	else
776 		attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
777 
778 	//fte's sound extensions
779 	if (cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS)
780 	{
781 		//spike -- our mixer can't deal with these, so just parse and ignore
782 		if (field_mask & SND_FTE_PITCHADJ)
783 			MSG_ReadByte();	//percentage
784 		if (field_mask & SND_FTE_TIMEOFS)
785 			MSG_ReadShort(); //in ms
786 		if (field_mask & SND_FTE_VELOCITY)
787 		{
788 			MSG_ReadShort(); //1/8th
789 			MSG_ReadShort(); //1/8th
790 			MSG_ReadShort(); //1/8th
791 		}
792 	}
793 	else if (field_mask & (SND_FTE_MOREFLAGS|SND_FTE_PITCHADJ|SND_FTE_TIMEOFS))
794 		Con_Warning("Unknown meaning for sound flags\n");
795 	if (cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS)
796 	{
797 		if (field_mask & SND_DP_PITCH)
798 			MSG_ReadShort();
799 	}
800 	else if (field_mask & SND_DP_PITCH)
801 		Con_Warning("Unknown meaning for sound flags\n");
802 
803 	//johnfitz -- PROTOCOL_FITZQUAKE
804 	if (field_mask & SND_LARGEENTITY)
805 	{
806 		ent = (unsigned short) MSG_ReadShort ();
807 		channel = MSG_ReadByte ();
808 	}
809 	else
810 	{
811 		channel = (unsigned short) MSG_ReadShort ();
812 		ent = channel >> 3;
813 		channel &= 7;
814 	}
815 
816 	if (field_mask & SND_LARGESOUND)
817 		sound_num = (unsigned short) MSG_ReadShort ();
818 	else
819 		sound_num = MSG_ReadByte ();
820 	//johnfitz
821 
822 	//johnfitz -- check soundnum
823 	if (sound_num >= MAX_SOUNDS)
824 		Host_Error ("CL_ParseStartSoundPacket: %i > MAX_SOUNDS", sound_num);
825 	//johnfitz
826 
827 	if (ent > cl.max_edicts) //johnfitz -- no more MAX_EDICTS
828 		Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
829 
830 	for (i = 0; i < 3; i++)
831 		pos[i] = MSG_ReadCoord (cl.protocolflags);
832 
833 	S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
834 }
835 
836 #if 0
837 /*
838 ==================
839 CL_KeepaliveMessage
840 
841 When the client is taking a long time to load stuff, send keepalive messages
842 so the server doesn't disconnect.
843 ==================
844 */
845 static byte	net_olddata[NET_MAXMESSAGE];
846 static void CL_KeepaliveMessage (void)
847 {
848 	float	time;
849 	static float lastmsg;
850 	int		ret;
851 	sizebuf_t	old;
852 	byte	*olddata;
853 
854 	if (sv.active)
855 		return;		// no need if server is local
856 	if (cls.demoplayback)
857 		return;
858 
859 // read messages from server, should just be nops
860 	olddata = net_olddata;
861 	old = net_message;
862 	memcpy (olddata, net_message.data, net_message.cursize);
863 
864 	do
865 	{
866 		ret = CL_GetMessage ();
867 		switch (ret)
868 		{
869 		default:
870 			Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
871 		case 0:
872 			break;	// nothing waiting
873 		case 1:
874 			Host_Error ("CL_KeepaliveMessage: received a message");
875 			break;
876 		case 2:
877 			if (MSG_ReadByte() != svc_nop)
878 				Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
879 			break;
880 		}
881 	} while (ret);
882 
883 	net_message = old;
884 	memcpy (net_message.data, olddata, net_message.cursize);
885 
886 // check time
887 	time = Sys_DoubleTime ();
888 	if (time - lastmsg < 5)
889 		return;
890 	lastmsg = time;
891 
892 // write out a nop
893 	Con_Printf ("--> client to server keepalive\n");
894 
895 	MSG_WriteByte (&cls.message, clc_nop);
896 	NET_SendMessage (cls.netcon, &cls.message);
897 	SZ_Clear (&cls.message);
898 }
899 #endif
900 
901 /*
902 ==================
903 CL_ParseServerInfo
904 ==================
905 */
CL_ParseServerInfo(void)906 static void CL_ParseServerInfo (void)
907 {
908 	const char	*str;
909 	int		i;
910 	qboolean	gamedirswitchwarning = false;
911 	char gamedir[1024];
912 	char protname[64];
913 	int		nummodels, numsounds;
914 	char	model_precache[MAX_MODELS][MAX_QPATH];
915 	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
916 
917 	Con_DPrintf ("Serverinfo packet received.\n");
918 
919 // ericw -- bring up loading plaque for map changes within a demo.
920 //          it will be hidden in CL_SignonReply.
921 	if (cls.demoplayback)
922 		SCR_BeginLoadingPlaque();
923 
924 //
925 // wipe the client_state_t struct
926 //
927 	CL_ClearState ();
928 
929 // parse protocol version number
930 	for(;;)
931 	{
932 		i = MSG_ReadLong ();
933 		if (i == PROTOCOL_FTE_PEXT1)
934 		{
935 			cl.protocol_pext1 = MSG_ReadLong();
936 			if (cl.protocol_pext1& ~PEXT1_ACCEPTED_CLIENT)
937 				Host_Error ("Server returned FTE1 protocol extensions that are not supported (%#x)", cl.protocol_pext1 & ~PEXT1_SUPPORTED_CLIENT);
938 			continue;
939 		}
940 		if (i == PROTOCOL_FTE_PEXT2)
941 		{
942 			cl.protocol_pext2 = MSG_ReadLong();
943 			if (cl.protocol_pext2 & ~PEXT2_ACCEPTED_CLIENT)
944 				Host_Error ("Server returned FTE2 protocol extensions that are not supported (%#x)", cl.protocol_pext2 & ~PEXT2_SUPPORTED_CLIENT);
945 			continue;
946 		}
947 		break;
948 	}
949 
950 	//johnfitz -- support multiple protocols
951 	if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE && i != PROTOCOL_RMQ) {
952 		Con_Printf ("\n"); //because there's no newline after serverinfo print
953 		Host_Error ("Server returned version %i, not %i or %i or %i", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE, PROTOCOL_RMQ);
954 	}
955 	cl.protocol = i;
956 	//johnfitz
957 
958 	if (cl.protocol == PROTOCOL_RMQ)
959 	{
960 		const unsigned int supportedflags = (PRFL_SHORTANGLE | PRFL_FLOATANGLE | PRFL_24BITCOORD | PRFL_FLOATCOORD | PRFL_EDICTSCALE | PRFL_INT32COORD);
961 
962 		// mh - read protocol flags from server so that we know what protocol features to expect
963 		cl.protocolflags = (unsigned int) MSG_ReadLong ();
964 
965 		if (0 != (cl.protocolflags & (~supportedflags)))
966 		{
967 			Con_Warning("PROTOCOL_RMQ protocolflags %i contains unsupported flags\n", cl.protocolflags);
968 		}
969 	}
970 	else cl.protocolflags = 0;
971 
972 	*gamedir = 0;
973 	if (cl.protocol_pext2 & PEXT2_PREDINFO)
974 	{
975 		q_strlcpy(gamedir, MSG_ReadString(), sizeof(gamedir));
976 		if (!COM_GameDirMatches(gamedir))
977 		{
978 			gamedirswitchwarning = true;
979 		}
980 	}
981 	(void) gamedirswitchwarning;/* variable set but not used */
982 
983 // parse maxclients
984 	cl.maxclients = MSG_ReadByte ();
985 	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
986 	{
987 		Host_Error ("Bad maxclients (%u) from server", cl.maxclients);
988 	}
989 	cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
990 
991 // parse gametype
992 	cl.gametype = MSG_ReadByte ();
993 
994 // parse signon message
995 	str = MSG_ReadString ();
996 	q_strlcpy (cl.levelname, str, sizeof(cl.levelname));
997 
998 // seperate the printfs so the server message can have a color
999 	Con_Printf ("\n%s\n", Con_Quakebar(40)); //johnfitz
1000 	Con_Printf ("%c%s\n", 2, str);
1001 
1002 //johnfitz -- tell user which protocol this is
1003 	if (cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS)
1004 		q_snprintf(protname, sizeof(protname), "fte%i", cl.protocol);
1005 	else
1006 		q_snprintf(protname, sizeof(protname), "%i", cl.protocol);
1007 	Con_Printf ("Using protocol %s", protname);
1008 	Con_Printf ("\n");
1009 
1010 // first we go through and touch all of the precache data that still
1011 // happens to be in the cache, so precaching something else doesn't
1012 // needlessly purge it
1013 
1014 // precache models
1015 	memset (cl.model_precache, 0, sizeof(cl.model_precache));
1016 	for (nummodels = 1 ; ; nummodels++)
1017 	{
1018 		str = MSG_ReadString ();
1019 		if (!str[0])
1020 			break;
1021 		if (nummodels==MAX_MODELS)
1022 		{
1023 			Host_Error ("Server sent too many model precaches");
1024 		}
1025 		q_strlcpy (model_precache[nummodels], str, MAX_QPATH);
1026 		Mod_TouchModel (str);
1027 	}
1028 
1029 	//johnfitz -- check for excessive models
1030 	if (nummodels >= 256)
1031 		Con_DWarning ("%i models exceeds standard limit of 256 (max = %d).\n", nummodels, MAX_MODELS);
1032 	//johnfitz
1033 
1034 // precache sounds
1035 	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
1036 	for (numsounds = 1 ; ; numsounds++)
1037 	{
1038 		str = MSG_ReadString ();
1039 		if (!str[0])
1040 			break;
1041 		if (numsounds==MAX_SOUNDS)
1042 		{
1043 			Host_Error ("Server sent too many sound precaches");
1044 		}
1045 		q_strlcpy (sound_precache[numsounds], str, MAX_QPATH);
1046 		S_TouchSound (str);
1047 	}
1048 
1049 	//johnfitz -- check for excessive sounds
1050 	if (numsounds >= 256)
1051 		Con_DWarning ("%i sounds exceeds standard limit of 256 (max = %d).\n", numsounds, MAX_SOUNDS);
1052 	//johnfitz
1053 
1054 //
1055 // now we try to load everything else until a cache allocation fails
1056 //
1057 
1058 	// copy the naked name of the map file to the cl structure -- O.S
1059 	COM_StripExtension (COM_SkipPath(model_precache[1]), cl.mapname, sizeof(cl.mapname));
1060 
1061 	for (i = 1; i < nummodels; i++)
1062 	{
1063 		cl.model_precache[i] = Mod_ForName (model_precache[i], false);
1064 		if (cl.model_precache[i] == NULL)
1065 		{
1066 			Host_Error ("Model %s not found", model_precache[i]);
1067 		}
1068 	}
1069 	S_BeginPrecaching ();
1070 	for (i = 1; i < numsounds; i++)
1071 	{
1072 		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
1073 	}
1074 	S_EndPrecaching ();
1075 
1076 // local state
1077 	cl.entities[0].model = cl.worldmodel = cl.model_precache[1];
1078 
1079 	R_NewMap ();
1080 
1081 	//johnfitz -- clear out string; we don't consider identical
1082 	//messages to be duplicates if the map has changed in between
1083 	con_lastcenterstring[0] = 0;
1084 	//johnfitz
1085 
1086 	Hunk_Check ();		// make sure nothing is hurt
1087 
1088 	noclip_anglehack = false;		// noclip is turned off at start
1089 
1090 	warn_about_nehahra_protocol = true; //johnfitz -- warn about nehahra protocol hack once per server connection
1091 
1092 //johnfitz -- reset developer stats
1093 	memset(&dev_stats, 0, sizeof(dev_stats));
1094 	memset(&dev_peakstats, 0, sizeof(dev_peakstats));
1095 	memset(&dev_overflows, 0, sizeof(dev_overflows));
1096 
1097 	cl.requestresend = true;
1098 	cl.ackframes_count = 0;
1099 	if (cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS)
1100 		cl.ackframes[cl.ackframes_count++] = -1;
1101 #ifdef PSET_SCRIPT
1102 		//the protocol changing depending upon files found on the client's computer is of course a really shit way to design things
1103 		//especially when users have a nasty habit of changing config files.
1104 		if (cl.protocol_pext2 || (cl.protocol_pext1&PEXT1_CSQC))
1105 			cl.protocol_particles = true;	//doesn't have a pext flag of its own, but at least we know what it is.
1106 #endif
1107 }
1108 
1109 /*
1110 ==================
1111 CL_ParseUpdate
1112 
1113 Parse an entity update message from the server
1114 If an entities model or origin changes from frame to frame, it must be
1115 relinked.  Other attributes can change without relinking.
1116 ==================
1117 */
CL_ParseUpdate(int bits)1118 static void CL_ParseUpdate (int bits)
1119 {
1120 	int		i;
1121 	qmodel_t	*model;
1122 	unsigned int	modnum;
1123 	qboolean	forcelink;
1124 	entity_t	*ent;
1125 	int		num;
1126 	int		skin;
1127 
1128 	if (cls.signon == SIGNONS - 1)
1129 	{	// first update is the final signon stage
1130 		cls.signon = SIGNONS;
1131 		CL_SignonReply ();
1132 	}
1133 
1134 	if (bits & U_MOREBITS)
1135 	{
1136 		i = MSG_ReadByte ();
1137 		bits |= (i<<8);
1138 	}
1139 
1140 	//johnfitz -- PROTOCOL_FITZQUAKE
1141 	if (cl.protocol == PROTOCOL_FITZQUAKE || cl.protocol == PROTOCOL_RMQ)
1142 	{
1143 		if (bits & U_EXTEND1)
1144 			bits |= MSG_ReadByte() << 16;
1145 		if (bits & U_EXTEND2)
1146 			bits |= MSG_ReadByte() << 24;
1147 	}
1148 	//johnfitz
1149 
1150 	if (bits & U_LONGENTITY)
1151 		num = MSG_ReadShort ();
1152 	else
1153 		num = MSG_ReadByte ();
1154 
1155 	ent = CL_EntityNum (num);
1156 
1157 	if (ent->msgtime != cl.mtime[1])
1158 		forcelink = true;	// no previous frame to lerp from
1159 	else
1160 		forcelink = false;
1161 
1162 	//johnfitz -- lerping
1163 	if (ent->msgtime + 0.2 < cl.mtime[0]) //more than 0.2 seconds since the last message (most entities think every 0.1 sec)
1164 		ent->lerpflags |= LERP_RESETANIM; //if we missed a think, we'd be lerping from the wrong frame
1165 	//johnfitz
1166 
1167 	ent->msgtime = cl.mtime[0];
1168 
1169 	//copy the baseline into the netstate for the rest of the code to use.
1170 #define netstate_start offsetof(entity_state_t, scale)
1171 	memcpy((char*)&ent->netstate + offsetof(entity_state_t, modelindex), (const char*)&ent->baseline + offsetof(entity_state_t, modelindex), sizeof(ent->baseline) - offsetof(entity_state_t, modelindex));
1172 
1173 	if (bits & U_MODEL)
1174 	{
1175 		modnum = MSG_ReadByte ();
1176 		if (modnum >= MAX_MODELS)
1177 			Host_Error ("CL_ParseModel: bad modnum");
1178 	}
1179 	else
1180 		modnum = ent->baseline.modelindex;
1181 
1182 	if (bits & U_FRAME)
1183 		ent->frame = MSG_ReadByte ();
1184 	else
1185 		ent->frame = ent->baseline.frame;
1186 
1187 	if (bits & U_COLORMAP)
1188 		ent->netstate.colormap = MSG_ReadByte();
1189 	if (bits & U_SKIN)
1190 		skin = MSG_ReadByte();
1191 	else
1192 		skin = ent->baseline.skin;
1193 	if (skin != ent->skinnum)
1194 	{
1195 		ent->skinnum = skin;
1196 		if (num > 0 && num <= cl.maxclients)
1197 			R_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin
1198 	}
1199 	if (bits & U_EFFECTS)
1200 		ent->effects = MSG_ReadByte();
1201 	else
1202 		ent->effects = ent->baseline.effects;
1203 
1204 // shift the known values for interpolation
1205 	VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
1206 	VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
1207 
1208 	if (bits & U_ORIGIN1)
1209 		ent->msg_origins[0][0] = MSG_ReadCoord (cl.protocolflags);
1210 	else
1211 		ent->msg_origins[0][0] = ent->baseline.origin[0];
1212 	if (bits & U_ANGLE1)
1213 		ent->msg_angles[0][0] = MSG_ReadAngle(cl.protocolflags);
1214 	else
1215 		ent->msg_angles[0][0] = ent->baseline.angles[0];
1216 
1217 	if (bits & U_ORIGIN2)
1218 		ent->msg_origins[0][1] = MSG_ReadCoord (cl.protocolflags);
1219 	else
1220 		ent->msg_origins[0][1] = ent->baseline.origin[1];
1221 	if (bits & U_ANGLE2)
1222 		ent->msg_angles[0][1] = MSG_ReadAngle(cl.protocolflags);
1223 	else
1224 		ent->msg_angles[0][1] = ent->baseline.angles[1];
1225 
1226 	if (bits & U_ORIGIN3)
1227 		ent->msg_origins[0][2] = MSG_ReadCoord (cl.protocolflags);
1228 	else
1229 		ent->msg_origins[0][2] = ent->baseline.origin[2];
1230 	if (bits & U_ANGLE3)
1231 		ent->msg_angles[0][2] = MSG_ReadAngle(cl.protocolflags);
1232 	else
1233 		ent->msg_angles[0][2] = ent->baseline.angles[2];
1234 
1235 	//johnfitz -- lerping for movetype_step entities
1236 	if (bits & U_STEP)
1237 	{
1238 		ent->lerpflags |= LERP_MOVESTEP;
1239 		ent->forcelink = true;
1240 	}
1241 	else
1242 		ent->lerpflags &= ~LERP_MOVESTEP;
1243 	//johnfitz
1244 
1245 	//johnfitz -- PROTOCOL_FITZQUAKE and PROTOCOL_NEHAHRA
1246 	if (cl.protocol == PROTOCOL_FITZQUAKE || cl.protocol == PROTOCOL_RMQ)
1247 	{
1248 		if (bits & U_ALPHA)
1249 			ent->alpha = MSG_ReadByte();
1250 		else
1251 			ent->alpha = ent->baseline.alpha;
1252 		if (bits & U_SCALE)
1253 			ent->netstate.scale = MSG_ReadByte(); // PROTOCOL_RMQ
1254 		if (bits & U_FRAME2)
1255 			ent->frame = (ent->frame & 0x00FF) | (MSG_ReadByte() << 8);
1256 		if (bits & U_MODEL2)
1257 		{
1258 			modnum = (modnum & 0x00FF) | (MSG_ReadByte() << 8);
1259 			if (modnum >= MAX_MODELS)
1260 				Host_Error ("CL_ParseModel: bad modnum");
1261 		}
1262 		if (bits & U_LERPFINISH)
1263 		{
1264 			ent->lerpfinish = ent->msgtime + ((float)(MSG_ReadByte()) / 255);
1265 			ent->lerpflags |= LERP_FINISH;
1266 		}
1267 		else
1268 			ent->lerpflags &= ~LERP_FINISH;
1269 	}
1270 	else if (cl.protocol == PROTOCOL_NETQUAKE)
1271 	{
1272 		//HACK: if this bit is set, assume this is PROTOCOL_NEHAHRA
1273 		if (bits & U_TRANS)
1274 		{
1275 			float a, b;
1276 
1277 			if (cl.protocol == PROTOCOL_NETQUAKE && warn_about_nehahra_protocol)
1278 			{
1279 				Con_Warning ("nonstandard update bit, assuming Nehahra protocol\n");
1280 				warn_about_nehahra_protocol = false;
1281 			}
1282 
1283 			a = MSG_ReadFloat();
1284 			b = MSG_ReadFloat(); //alpha
1285 			if (a == 2)
1286 				MSG_ReadFloat(); //fullbright (not using this yet)
1287 			ent->alpha = ENTALPHA_ENCODE(b);
1288 		}
1289 		else
1290 			ent->alpha = ent->baseline.alpha;
1291 	}
1292 	else
1293 		ent->alpha = ent->baseline.alpha;
1294 	//johnfitz
1295 
1296 	//johnfitz -- moved here from above
1297 	model = cl.model_precache[modnum];
1298 	if (model != ent->model)
1299 	{
1300 		ent->model = model;
1301 		InvalidateTraceLineCache();
1302 	// automatic animation (torches, etc) can be either all together
1303 	// or randomized
1304 		if (model)
1305 		{
1306 			if (model->synctype == ST_RAND)
1307 				ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
1308 			else
1309 				ent->syncbase = 0.0;
1310 		}
1311 		else
1312 			forcelink = true;	// hack to make null model players work
1313 		if (num > 0 && num <= cl.maxclients)
1314 			R_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin
1315 
1316 		ent->lerpflags |= LERP_RESETANIM; //johnfitz -- don't lerp animation across model changes
1317 	}
1318 	//johnfitz
1319 
1320 	if ( forcelink )
1321 	{	// didn't have an update last message
1322 		VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
1323 		VectorCopy (ent->msg_origins[0], ent->origin);
1324 		VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
1325 		VectorCopy (ent->msg_angles[0], ent->angles);
1326 		ent->forcelink = true;
1327 	}
1328 }
1329 
1330 /*
1331 ==================
1332 CL_ParseBaseline
1333 ==================
1334 */
CL_ParseBaseline(entity_t * ent,int version)1335 static void CL_ParseBaseline (entity_t *ent, int version) //johnfitz -- added argument
1336 {
1337 	int	i;
1338 	int bits; //johnfitz
1339 
1340 	if (version == 6)
1341 	{
1342 		CLFTE_ParseBaseline(&ent->baseline);
1343 		return;
1344 	}
1345 
1346 	ent->baseline = nullentitystate;
1347 
1348 	//johnfitz -- PROTOCOL_FITZQUAKE
1349 	if (version == 7)
1350 		bits = B_LARGEMODEL|B_LARGEFRAME;	//dpp7's spawnstatic2
1351 	else
1352 	bits = (version == 2) ? MSG_ReadByte() : 0;
1353 	ent->baseline.modelindex = (bits & B_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte();
1354 	ent->baseline.frame = (bits & B_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte();
1355 	//johnfitz
1356 
1357 	ent->baseline.colormap = MSG_ReadByte();
1358 	ent->baseline.skin = MSG_ReadByte();
1359 	for (i = 0; i < 3; i++)
1360 	{
1361 		ent->baseline.origin[i] = MSG_ReadCoord (cl.protocolflags);
1362 		ent->baseline.angles[i] = MSG_ReadAngle (cl.protocolflags);
1363 	}
1364 
1365 	ent->baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte() : ENTALPHA_DEFAULT; //johnfitz -- PROTOCOL_FITZQUAKE
1366 }
1367 
1368 
1369 #define CL_SetStati(stat, val) cl.statsf[stat] = (cl.stats[stat] = val)
1370 #define CL_SetHudStat(stat, val) if (cl.stats[stat] != val)Sbar_Changed(); CL_SetStati(stat,val)
1371 
1372 /*
1373 ==================
1374 CL_ParseClientdata
1375 
1376 Server information pertaining to this client only
1377 ==================
1378 */
CL_ParseClientdata(void)1379 static void CL_ParseClientdata (void)
1380 {
1381 	int		i;
1382 	int		bits; //johnfitz
1383 
1384 	bits = (unsigned short)MSG_ReadShort (); //johnfitz -- read bits here isntead of in CL_ParseServerMessage()
1385 
1386 	//johnfitz -- PROTOCOL_FITZQUAKE
1387 	if (bits & SU_EXTEND1)
1388 		bits |= (MSG_ReadByte() << 16);
1389 	if (bits & SU_EXTEND2)
1390 		bits |= (MSG_ReadByte() << 24);
1391 	//johnfitz
1392 
1393 	bits |= SU_ITEMS;
1394 
1395 	if (bits & SU_VIEWHEIGHT)
1396 		CL_SetStati(STAT_VIEWHEIGHT, MSG_ReadChar ());
1397 	else
1398 		CL_SetStati(STAT_VIEWHEIGHT, DEFAULT_VIEWHEIGHT);
1399 
1400 	if (bits & SU_IDEALPITCH)
1401 		CL_SetStati(STAT_IDEALPITCH, MSG_ReadChar ());
1402 	else
1403 		CL_SetStati(STAT_IDEALPITCH, 0);
1404 
1405 	VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
1406 	for (i = 0; i < 3; i++)
1407 	{
1408 		if (bits & (SU_PUNCH1<<i) )
1409 			cl.punchangle[i] = MSG_ReadChar();
1410 		else
1411 			cl.punchangle[i] = 0;
1412 
1413 		if (bits & (SU_VELOCITY1<<i) )
1414 			cl.mvelocity[0][i] = MSG_ReadChar()*16;
1415 		else
1416 			cl.mvelocity[0][i] = 0;
1417 	}
1418 
1419 	//johnfitz -- update v_punchangles
1420 	if (v_punchangles[0][0] != cl.punchangle[0] || v_punchangles[0][1] != cl.punchangle[1] || v_punchangles[0][2] != cl.punchangle[2])
1421 	{
1422 		v_punchangles_times[1] = v_punchangles_times[0];
1423 		v_punchangles_times[0] = cl.mtime[0];
1424 		VectorCopy (v_punchangles[0], v_punchangles[1]);
1425 		VectorCopy (cl.punchangle, v_punchangles[0]);
1426 	}
1427 	//johnfitz
1428 
1429 	if (bits & SU_ITEMS)
1430 		CL_SetStati(STAT_ITEMS, MSG_ReadLong ());
1431 
1432 	cl.onground = (bits & SU_ONGROUND) != 0;
1433 	cl.inwater = (bits & SU_INWATER) != 0;
1434 
1435 	{
1436 		unsigned short weaponframe = 0;
1437 		unsigned short armourval = 0;
1438 		unsigned short weaponmodel = 0;
1439 		unsigned int activeweapon;
1440 		short health;
1441 		unsigned short ammo;
1442 		unsigned short ammovals[4];
1443 
1444 		if (bits & SU_WEAPONFRAME)
1445 			weaponframe = MSG_ReadByte ();
1446 		if (bits & SU_ARMOR)
1447 			armourval = MSG_ReadByte ();
1448 		if (bits & SU_WEAPON)
1449 			weaponmodel = MSG_ReadByte ();
1450 		health = MSG_ReadShort ();
1451 		ammo = MSG_ReadByte ();
1452 		for (i = 0; i < 4; i++)
1453 			ammovals[i] = MSG_ReadByte ();
1454 		activeweapon = MSG_ReadByte ();
1455 		if (!standard_quake)
1456 			activeweapon = 1u<<activeweapon;
1457 
1458 		//johnfitz -- PROTOCOL_FITZQUAKE
1459 		if (bits & SU_WEAPON2)
1460 			weaponmodel |= (MSG_ReadByte() << 8);
1461 		if (bits & SU_ARMOR2)
1462 			armourval |= (MSG_ReadByte() << 8);
1463 		if (bits & SU_AMMO2)
1464 			ammo |= (MSG_ReadByte() << 8);
1465 		if (bits & SU_SHELLS2)
1466 			ammovals[0] |= (MSG_ReadByte() << 8);
1467 		if (bits & SU_NAILS2)
1468 			ammovals[1] |= (MSG_ReadByte() << 8);
1469 		if (bits & SU_ROCKETS2)
1470 			ammovals[2] |= (MSG_ReadByte() << 8);
1471 		if (bits & SU_CELLS2)
1472 			ammovals[3] |= (MSG_ReadByte() << 8);
1473 		if (bits & SU_WEAPONFRAME2)
1474 			weaponframe |= (MSG_ReadByte() << 8);
1475 		if (bits & SU_WEAPONALPHA)
1476 			cl.viewent.alpha = MSG_ReadByte();
1477 		else
1478 			cl.viewent.alpha = ENTALPHA_DEFAULT;
1479 		//johnfitz
1480 
1481 		CL_SetHudStat(STAT_WEAPONFRAME, weaponframe);
1482 		CL_SetHudStat(STAT_ARMOR, armourval);
1483 		CL_SetHudStat(STAT_WEAPON, weaponmodel);
1484 		CL_SetHudStat(STAT_ACTIVEWEAPON, activeweapon);
1485 		CL_SetHudStat(STAT_HEALTH, health);
1486 		CL_SetHudStat(STAT_AMMO, ammo);
1487 		CL_SetHudStat(STAT_SHELLS, ammovals[0]);
1488 		CL_SetHudStat(STAT_NAILS, ammovals[1]);
1489 		CL_SetHudStat(STAT_ROCKETS, ammovals[2]);
1490 		CL_SetHudStat(STAT_CELLS, ammovals[3]);
1491 	}
1492 }
1493 
1494 /*
1495 =====================
1496 CL_NewTranslation
1497 =====================
1498 */
CL_NewTranslation(int slot)1499 void CL_NewTranslation (int slot)
1500 {
1501 	if (slot > cl.maxclients)
1502 		Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
1503 	R_TranslatePlayerSkin (slot);
1504 }
1505 
1506 /*
1507 =====================
1508 CL_ParseStatic
1509 =====================
1510 */
CL_ParseStatic(int version)1511 static void CL_ParseStatic (int version) //johnfitz -- added a parameter
1512 {
1513 	entity_t *ent;
1514 	int		i;
1515 
1516 	i = cl.num_statics;
1517 	if (i >= cl.max_static_entities)
1518 	{
1519 		int ec = 64;
1520 		entity_t **newstatics = realloc(cl.static_entities, sizeof(*newstatics) * (cl.max_static_entities+ec));
1521 		entity_t *newents = Hunk_Alloc(sizeof(*newents) * ec);
1522 		if (!newstatics || !newents)
1523 			Host_Error ("Too many static entities");
1524 		cl.static_entities = newstatics;
1525 		while (ec--)
1526 			cl.static_entities[cl.max_static_entities++] = newents++;
1527 	}
1528 
1529 	ent = cl.static_entities[i];
1530 	cl.num_statics++;
1531 	CL_ParseBaseline (ent, version); //johnfitz -- added second parameter
1532 
1533 // copy it to the current state
1534 
1535 	ent->netstate = ent->baseline;
1536 	ent->eflags = ent->netstate.eflags; //spike -- annoying and probably not used anyway, but w/e
1537 
1538 	ent->model = cl.model_precache[ent->baseline.modelindex];
1539 	ent->lerpflags |= LERP_RESETANIM; //johnfitz -- lerping
1540 	ent->frame = ent->baseline.frame;
1541 
1542 	ent->skinnum = ent->baseline.skin;
1543 	ent->effects = ent->baseline.effects;
1544 	ent->alpha = ent->baseline.alpha; //johnfitz -- alpha
1545 
1546 	VectorCopy (ent->baseline.origin, ent->origin);
1547 	VectorCopy (ent->baseline.angles, ent->angles);
1548 	if (ent->model)
1549 		R_AddEfrags (ent);
1550 
1551 	InvalidateTraceLineCache();
1552 }
1553 
1554 /*
1555 ===================
1556 CL_ParseStaticSound
1557 ===================
1558 */
CL_ParseStaticSound(int version)1559 static void CL_ParseStaticSound (int version) //johnfitz -- added argument
1560 {
1561 	vec3_t		org;
1562 	int			sound_num, vol, atten;
1563 	int			i;
1564 
1565 	for (i = 0; i < 3; i++)
1566 		org[i] = MSG_ReadCoord (cl.protocolflags);
1567 
1568 	//johnfitz -- PROTOCOL_FITZQUAKE
1569 	if (version == 2)
1570 		sound_num = MSG_ReadShort ();
1571 	else
1572 		sound_num = MSG_ReadByte ();
1573 	//johnfitz
1574 
1575 	vol = MSG_ReadByte ();
1576 	atten = MSG_ReadByte ();
1577 
1578 	S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
1579 }
1580 
1581 /*
1582 CL_ParsePrecache
1583 
1584 spike -- added this mostly for particle effects, but its also used for models+sounds (if needed)
1585 */
CL_ParsePrecache(void)1586 static void CL_ParsePrecache(void)
1587 {
1588 	unsigned short code = MSG_ReadShort();
1589 	unsigned int index = code&0x3fff;
1590 	const char *name = MSG_ReadString();
1591 	switch((code>>14) & 0x3)
1592 	{
1593 	case 0:	//models
1594 		if (index < MAX_MODELS)
1595 		{
1596 			cl.model_precache[index] = Mod_ForName (name, false);
1597 			//FIXME: if its a bsp model, generate lightmaps.
1598 			//FIXME: update static entities with that modelindex
1599 		}
1600 		break;
1601 #ifdef PSET_SCRIPT
1602 	case 1:	//particles
1603 		if (index < MAX_PARTICLETYPES)
1604 		{
1605 			if (*name)
1606 			{
1607 				cl.particle_precache[index].name = strcpy(Hunk_Alloc(strlen(name)+1), name);
1608 				cl.particle_precache[index].index = PScript_FindParticleType(cl.particle_precache[index].name);
1609 			}
1610 			else
1611 			{
1612 				cl.particle_precache[index].name = NULL;
1613 				cl.particle_precache[index].index = -1;
1614 			}
1615 		}
1616 		break;
1617 #endif
1618 	case 2:	//sounds
1619 		if (index < MAX_SOUNDS)
1620 			cl.sound_precache[index] = S_PrecacheSound (name);
1621 		break;
1622 //	case 3:	//unused
1623 	default:
1624 		Con_Warning("CL_ParsePrecache: unsupported precache type\n");
1625 		break;
1626 	}
1627 }
1628 #ifdef PSET_SCRIPT
1629 int CL_GenerateRandomParticlePrecache(const char *pname);
1630 //small function for simpler reuse
CL_ForceProtocolParticles(void)1631 static void CL_ForceProtocolParticles(void)
1632 {
1633 	cl.protocol_particles = true;
1634 	PScript_FindParticleType("effectinfo.");	//make sure this is implicitly loaded.
1635 	COM_Effectinfo_Enumerate(CL_GenerateRandomParticlePrecache);
1636 	Con_Warning("Received svcdp_pointparticles1 but extension not active");
1637 }
1638 
1639 /*
1640 CL_RegisterParticles
1641 called when the particle system has changed, and any cached indexes are now probably stale.
1642 */
CL_RegisterParticles(void)1643 void CL_RegisterParticles(void)
1644 {
1645 	extern qmodel_t	mod_known[];
1646 	extern int		mod_numknown;
1647 	int i;
1648 
1649 	//make sure the precaches know the right effects
1650 	for (i = 0; i < MAX_PARTICLETYPES; i++)
1651 	{
1652 		if (cl.particle_precache[i].name)
1653 			cl.particle_precache[i].index = PScript_FindParticleType(cl.particle_precache[i].name);
1654 		else
1655 			cl.particle_precache[i].index = -1;
1656 	}
1657 
1658 	//and make sure models get the right effects+trails etc too
1659 	for (i = 0; i < mod_numknown; i++)
1660 		PScript_UpdateModelEffects(&mod_known[i]);
1661 }
1662 
1663 /*
1664 CL_ParseParticles
1665 
1666 spike -- this handles the various ssqc builtins (the ones that were based on csqc)
1667 */
CL_ParseParticles(int type)1668 static void CL_ParseParticles(int type)
1669 {
1670 	vec3_t org, vel;
1671 	if (type < 0)
1672 	{	//trail
1673 		entity_t *ent;
1674 		int entity = MSG_ReadShort();
1675 		int efnum = MSG_ReadShort();
1676 		org[0] = MSG_ReadCoord(cl.protocolflags);
1677 		org[1] = MSG_ReadCoord(cl.protocolflags);
1678 		org[2] = MSG_ReadCoord(cl.protocolflags);
1679 		vel[0] = MSG_ReadCoord(cl.protocolflags);
1680 		vel[1] = MSG_ReadCoord(cl.protocolflags);
1681 		vel[2] = MSG_ReadCoord(cl.protocolflags);
1682 
1683 		ent = CL_EntityNum(entity);
1684 
1685 		if (efnum < MAX_PARTICLETYPES && cl.particle_precache[efnum].name)
1686 			PScript_ParticleTrail(org, vel, cl.particle_precache[efnum].index, 1, 0, NULL, &ent->trailstate);
1687 	}
1688 	else
1689 	{	//point
1690 		int efnum = MSG_ReadShort();
1691 		int count;
1692 		org[0] = MSG_ReadCoord(cl.protocolflags);
1693 		org[1] = MSG_ReadCoord(cl.protocolflags);
1694 		org[2] = MSG_ReadCoord(cl.protocolflags);
1695 		if (type)
1696 		{
1697 			vel[0] = vel[1] = vel[2] = 0;
1698 			count = 1;
1699 		}
1700 		else
1701 		{
1702 			vel[0] = MSG_ReadCoord(cl.protocolflags);
1703 			vel[1] = MSG_ReadCoord(cl.protocolflags);
1704 			vel[2] = MSG_ReadCoord(cl.protocolflags);
1705 			count = MSG_ReadShort();
1706 		}
1707 		if (efnum < MAX_PARTICLETYPES && cl.particle_precache[efnum].name)
1708 		{
1709 			PScript_RunParticleEffectState (org, vel, count, cl.particle_precache[efnum].index, NULL);
1710 		}
1711 	}
1712 }
1713 #endif
1714 
1715 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1716 
CL_ParseStatNumeric(int stat,int ival,float fval)1717 static void CL_ParseStatNumeric(int stat, int ival, float fval)
1718 {
1719 	if (stat < 0 || stat >= MAX_CL_STATS)
1720 	{
1721 		Con_DWarning ("svc_updatestat: %i is invalid\n", stat);
1722 		return;
1723 	}
1724 	cl.stats[stat] = ival;
1725 	cl.statsf[stat] = fval;
1726 	//just assume that they all affect the hud
1727 	Sbar_Changed ();
1728 }
CL_ParseStatFloat(int stat,float fval)1729 static void CL_ParseStatFloat(int stat, float fval)
1730 {
1731 	CL_ParseStatNumeric(stat,fval,fval);
1732 }
CL_ParseStatInt(int stat,int ival)1733 static void CL_ParseStatInt(int stat, int ival)
1734 {
1735 	CL_ParseStatNumeric(stat,ival,ival);
1736 }
CL_ParseStatString(int stat,const char * str)1737 static void CL_ParseStatString(int stat, const char *str)
1738 {
1739 	if (stat < 0 || stat >= MAX_CL_STATS)
1740 	{
1741 		Con_DWarning ("svc_updatestat: %i is invalid\n", stat);
1742 		return;
1743 	}
1744 	free(cl.statss[stat]);
1745 	cl.statss[stat] = strdup(str);
1746 	//hud doesn't know/care about any of these strings so don't bother invalidating anything.
1747 }
1748 
1749 /*
1750 =====================
1751 CL_ParseServerMessage
1752 =====================
1753 */
CL_ParseServerMessage(void)1754 void CL_ParseServerMessage (void)
1755 {
1756 	int			cmd;
1757 	int			i;
1758 	const char		*str; //johnfitz
1759 	int			total, j, lastcmd; //johnfitz
1760 
1761 //
1762 // if recording demos, copy the message out
1763 //
1764 	if (cl_shownet.value == 1)
1765 		Con_Printf ("%i ",net_message.cursize);
1766 	else if (cl_shownet.value == 2)
1767 		Con_Printf ("------------------\n");
1768 
1769 	if (!(cl.protocol_pext2 & PEXT2_PREDINFO))
1770 	cl.onground = false;	// unless the server says otherwise
1771 //
1772 // parse the message
1773 //
1774 	MSG_BeginReading ();
1775 
1776 	lastcmd = 0;
1777 	while (1)
1778 	{
1779 		if (msg_badread)
1780 			Host_Error ("CL_ParseServerMessage: Bad server message");
1781 
1782 		cmd = MSG_ReadByte ();
1783 
1784 		if (cmd == -1)
1785 		{
1786 			SHOWNET("END OF MESSAGE");
1787 
1788 			if (cl.items != cl.stats[STAT_ITEMS])
1789 			{
1790 				for (i = 0; i < 32; i++)
1791 					if ( ((uint32_t)cl.stats[STAT_ITEMS] & (1u<<i)) && !((uint32_t)cl.items & (1u<<i)))
1792 						cl.item_gettime[i] = cl.time;
1793 				cl.items = cl.stats[STAT_ITEMS];
1794 			}
1795 			return;		// end of message
1796 		}
1797 
1798 	// if the high bit of the command byte is set, it is a fast update
1799 		if (cmd & U_SIGNAL) //johnfitz -- was 128, changed for clarity
1800 		{
1801 			SHOWNET("fast update");
1802 			CL_ParseUpdate (cmd&127);
1803 			continue;
1804 		}
1805 
1806 		SHOWNET(svc_strings[cmd]);
1807 
1808 	// other commands
1809 		switch (cmd)
1810 		{
1811 		default:
1812 			Host_Error ("Illegible server message %s, previous was %s", svc_strings[cmd], svc_strings[lastcmd]); //johnfitz -- added svc_strings[lastcmd]
1813 			break;
1814 
1815 		case svc_nop:
1816 		//	Con_Printf ("svc_nop\n");
1817 			break;
1818 
1819 		case svc_time:
1820 			cl.mtime[1] = cl.mtime[0];
1821 			cl.mtime[0] = MSG_ReadFloat ();
1822 			if (cl.protocol_pext2 & PEXT2_PREDINFO)
1823 				MSG_ReadShort();	//input sequence ack.
1824 			break;
1825 
1826 		case svc_clientdata:
1827 			CL_ParseClientdata (); //johnfitz -- removed bits parameter, we will read this inside CL_ParseClientdata()
1828 			break;
1829 
1830 		case svc_version:
1831 			i = MSG_ReadLong ();
1832 			//johnfitz -- support multiple protocols
1833 			if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE && i != PROTOCOL_RMQ)
1834 				Host_Error ("Server returned version %i, not %i or %i or %i", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE, PROTOCOL_RMQ);
1835 			cl.protocol = i;
1836 			//johnfitz
1837 			break;
1838 
1839 		case svc_disconnect:
1840 			Host_EndGame ("Server disconnected\n");
1841 
1842 		case svc_print:
1843 			Con_Printf ("%s", MSG_ReadString ());
1844 			break;
1845 
1846 		case svc_centerprint:
1847 			//johnfitz -- log centerprints to console
1848 			str = MSG_ReadString ();
1849 			SCR_CenterPrint (str);
1850 			Con_LogCenterPrint (str);
1851 			//johnfitz
1852 			break;
1853 
1854 		case svc_stufftext:
1855 			Cbuf_AddText (MSG_ReadString ());
1856 			break;
1857 
1858 		case svc_damage:
1859 			V_ParseDamage ();
1860 			break;
1861 
1862 		case svc_serverinfo:
1863 			CL_ParseServerInfo ();
1864 			vid.recalc_refdef = true;	// leave intermission full screen
1865 			break;
1866 
1867 		case svc_setangle:
1868 			for (i=0 ; i<3 ; i++)
1869 				cl.viewangles[i] = MSG_ReadAngle (cl.protocolflags);
1870 			break;
1871 		case svcfte_setangledelta:
1872 			for (i=0 ; i<3 ; i++)
1873 				cl.viewangles[i] += MSG_ReadAngle16 (cl.protocolflags);
1874 			break;
1875 
1876 		case svc_setview:
1877 			cl.viewentity = MSG_ReadShort ();
1878 			break;
1879 
1880 		case svc_lightstyle:
1881 			i = MSG_ReadByte ();
1882 			if (i >= MAX_LIGHTSTYLES)
1883 				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
1884 			q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING);
1885 			cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
1886 			//johnfitz -- save extra info
1887 			if (cl_lightstyle[i].length)
1888 			{
1889 				total = 0;
1890 				cl_lightstyle[i].peak = 'a';
1891 				for (j=0; j<cl_lightstyle[i].length; j++)
1892 				{
1893 					total += cl_lightstyle[i].map[j] - 'a';
1894 					cl_lightstyle[i].peak = q_max(cl_lightstyle[i].peak, cl_lightstyle[i].map[j]);
1895 				}
1896 				cl_lightstyle[i].average = total / cl_lightstyle[i].length + 'a';
1897 			}
1898 			else
1899 				cl_lightstyle[i].average = cl_lightstyle[i].peak = 'm';
1900 			//johnfitz
1901 			break;
1902 
1903 		case svc_sound:
1904 			CL_ParseStartSoundPacket();
1905 			break;
1906 
1907 		case svc_stopsound:
1908 			i = MSG_ReadShort();
1909 			S_StopSound(i>>3, i&7);
1910 			break;
1911 
1912 		case svc_updatename:
1913 			Sbar_Changed ();
1914 			i = MSG_ReadByte ();
1915 			if (i >= cl.maxclients)
1916 				Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
1917 			q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME);
1918 			break;
1919 
1920 		case svc_updatefrags:
1921 			Sbar_Changed ();
1922 			i = MSG_ReadByte ();
1923 			if (i >= cl.maxclients)
1924 				Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
1925 			cl.scores[i].frags = MSG_ReadShort ();
1926 			break;
1927 
1928 		case svc_updatecolors:
1929 			Sbar_Changed ();
1930 			i = MSG_ReadByte ();
1931 			if (i >= cl.maxclients)
1932 				Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
1933 			cl.scores[i].colors = MSG_ReadByte ();
1934 			CL_NewTranslation (i);
1935 			break;
1936 
1937 		case svc_particle:
1938 			R_ParseParticleEffect ();
1939 			break;
1940 
1941 		case svc_spawnbaseline:
1942 			i = MSG_ReadShort ();
1943 			// must use CL_EntityNum() to force cl.num_entities up
1944 			CL_ParseBaseline (CL_EntityNum(i), 1); // johnfitz -- added second parameter
1945 			break;
1946 
1947 		case svc_spawnstatic:
1948 			CL_ParseStatic (1); //johnfitz -- added parameter
1949 			break;
1950 
1951 		case svc_temp_entity:
1952 			CL_ParseTEnt ();
1953 			break;
1954 
1955 		case svc_setpause:
1956 			cl.paused = MSG_ReadByte ();
1957 			if (cl.paused)
1958 			{
1959 				CDAudio_Pause ();
1960 				BGM_Pause ();
1961 			}
1962 			else
1963 			{
1964 				CDAudio_Resume ();
1965 				BGM_Resume ();
1966 			}
1967 			break;
1968 
1969 		case svc_signonnum:
1970 			i = MSG_ReadByte ();
1971 			if (i <= cls.signon)
1972 				Host_Error ("Received signon %i when at %i", i, cls.signon);
1973 			cls.signon = i;
1974 			//johnfitz -- if signonnum==2, signon packet has been fully parsed, so check for excessive static ents and efrags
1975 			if (i == 2)
1976 			{
1977 				if (cl.num_statics > 128)
1978 					Con_DWarning ("%i static entities exceeds standard limit of 128.\n", cl.num_statics);
1979 				R_CheckEfrags ();
1980 			}
1981 			//johnfitz
1982 			CL_SignonReply ();
1983 			break;
1984 
1985 		case svc_killedmonster:
1986 			cl.stats[STAT_MONSTERS]++;
1987 			cl.statsf[STAT_MONSTERS] = cl.stats[STAT_MONSTERS];
1988 			break;
1989 
1990 		case svc_foundsecret:
1991 			cl.stats[STAT_SECRETS]++;
1992 			cl.statsf[STAT_SECRETS] = cl.stats[STAT_SECRETS];
1993 			break;
1994 
1995 		case svc_updatestat:
1996 			i = MSG_ReadByte ();
1997 			CL_ParseStatInt(i, MSG_ReadLong());
1998 			break;
1999 
2000 		case svc_spawnstaticsound:
2001 			CL_ParseStaticSound (1); //johnfitz -- added parameter
2002 			break;
2003 
2004 		case svc_cdtrack:
2005 			cl.cdtrack = MSG_ReadByte ();
2006 			cl.looptrack = MSG_ReadByte ();
2007 			if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
2008 				BGM_PlayCDtrack ((byte)cls.forcetrack, true);
2009 			else
2010 				BGM_PlayCDtrack ((byte)cl.cdtrack, true);
2011 			break;
2012 
2013 		case svc_intermission:
2014 			cl.intermission = 1;
2015 			cl.completed_time = cl.time;
2016 			vid.recalc_refdef = true;	// go to full screen
2017 			break;
2018 
2019 		case svc_finale:
2020 			cl.intermission = 2;
2021 			cl.completed_time = cl.time;
2022 			vid.recalc_refdef = true;	// go to full screen
2023 			//johnfitz -- log centerprints to console
2024 			str = MSG_ReadString ();
2025 			SCR_CenterPrint (str);
2026 			Con_LogCenterPrint (str);
2027 			//johnfitz
2028 			break;
2029 
2030 		case svc_cutscene:
2031 			cl.intermission = 3;
2032 			cl.completed_time = cl.time;
2033 			vid.recalc_refdef = true;	// go to full screen
2034 			//johnfitz -- log centerprints to console
2035 			str = MSG_ReadString ();
2036 			SCR_CenterPrint (str);
2037 			Con_LogCenterPrint (str);
2038 			//johnfitz
2039 			break;
2040 
2041 		case svc_sellscreen:
2042 			Cmd_ExecuteString ("help", src_command);
2043 			break;
2044 
2045 		//johnfitz -- new svc types
2046 		case svc_skybox:
2047 			Sky_LoadSkyBox (MSG_ReadString());
2048 			break;
2049 
2050 		case svc_bf:
2051 			Cmd_ExecuteString ("bf", src_command);
2052 			break;
2053 
2054 		case svc_fog:
2055 			Fog_ParseServerMessage ();
2056 			break;
2057 
2058 		case svc_spawnbaseline2: //PROTOCOL_FITZQUAKE
2059 			i = MSG_ReadShort ();
2060 			// must use CL_EntityNum() to force cl.num_entities up
2061 			CL_ParseBaseline (CL_EntityNum(i), 2);
2062 			break;
2063 
2064 		case svc_spawnstatic2: //PROTOCOL_FITZQUAKE
2065 			CL_ParseStatic (2);
2066 			break;
2067 
2068 		case svc_spawnstaticsound2: //PROTOCOL_FITZQUAKE
2069 			CL_ParseStaticSound (2);
2070 			break;
2071 		//johnfitz
2072 
2073 		//used by the 2021 rerelease
2074 		case svc_achievement:
2075 			str = MSG_ReadString();
2076 			Con_DPrintf("Ignoring svc_achievement (%s)\n", str);
2077 			break;
2078 #ifdef PSET_SCRIPT
2079 		case svcdp_trailparticles:
2080 			if (!cl.protocol_particles)
2081 				CL_ForceProtocolParticles();
2082 			CL_ParseParticles(-1);
2083 			break;
2084 		case svcdp_pointparticles:
2085 			if (!cl.protocol_particles)
2086 				CL_ForceProtocolParticles();
2087 			CL_ParseParticles(0);
2088 			break;
2089 		case svcdp_pointparticles1:
2090 			if (!cl.protocol_particles)
2091 				CL_ForceProtocolParticles();
2092 			CL_ParseParticles(1);
2093 			break;
2094 #endif
2095 
2096 		//spike -- for particles more than anything else
2097 		case svcdp_precache:
2098 			if (!cl.protocol_pext2)
2099 				Host_Error ("Received svcdp_precache but extension not active");
2100 			CL_ParsePrecache();
2101 			break;
2102 		//spike -- new deltas (including new fields etc)
2103 		//stats also changed, and are sent unreliably using the same ack mechanism (which means they're not blocked until the reliables are acked, preventing the need to spam them in every packet).
2104 		case svcdp_updatestatbyte:
2105 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2106 				Host_Error ("Received svcdp_updatestatbyte but extension not active");
2107 			i = MSG_ReadByte ();
2108 			CL_ParseStatInt(i, MSG_ReadByte());
2109 			break;
2110 		case svcfte_updatestatstring:
2111 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2112 				Host_Error ("Received svcfte_updatestatstring but extension not active");
2113 			i = MSG_ReadByte ();
2114 			CL_ParseStatString(i, MSG_ReadString());
2115 			break;
2116 		case svcfte_updatestatfloat:
2117 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2118 				Host_Error ("Received svcfte_updatestatfloat but extension not active");
2119 			i = MSG_ReadByte ();
2120 			CL_ParseStatFloat(i, MSG_ReadFloat());
2121 			break;
2122 		//static ents get all the new fields too, even if the client will probably ignore most of them, the option is at least there to fix it without updating protocols separately.
2123 		case svcfte_spawnstatic2:
2124 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2125 				Host_Error ("Received svcfte_spawnstatic2 but extension not active");
2126 			CL_ParseStatic (6);
2127 			break;
2128 		//baselines have all fields. hurrah for the same delta mechanism
2129 		case svcfte_spawnbaseline2:
2130 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2131 				Host_Error ("Received svcfte_spawnbaseline2 but extension not active");
2132 			i = MSG_ReadEntity (cl.protocol_pext2);
2133 			// must use CL_EntityNum() to force cl.num_entities up
2134 			CL_ParseBaseline (CL_EntityNum(i), 6);
2135 			break;
2136 		//ent updates replace svc_time too
2137 		case svcfte_updateentities:
2138 			if (!(cl.protocol_pext2 & PEXT2_REPLACEMENTDELTAS))
2139 				Host_Error ("Received svcfte_updateentities but extension not active");
2140 			CLFTE_ParseEntitiesUpdate();
2141 			break;
2142 
2143 		case svcfte_cgamepacket:
2144 			if (!(cl.protocol_pext1 & PEXT1_CSQC))
2145 				Host_Error ("Received svcfte_cgamepacket but extension not active");
2146 			if (cl.qcvm.extfuncs.CSQC_Parse_Event)
2147 			{
2148 				PR_SwitchQCVM(&cl.qcvm);
2149 				PR_ExecuteProgram(cl.qcvm.extfuncs.CSQC_Parse_Event);
2150 				PR_SwitchQCVM(NULL);
2151 			}
2152 			else
2153 				Host_Error ("CSQC_Parse_Event: Missing or incompatible CSQC\n");
2154 			break;
2155 		}
2156 
2157 		lastcmd = cmd; //johnfitz
2158 	}
2159 }
2160 
2161