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