1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "server.h"
22
23 /*
24 =============================================================================
25
26 Encode a client frame onto the network channel
27
28 =============================================================================
29 */
30
31 /*
32 =============
33 SV_EmitPacketEntities
34
35 Writes a delta update of an entity_state_t list to the message.
36 =============
37 */
SV_EmitPacketEntities(client_frame_t * from,client_frame_t * to,sizebuf_t * msg)38 void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
39 {
40 entity_state_t *oldent = NULL, *newent = NULL;
41 int oldindex, newindex;
42 int oldnum, newnum;
43 int from_num_entities;
44 int bits;
45
46 MSG_WriteByte (msg, svc_packetentities);
47
48 if (!from)
49 from_num_entities = 0;
50 else
51 from_num_entities = from->num_entities;
52
53 newindex = 0;
54 oldindex = 0;
55 while (newindex < to->num_entities || oldindex < from_num_entities)
56 {
57 if (newindex >= to->num_entities)
58 newnum = 9999;
59 else
60 {
61 newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
62 newnum = newent->number;
63 }
64
65 if (oldindex >= from_num_entities)
66 oldnum = 9999;
67 else
68 {
69 oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
70 oldnum = oldent->number;
71 }
72
73 if (newnum == oldnum)
74 { // delta update from old position
75 // because the force parm is false, this will not result
76 // in any bytes being emited if the entity has not changed at all
77 // note that players are always 'newentities', this updates their oldorigin always
78 // and prevents warping
79 MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
80 oldindex++;
81 newindex++;
82 continue;
83 }
84
85 if (newnum < oldnum)
86 { // this is a new entity, send it from the baseline
87 MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
88 newindex++;
89 continue;
90 }
91
92 if (newnum > oldnum)
93 { // the old entity isn't present in the new message
94 bits = U_REMOVE;
95 if (oldnum >= 256)
96 bits |= U_NUMBER16 | U_MOREBITS1;
97
98 MSG_WriteByte (msg, bits&255 );
99 if (bits & 0x0000ff00)
100 MSG_WriteByte (msg, (bits>>8)&255 );
101
102 if (bits & U_NUMBER16)
103 MSG_WriteShort (msg, oldnum);
104 else
105 MSG_WriteByte (msg, oldnum);
106
107 oldindex++;
108 continue;
109 }
110 }
111
112 MSG_WriteShort (msg, 0); // end of packetentities
113 }
114
115
116
117 /*
118 =============
119 SV_WritePlayerstateToClient
120
121 =============
122 */
SV_WritePlayerstateToClient(client_frame_t * from,client_frame_t * to,sizebuf_t * msg)123 void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
124 {
125 int i;
126 int pflags;
127 player_state_t *ps, *ops;
128 player_state_t dummy;
129 int statbits;
130
131 ps = &to->ps;
132 if (!from)
133 {
134 memset (&dummy, 0, sizeof(dummy));
135 ops = &dummy;
136 }
137 else
138 ops = &from->ps;
139
140 //
141 // determine what needs to be sent
142 //
143 pflags = 0;
144
145 if (ps->pmove.pm_type != ops->pmove.pm_type)
146 pflags |= PS_M_TYPE;
147
148 if (ps->pmove.origin[0] != ops->pmove.origin[0]
149 || ps->pmove.origin[1] != ops->pmove.origin[1]
150 || ps->pmove.origin[2] != ops->pmove.origin[2] )
151 pflags |= PS_M_ORIGIN;
152
153 if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
154 || ps->pmove.velocity[1] != ops->pmove.velocity[1]
155 || ps->pmove.velocity[2] != ops->pmove.velocity[2] )
156 pflags |= PS_M_VELOCITY;
157
158 if (ps->pmove.pm_time != ops->pmove.pm_time)
159 pflags |= PS_M_TIME;
160
161 if (ps->pmove.pm_flags != ops->pmove.pm_flags)
162 pflags |= PS_M_FLAGS;
163
164 if (ps->pmove.gravity != ops->pmove.gravity)
165 pflags |= PS_M_GRAVITY;
166
167 if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
168 || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
169 || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
170 pflags |= PS_M_DELTA_ANGLES;
171
172
173 if (ps->viewoffset[0] != ops->viewoffset[0]
174 || ps->viewoffset[1] != ops->viewoffset[1]
175 || ps->viewoffset[2] != ops->viewoffset[2] )
176 pflags |= PS_VIEWOFFSET;
177
178 if (ps->viewangles[0] != ops->viewangles[0]
179 || ps->viewangles[1] != ops->viewangles[1]
180 || ps->viewangles[2] != ops->viewangles[2] )
181 pflags |= PS_VIEWANGLES;
182
183 if (ps->kick_angles[0] != ops->kick_angles[0]
184 || ps->kick_angles[1] != ops->kick_angles[1]
185 || ps->kick_angles[2] != ops->kick_angles[2] )
186 pflags |= PS_KICKANGLES;
187
188 if (ps->blend[0] != ops->blend[0]
189 || ps->blend[1] != ops->blend[1]
190 || ps->blend[2] != ops->blend[2]
191 || ps->blend[3] != ops->blend[3] )
192 pflags |= PS_BLEND;
193
194 if (ps->fov != ops->fov)
195 pflags |= PS_FOV;
196
197 if (ps->rdflags != ops->rdflags)
198 pflags |= PS_RDFLAGS;
199
200 if (ps->gunframe != ops->gunframe)
201 pflags |= PS_WEAPONFRAME;
202
203 pflags |= PS_WEAPONINDEX;
204
205 //
206 // write it
207 //
208 MSG_WriteByte (msg, svc_playerinfo);
209 MSG_WriteShort (msg, pflags);
210
211 //
212 // write the pmove_state_t
213 //
214 if (pflags & PS_M_TYPE)
215 MSG_WriteByte (msg, ps->pmove.pm_type);
216
217 if (pflags & PS_M_ORIGIN)
218 {
219 MSG_WriteShort (msg, ps->pmove.origin[0]);
220 MSG_WriteShort (msg, ps->pmove.origin[1]);
221 MSG_WriteShort (msg, ps->pmove.origin[2]);
222 }
223
224 if (pflags & PS_M_VELOCITY)
225 {
226 MSG_WriteShort (msg, ps->pmove.velocity[0]);
227 MSG_WriteShort (msg, ps->pmove.velocity[1]);
228 MSG_WriteShort (msg, ps->pmove.velocity[2]);
229 }
230
231 if (pflags & PS_M_TIME)
232 MSG_WriteByte (msg, ps->pmove.pm_time);
233
234 if (pflags & PS_M_FLAGS)
235 MSG_WriteByte (msg, ps->pmove.pm_flags);
236
237 if (pflags & PS_M_GRAVITY)
238 MSG_WriteShort (msg, ps->pmove.gravity);
239
240 if (pflags & PS_M_DELTA_ANGLES)
241 {
242 MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
243 MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
244 MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
245 }
246
247 //
248 // write the rest of the player_state_t
249 //
250 if (pflags & PS_VIEWOFFSET)
251 {
252 MSG_WriteChar (msg, ps->viewoffset[0]*4);
253 MSG_WriteChar (msg, ps->viewoffset[1]*4);
254 MSG_WriteChar (msg, ps->viewoffset[2]*4);
255 }
256
257 if (pflags & PS_VIEWANGLES)
258 {
259 MSG_WriteAngle16 (msg, ps->viewangles[0]);
260 MSG_WriteAngle16 (msg, ps->viewangles[1]);
261 MSG_WriteAngle16 (msg, ps->viewangles[2]);
262 }
263
264 if (pflags & PS_KICKANGLES)
265 {
266 MSG_WriteChar (msg, ps->kick_angles[0]*4);
267 MSG_WriteChar (msg, ps->kick_angles[1]*4);
268 MSG_WriteChar (msg, ps->kick_angles[2]*4);
269 }
270
271 if (pflags & PS_WEAPONINDEX)
272 {
273 MSG_WriteByte (msg, ps->gunindex);
274 }
275
276 if (pflags & PS_WEAPONFRAME)
277 {
278 MSG_WriteByte (msg, ps->gunframe);
279 MSG_WriteChar (msg, ps->gunoffset[0]*4);
280 MSG_WriteChar (msg, ps->gunoffset[1]*4);
281 MSG_WriteChar (msg, ps->gunoffset[2]*4);
282 MSG_WriteChar (msg, ps->gunangles[0]*4);
283 MSG_WriteChar (msg, ps->gunangles[1]*4);
284 MSG_WriteChar (msg, ps->gunangles[2]*4);
285 }
286
287 if (pflags & PS_BLEND)
288 {
289 MSG_WriteByte (msg, ps->blend[0]*255);
290 MSG_WriteByte (msg, ps->blend[1]*255);
291 MSG_WriteByte (msg, ps->blend[2]*255);
292 MSG_WriteByte (msg, ps->blend[3]*255);
293 }
294 if (pflags & PS_FOV)
295 MSG_WriteByte (msg, ps->fov);
296 if (pflags & PS_RDFLAGS)
297 MSG_WriteByte (msg, ps->rdflags);
298
299 // send stats
300 statbits = 0;
301 for (i=0 ; i<MAX_STATS ; i++)
302 if (ps->stats[i] != ops->stats[i])
303 statbits |= 1<<i;
304 MSG_WriteLong (msg, statbits);
305 for (i=0 ; i<MAX_STATS ; i++)
306 if (statbits & (1<<i) )
307 MSG_WriteShort (msg, ps->stats[i]);
308 }
309
310
311 /*
312 ==================
313 SV_WriteFrameToClient
314 ==================
315 */
SV_WriteFrameToClient(client_t * client,sizebuf_t * msg)316 void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
317 {
318 client_frame_t *frame, *oldframe;
319 int lastframe;
320
321 //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
322 // this is the frame we are creating
323 frame = &client->frames[sv.framenum & UPDATE_MASK];
324
325 if (client->lastframe <= 0)
326 { // client is asking for a retransmit
327 oldframe = NULL;
328 lastframe = -1;
329 }
330 else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
331 { // client hasn't gotten a good message through in a long time
332 // Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
333 oldframe = NULL;
334 lastframe = -1;
335 }
336 else
337 { // we have a valid message to delta from
338 oldframe = &client->frames[client->lastframe & UPDATE_MASK];
339 lastframe = client->lastframe;
340 }
341
342 MSG_WriteByte (msg, svc_frame);
343 MSG_WriteLong (msg, sv.framenum);
344 MSG_WriteLong (msg, lastframe); // what we are delta'ing from
345 MSG_WriteByte (msg, client->surpressCount); // rate dropped packets
346 client->surpressCount = 0;
347
348 // send over the areabits
349 MSG_WriteByte (msg, frame->areabytes);
350 SZ_Write (msg, frame->areabits, frame->areabytes);
351
352 // delta encode the playerstate
353 SV_WritePlayerstateToClient (oldframe, frame, msg);
354
355 // delta encode the entities
356 SV_EmitPacketEntities (oldframe, frame, msg);
357 }
358
359
360 /*
361 =============================================================================
362
363 Build a client frame structure
364
365 =============================================================================
366 */
367
368 byte fatpvs[65536/8]; // 32767 is MAX_MAP_LEAFS
369
370 /*
371 ============
372 SV_FatPVS
373
374 The client will interpolate the view position,
375 so we can't use a single PVS point
376 ===========
377 */
SV_FatPVS(vec3_t org)378 void SV_FatPVS (vec3_t org)
379 {
380 int leafs[64];
381 int i, j, count;
382 int longs;
383 byte *src;
384 vec3_t mins, maxs;
385
386 for (i=0 ; i<3 ; i++)
387 {
388 mins[i] = org[i] - 8;
389 maxs[i] = org[i] + 8;
390 }
391
392 count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
393 if (count < 1)
394 Com_Error (ERR_FATAL, "SV_FatPVS: count < 1");
395 longs = (CM_NumClusters()+31)>>5;
396
397 // convert leafs to clusters
398 for (i=0 ; i<count ; i++)
399 leafs[i] = CM_LeafCluster(leafs[i]);
400
401 memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
402 // or in all the other leaf bits
403 for (i=1 ; i<count ; i++)
404 {
405 for (j=0 ; j<i ; j++)
406 if (leafs[i] == leafs[j])
407 break;
408 if (j != i)
409 continue; // already have the cluster we want
410 src = CM_ClusterPVS(leafs[i]);
411 for (j=0 ; j<longs ; j++)
412 ((long *)fatpvs)[j] |= ((long *)src)[j];
413 }
414 }
415
416
417 /*
418 =============
419 SV_BuildClientFrame
420
421 Decides which entities are going to be visible to the client, and
422 copies off the playerstat and areabits.
423 =============
424 */
SV_BuildClientFrame(client_t * client)425 void SV_BuildClientFrame (client_t *client)
426 {
427 int e, i;
428 vec3_t org;
429 edict_t *ent;
430 edict_t *clent;
431 client_frame_t *frame;
432 entity_state_t *state;
433 int l;
434 int clientarea, clientcluster;
435 int leafnum;
436 int c_fullsend;
437 byte *clientphs;
438 byte *bitvector;
439
440 clent = client->edict;
441 if (!clent->client)
442 return; // not in game yet
443
444 // this is the frame we are creating
445 frame = &client->frames[sv.framenum & UPDATE_MASK];
446
447 frame->senttime = svs.realtime; // save it for ping calc later
448
449 // find the client's PVS
450 for (i=0 ; i<3 ; i++)
451 org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
452
453 leafnum = CM_PointLeafnum (org);
454 clientarea = CM_LeafArea (leafnum);
455 clientcluster = CM_LeafCluster (leafnum);
456
457 // calculate the visible areas
458 frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
459
460 // grab the current player_state_t
461 frame->ps = clent->client->ps;
462
463
464 SV_FatPVS (org);
465 clientphs = CM_ClusterPHS (clientcluster);
466
467 // build up the list of visible entities
468 frame->num_entities = 0;
469 frame->first_entity = svs.next_client_entities;
470
471 c_fullsend = 0;
472
473 for (e=1 ; e<ge->num_edicts ; e++)
474 {
475 ent = EDICT_NUM(e);
476
477 // ignore ents without visible models
478 if (ent->svflags & SVF_NOCLIENT)
479 continue;
480
481 // ignore ents without visible models unless they have an effect
482 if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
483 && !ent->s.event)
484 continue;
485
486 // ignore if not touching a PV leaf
487 if (ent != clent)
488 {
489 // check area
490 if (!CM_AreasConnected (clientarea, ent->areanum))
491 { // doors can legally straddle two areas, so
492 // we may need to check another one
493 if (!ent->areanum2
494 || !CM_AreasConnected (clientarea, ent->areanum2))
495 continue; // blocked by a door
496 }
497
498 // beams just check one point for PHS
499 if (ent->s.renderfx & RF_BEAM)
500 {
501 l = ent->clusternums[0];
502 if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
503 continue;
504 }
505 else
506 {
507 // FIXME: if an ent has a model and a sound, but isn't
508 // in the PVS, only the PHS, clear the model
509 if (ent->s.sound)
510 {
511 bitvector = fatpvs; //clientphs;
512 }
513 else
514 bitvector = fatpvs;
515
516 if (ent->num_clusters == -1)
517 { // too many leafs for individual check, go by headnode
518 if (!CM_HeadnodeVisible (ent->headnode, bitvector))
519 continue;
520 c_fullsend++;
521 }
522 else
523 { // check individual leafs
524 for (i=0 ; i < ent->num_clusters ; i++)
525 {
526 l = ent->clusternums[i];
527 if (bitvector[l >> 3] & (1 << (l&7) ))
528 break;
529 }
530 if (i == ent->num_clusters)
531 continue; // not visible
532 }
533
534 if (!ent->s.modelindex)
535 { // don't send sounds if they will be attenuated away
536 vec3_t delta;
537 float len;
538
539 VectorSubtract (org, ent->s.origin, delta);
540 len = VectorLength (delta);
541 if (len > 400)
542 continue;
543 }
544 }
545 }
546
547 // add it to the circular client_entities array
548 state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
549 if (ent->s.number != e)
550 {
551 Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
552 ent->s.number = e;
553 }
554 *state = ent->s;
555
556 // don't mark players missiles as solid
557 if (ent->owner == client->edict)
558 state->solid = 0;
559
560 svs.next_client_entities++;
561 frame->num_entities++;
562 }
563 }
564
565
566 /*
567 ==================
568 SV_RecordDemoMessage
569
570 Save everything in the world out without deltas.
571 Used for recording footage for merged or assembled demos
572 ==================
573 */
SV_RecordDemoMessage(void)574 void SV_RecordDemoMessage (void)
575 {
576 int e;
577 edict_t *ent;
578 entity_state_t nostate;
579 sizebuf_t buf;
580 byte buf_data[32768];
581 int len;
582
583 if (!svs.demofile)
584 return;
585
586 memset (&nostate, 0, sizeof(nostate));
587 SZ_Init (&buf, buf_data, sizeof(buf_data));
588
589 // write a frame message that doesn't contain a player_state_t
590 MSG_WriteByte (&buf, svc_frame);
591 MSG_WriteLong (&buf, sv.framenum);
592
593 MSG_WriteByte (&buf, svc_packetentities);
594
595 e = 1;
596 ent = EDICT_NUM(e);
597 while (e < ge->num_edicts)
598 {
599 // ignore ents without visible models unless they have an effect
600 if (ent->inuse &&
601 ent->s.number &&
602 (ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) &&
603 !(ent->svflags & SVF_NOCLIENT))
604 MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
605
606 e++;
607 ent = EDICT_NUM(e);
608 }
609
610 MSG_WriteShort (&buf, 0); // end of packetentities
611
612 // now add the accumulated multicast information
613 SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize);
614 SZ_Clear (&svs.demo_multicast);
615
616 // now write the entire message to the file, prefixed by the length
617 len = LittleLong (buf.cursize);
618 fwrite (&len, 4, 1, svs.demofile);
619 fwrite (buf.data, buf.cursize, 1, svs.demofile);
620 }
621
622