1 /*
2 ===========================================================================
3
4 Return to Castle Wolfenstein multiplayer GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (RTCW MP Source Code).
8
9 RTCW MP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 RTCW MP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with RTCW MP Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29
30 #include "server.h"
31
32
33 /*
34 =============================================================================
35
36 Delta encode a client frame onto the network channel
37
38 A normal server packet will look like:
39
40 4 sequence number (high bit set if an oversize fragment)
41 <optional reliable commands>
42 1 svc_snapshot
43 4 last client reliable command
44 4 serverTime
45 1 lastframe for delta compression
46 1 snapFlags
47 1 areaBytes
48 <areabytes>
49 <playerstate>
50 <packetentities>
51
52 =============================================================================
53 */
54
55 /*
56 =============
57 SV_EmitPacketEntities
58
59 Writes a delta update of an entityState_t list to the message.
60 =============
61 */
SV_EmitPacketEntities(clientSnapshot_t * from,clientSnapshot_t * to,msg_t * msg)62 static void SV_EmitPacketEntities( clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg ) {
63 entityState_t *oldent, *newent;
64 int oldindex, newindex;
65 int oldnum, newnum;
66 int from_num_entities;
67
68 // generate the delta update
69 if ( !from ) {
70 from_num_entities = 0;
71 } else {
72 from_num_entities = from->num_entities;
73 }
74
75 newent = NULL;
76 oldent = NULL;
77 newindex = 0;
78 oldindex = 0;
79 while ( newindex < to->num_entities || oldindex < from_num_entities ) {
80 if ( newindex >= to->num_entities ) {
81 newnum = 9999;
82 } else {
83 newent = &svs.snapshotEntities[( to->first_entity + newindex ) % svs.numSnapshotEntities];
84 newnum = newent->number;
85 }
86
87 if ( oldindex >= from_num_entities ) {
88 oldnum = 9999;
89 } else {
90 oldent = &svs.snapshotEntities[( from->first_entity + oldindex ) % svs.numSnapshotEntities];
91 oldnum = oldent->number;
92 }
93
94 if ( newnum == oldnum ) {
95 // delta update from old position
96 // because the force parm is qfalse, this will not result
97 // in any bytes being emited if the entity has not changed at all
98 MSG_WriteDeltaEntity( msg, oldent, newent, qfalse );
99 oldindex++;
100 newindex++;
101 continue;
102 }
103
104 if ( newnum < oldnum ) {
105 // this is a new entity, send it from the baseline
106 MSG_WriteDeltaEntity( msg, &sv.svEntities[newnum].baseline, newent, qtrue );
107 newindex++;
108 continue;
109 }
110
111 if ( newnum > oldnum ) {
112 // the old entity isn't present in the new message
113 MSG_WriteDeltaEntity( msg, oldent, NULL, qtrue );
114 oldindex++;
115 continue;
116 }
117 }
118
119 MSG_WriteBits( msg, ( MAX_GENTITIES - 1 ), GENTITYNUM_BITS ); // end of packetentities
120 }
121
122
123
124 /*
125 ==================
126 SV_WriteSnapshotToClient
127 ==================
128 */
SV_WriteSnapshotToClient(client_t * client,msg_t * msg)129 static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) {
130 clientSnapshot_t *frame, *oldframe;
131 int lastframe;
132 int i;
133 int snapFlags;
134
135 // this is the snapshot we are creating
136 frame = &client->frames[ client->netchan.outgoingSequence & PACKET_MASK ];
137
138 // try to use a previous frame as the source for delta compressing the snapshot
139 if ( client->deltaMessage <= 0 || client->state != CS_ACTIVE ) {
140 // client is asking for a retransmit
141 oldframe = NULL;
142 lastframe = 0;
143 } else if ( client->netchan.outgoingSequence - client->deltaMessage
144 >= ( PACKET_BACKUP - 3 ) ) {
145 // client hasn't gotten a good message through in a long time
146 Com_DPrintf( "%s: Delta request from out of date packet.\n", client->name );
147 oldframe = NULL;
148 lastframe = 0;
149 } else {
150 // we have a valid snapshot to delta from
151 oldframe = &client->frames[ client->deltaMessage & PACKET_MASK ];
152 lastframe = client->netchan.outgoingSequence - client->deltaMessage;
153
154 // the snapshot's entities may still have rolled off the buffer, though
155 if ( oldframe->first_entity <= svs.nextSnapshotEntities - svs.numSnapshotEntities ) {
156 Com_DPrintf( "%s: Delta request from out of date entities.\n", client->name );
157 oldframe = NULL;
158 lastframe = 0;
159 }
160 }
161
162 MSG_WriteByte( msg, svc_snapshot );
163
164 // NOTE, MRE: now sent at the start of every message from server to client
165 // let the client know which reliable clientCommands we have received
166 //MSG_WriteLong( msg, client->lastClientCommand );
167
168 // send over the current server time so the client can drift
169 // its view of time to try to match
170 if( client->oldServerTime ) {
171 // The server has not yet got an acknowledgement of the
172 // new gamestate from this client, so continue to send it
173 // a time as if the server has not restarted. Note from
174 // the client's perspective this time is strictly speaking
175 // incorrect, but since it'll be busy loading a map at
176 // the time it doesn't really matter.
177 MSG_WriteLong (msg, sv.time + client->oldServerTime);
178 } else {
179 MSG_WriteLong (msg, sv.time);
180 }
181
182 // what we are delta'ing from
183 MSG_WriteByte( msg, lastframe );
184
185 snapFlags = svs.snapFlagServerBit;
186 if ( client->rateDelayed ) {
187 snapFlags |= SNAPFLAG_RATE_DELAYED;
188 }
189 if ( client->state != CS_ACTIVE ) {
190 snapFlags |= SNAPFLAG_NOT_ACTIVE;
191 }
192
193 MSG_WriteByte( msg, snapFlags );
194
195 // send over the areabits
196 MSG_WriteByte( msg, frame->areabytes );
197 MSG_WriteData( msg, frame->areabits, frame->areabytes );
198
199 // delta encode the playerstate
200 if ( oldframe ) {
201 MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps );
202 } else {
203 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps );
204 }
205
206 // delta encode the entities
207 SV_EmitPacketEntities( oldframe, frame, msg );
208
209 // padding for rate debugging
210 if ( sv_padPackets->integer ) {
211 for ( i = 0 ; i < sv_padPackets->integer ; i++ ) {
212 MSG_WriteByte( msg, svc_nop );
213 }
214 }
215 }
216
217
218 /*
219 ==================
220 SV_UpdateServerCommandsToClient
221
222 (re)send all server commands the client hasn't acknowledged yet
223 ==================
224 */
SV_UpdateServerCommandsToClient(client_t * client,msg_t * msg)225 void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg ) {
226 int i;
227
228 // write any unacknowledged serverCommands
229 for ( i = client->reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
230 MSG_WriteByte( msg, svc_serverCommand );
231 MSG_WriteLong( msg, i );
232 MSG_WriteString( msg, client->reliableCommands[ i & ( MAX_RELIABLE_COMMANDS - 1 ) ] );
233 }
234 client->reliableSent = client->reliableSequence;
235 }
236
237 /*
238 =============================================================================
239
240 Build a client snapshot structure
241
242 =============================================================================
243 */
244
245 typedef struct {
246 int numSnapshotEntities;
247 int snapshotEntities[MAX_SNAPSHOT_ENTITIES];
248 } snapshotEntityNumbers_t;
249
250 /*
251 =======================
252 SV_QsortEntityNumbers
253 =======================
254 */
SV_QsortEntityNumbers(const void * a,const void * b)255 static int QDECL SV_QsortEntityNumbers( const void *a, const void *b ) {
256 int *ea, *eb;
257
258 ea = (int *)a;
259 eb = (int *)b;
260
261 if ( *ea == *eb ) {
262 Com_Error( ERR_DROP, "SV_QsortEntityStates: duplicated entity" );
263 }
264
265 if ( *ea < *eb ) {
266 return -1;
267 }
268
269 return 1;
270 }
271
272
273 /*
274 ===============
275 SV_AddEntToSnapshot
276 ===============
277 */
SV_AddEntToSnapshot(svEntity_t * svEnt,sharedEntity_t * gEnt,snapshotEntityNumbers_t * eNums)278 static void SV_AddEntToSnapshot( svEntity_t *svEnt, sharedEntity_t *gEnt, snapshotEntityNumbers_t *eNums ) {
279 // if we have already added this entity to this snapshot, don't add again
280 if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
281 return;
282 }
283 svEnt->snapshotCounter = sv.snapshotCounter;
284
285 // if we are full, silently discard entities
286 if ( eNums->numSnapshotEntities == MAX_SNAPSHOT_ENTITIES ) {
287 return;
288 }
289
290 eNums->snapshotEntities[ eNums->numSnapshotEntities ] = gEnt->s.number;
291 eNums->numSnapshotEntities++;
292 }
293
294 #if defined ANTIWALLHACK
has_player_sound(int entnum)295 static int has_player_sound(int entnum)
296 {
297 return 0;
298
299 #if 0 // Leaving this code inactive for now
300 int event;
301 sharedEntity_t *ent;
302 playerState_t *ps;
303
304 // check for weapon ready looping sound
305 ps = SV_GameClientNum(entnum);
306 if ( ps->weapon == WP_FLAMETHROWER )
307 return 1;
308
309 // check for sound event
310 ent = SV_GentityNum(entnum);
311 event = ent->s.event & ~EV_EVENT_BITS;
312 if (event == 0)
313 return 0;
314
315 switch (event)
316 {
317 case EV_FOOTSTEP:
318 case EV_FOOTSTEP_METAL:
319 case EV_FOOTSTEP_WOOD:
320 case EV_FOOTSTEP_GRASS:
321 case EV_FOOTSTEP_GRAVEL:
322 case EV_FOOTSTEP_ROOF:
323 case EV_FOOTSTEP_SNOW:
324 case EV_FOOTSTEP_CARPET:
325 case EV_FOOTSPLASH:
326 case EV_SWIM:
327 case EV_FALL_SHORT:
328 case EV_FALL_MEDIUM:
329 case EV_FALL_FAR:
330 case EV_JUMP:
331 case EV_WATER_TOUCH:
332 case EV_WATER_LEAVE:
333 case EV_WATER_UNDER:
334 case EV_WATER_CLEAR:
335 case EV_CHANGE_WEAPON:
336 case EV_PAIN:
337 return 1;
338 break;
339
340 default:
341 return 0;
342 break;
343 }
344 #endif
345 }
346 #endif
347
348 /*
349 ===============
350 SV_AddEntitiesVisibleFromPoint
351 ===============
352 */
SV_AddEntitiesVisibleFromPoint(vec3_t origin,clientSnapshot_t * frame,snapshotEntityNumbers_t * eNums,qboolean portal,qboolean localClient)353 static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
354 // snapshotEntityNumbers_t *eNums, qboolean portal, clientSnapshot_t *oldframe, qboolean localClient ) {
355 // snapshotEntityNumbers_t *eNums, qboolean portal ) {
356 snapshotEntityNumbers_t *eNums, qboolean portal, qboolean localClient ) {
357 int e, i;
358 sharedEntity_t *ent, *playerEnt;
359 svEntity_t *svEnt;
360 int l;
361 int clientarea, clientcluster;
362 int leafnum;
363 byte *clientpvs;
364 byte *bitvector;
365
366 #if defined ANTIWALLHACK
367 sharedEntity_t *client;
368 #endif
369
370 // during an error shutdown message we may need to transmit
371 // the shutdown message after the server has shutdown, so
372 // specfically check for it
373 if ( !sv.state ) {
374 return;
375 }
376
377 leafnum = CM_PointLeafnum( origin );
378 clientarea = CM_LeafArea( leafnum );
379 clientcluster = CM_LeafCluster( leafnum );
380
381 // calculate the visible areas
382 frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );
383
384 clientpvs = CM_ClusterPVS( clientcluster );
385
386 playerEnt = SV_GentityNum( frame->ps.clientNum );
387
388 for ( e = 0 ; e < sv.num_entities ; e++ ) {
389 ent = SV_GentityNum( e );
390
391 // never send entities that aren't linked in
392 if ( !ent->r.linked ) {
393 continue;
394 }
395
396 if ( ent->s.number != e ) {
397 Com_DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
398 ent->s.number = e;
399 }
400
401 // entities can be flagged to explicitly not be sent to the client
402 if ( ent->r.svFlags & SVF_NOCLIENT ) {
403 continue;
404 }
405
406 // entities can be flagged to be sent to only one client
407 if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
408 if ( ent->r.singleClient != frame->ps.clientNum ) {
409 continue;
410 }
411 }
412 // entities can be flagged to be sent to everyone but one client
413 if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
414 if ( ent->r.singleClient == frame->ps.clientNum ) {
415 continue;
416 }
417 }
418
419 svEnt = SV_SvEntityForGentity( ent );
420
421 // don't double add an entity through portals
422 if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
423 continue;
424 }
425
426 // if this client is viewing from a camera, only add ents visible from portal ents
427 if ( ( playerEnt->s.eFlags & EF_VIEWING_CAMERA ) && !portal ) {
428 if ( ent->r.svFlags & SVF_PORTAL ) {
429 SV_AddEntToSnapshot( svEnt, ent, eNums );
430 // SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, oldframe, localClient );
431 SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, localClient );
432 }
433 continue;
434 }
435
436 // broadcast entities are always sent
437 if ( ent->r.svFlags & SVF_BROADCAST ) {
438 SV_AddEntToSnapshot( svEnt, ent, eNums );
439 continue;
440 }
441
442 // ignore if not touching a PV leaf
443 // check area
444 if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
445 // doors can legally straddle two areas, so
446 // we may need to check another one
447 if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
448 goto notVisible; // blocked by a door
449 }
450 }
451
452 bitvector = clientpvs;
453
454 // check individual leafs
455 if ( !svEnt->numClusters ) {
456 goto notVisible;
457 }
458 l = 0;
459 for ( i = 0 ; i < svEnt->numClusters ; i++ ) {
460 l = svEnt->clusternums[i];
461 if ( bitvector[l >> 3] & ( 1 << ( l & 7 ) ) ) {
462 break;
463 }
464 }
465
466 // if we haven't found it to be visible,
467 // check overflow clusters that coudln't be stored
468 if ( i == svEnt->numClusters ) {
469 if ( svEnt->lastCluster ) {
470 for ( ; l <= svEnt->lastCluster ; l++ ) {
471 if ( bitvector[l >> 3] & ( 1 << ( l & 7 ) ) ) {
472 break;
473 }
474 }
475 if ( l == svEnt->lastCluster ) {
476 goto notVisible; // not visible
477 }
478 } else {
479 goto notVisible;
480 }
481 }
482
483 //----(SA) added "visibility dummies"
484 if ( ent->r.svFlags & SVF_VISDUMMY ) {
485 sharedEntity_t *ment = 0;
486
487 //find master;
488 ment = SV_GentityNum( ent->s.otherEntityNum );
489
490 if ( ment ) {
491 svEntity_t *master = 0;
492 master = SV_SvEntityForGentity( ment );
493
494 if ( master->snapshotCounter == sv.snapshotCounter || !ment->r.linked ) {
495 goto notVisible;
496 //continue;
497 }
498
499 SV_AddEntToSnapshot( master, ment, eNums );
500 }
501 goto notVisible;
502 //continue; // master needs to be added, but not this dummy ent
503 }
504 //----(SA) end
505 else if ( ent->r.svFlags & SVF_VISDUMMY_MULTIPLE ) {
506 {
507 int h;
508 sharedEntity_t *ment = 0;
509 svEntity_t *master = 0;
510
511 for ( h = 0; h < sv.num_entities; h++ )
512 {
513 ment = SV_GentityNum( h );
514
515 if ( ment == ent ) {
516 continue;
517 }
518
519 if ( ment ) {
520 master = SV_SvEntityForGentity( ment );
521 } else {
522 continue;
523 }
524
525 if ( !( ment->r.linked ) ) {
526 continue;
527 }
528
529 if ( ment->s.number != h ) {
530 Com_DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
531 ment->s.number = h;
532 }
533
534 if ( ment->r.svFlags & SVF_NOCLIENT ) {
535 continue;
536 }
537
538 if ( master->snapshotCounter == sv.snapshotCounter ) {
539 continue;
540 }
541
542 if ( ment->s.otherEntityNum == ent->s.number ) {
543 SV_AddEntToSnapshot( master, ment, eNums );
544 }
545 }
546 goto notVisible;
547 }
548 }
549
550 #if defined ANTIWALLHACK
551 if (e < sv_maxclients->integer) // client
552 {
553 if (e == frame->ps.clientNum)
554 continue;
555
556 client = SV_GentityNum(frame->ps.clientNum);
557
558 if (awh_active->integer && ! portal && ! (client->r.svFlags & SVF_BOT) &&
559 (frame->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) )
560 {
561 if (! AWH_CanSee(frame->ps.clientNum, e))
562 {
563 if (! has_player_sound(e))
564 continue;
565
566 if (! AWH_CanHear(frame->ps.clientNum, e))
567 continue;
568
569 AWH_RandomizePos(frame->ps.clientNum, e);
570 }
571 }
572 }
573 #endif
574
575 // add it
576 SV_AddEntToSnapshot( svEnt, ent, eNums );
577
578 // if it's a portal entity, add everything visible from its camera position
579 if ( ent->r.svFlags & SVF_PORTAL ) {
580 // SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, oldframe, localClient );
581 SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, localClient );
582 }
583
584 continue;
585
586 notVisible:
587
588 // Ridah, if this entity has changed events, then send it regardless of whether we can see it or not
589 // DHM - Nerve :: not in multiplayer please
590 if ( sv_gametype->integer == GT_SINGLE_PLAYER && localClient ) {
591 if ( ent->r.eventTime == svs.time ) {
592 ent->s.eFlags |= EF_NODRAW; // don't draw, just process event
593 SV_AddEntToSnapshot( svEnt, ent, eNums );
594 } else if ( ent->s.eType == ET_PLAYER ) {
595 // keep players around if they are alive and active (so sounds dont get messed up)
596 if ( !( ent->s.eFlags & EF_DEAD ) ) {
597 ent->s.eFlags |= EF_NODRAW; // don't draw, just process events and sounds
598 SV_AddEntToSnapshot( svEnt, ent, eNums );
599 }
600 }
601 }
602
603 }
604 }
605
606 /*
607 =============
608 SV_BuildClientSnapshot
609
610 Decides which entities are going to be visible to the client, and
611 copies off the playerstate and areabits.
612
613 This properly handles multiple recursive portals, but the render
614 currently doesn't.
615
616 For viewing through other player's eyes, clent can be something other than client->gentity
617 =============
618 */
SV_BuildClientSnapshot(client_t * client)619 static void SV_BuildClientSnapshot( client_t *client ) {
620 vec3_t org;
621 // clientSnapshot_t *frame, *oldframe;
622 clientSnapshot_t *frame;
623 snapshotEntityNumbers_t entityNumbers;
624 int i;
625 sharedEntity_t *ent;
626 entityState_t *state;
627 svEntity_t *svEnt;
628 sharedEntity_t *clent;
629 int clientNum;
630 playerState_t *ps;
631
632 // bump the counter used to prevent double adding
633 sv.snapshotCounter++;
634
635 // this is the frame we are creating
636 frame = &client->frames[ client->netchan.outgoingSequence & PACKET_MASK ];
637
638 // clear everything in this snapshot
639 entityNumbers.numSnapshotEntities = 0;
640 memset( frame->areabits, 0, sizeof( frame->areabits ) );
641
642 // show_bug.cgi?id=62
643 frame->num_entities = 0;
644
645 clent = client->gentity;
646 if ( !clent || client->state == CS_ZOMBIE ) {
647 return;
648 }
649
650 // grab the current playerState_t
651 ps = SV_GameClientNum( client - svs.clients );
652 frame->ps = *ps;
653
654 // never send client's own entity, because it can
655 // be regenerated from the playerstate
656 clientNum = frame->ps.clientNum;
657 if ( clientNum < 0 || clientNum >= MAX_GENTITIES ) {
658 Com_Error( ERR_DROP, "SV_SvEntityForGentity: bad gEnt" );
659 }
660 svEnt = &sv.svEntities[ clientNum ];
661
662 svEnt->snapshotCounter = sv.snapshotCounter;
663
664 // find the client's viewpoint
665 VectorCopy( ps->origin, org );
666 org[2] += ps->viewheight;
667
668 //----(SA) added for 'lean'
669 // need to account for lean, so areaportal doors draw properly
670 if ( frame->ps.leanf != 0 ) {
671 vec3_t right, v3ViewAngles;
672 VectorCopy( ps->viewangles, v3ViewAngles );
673 v3ViewAngles[2] += frame->ps.leanf / 2.0f;
674 AngleVectors( v3ViewAngles, NULL, right, NULL );
675 VectorMA( org, frame->ps.leanf, right, org );
676 }
677 //----(SA) end
678
679 // add all the entities directly visible to the eye, which
680 // may include portal entities that merge other viewpoints
681 SV_AddEntitiesVisibleFromPoint( org, frame, &entityNumbers, qfalse, client->netchan.remoteAddress.type == NA_LOOPBACK );
682
683 // if there were portals visible, there may be out of order entities
684 // in the list which will need to be resorted for the delta compression
685 // to work correctly. This also catches the error condition
686 // of an entity being included twice.
687 qsort( entityNumbers.snapshotEntities, entityNumbers.numSnapshotEntities,
688 sizeof( entityNumbers.snapshotEntities[0] ), SV_QsortEntityNumbers );
689
690 // now that all viewpoint's areabits have been OR'd together, invert
691 // all of them to make it a mask vector, which is what the renderer wants
692 for ( i = 0 ; i < MAX_MAP_AREA_BYTES / 4 ; i++ ) {
693 ( (int *)frame->areabits )[i] = ( (int *)frame->areabits )[i] ^ -1;
694 }
695
696 // copy the entity states out
697 frame->num_entities = 0;
698 frame->first_entity = svs.nextSnapshotEntities;
699 for ( i = 0 ; i < entityNumbers.numSnapshotEntities ; i++ ) {
700 ent = SV_GentityNum( entityNumbers.snapshotEntities[i] );
701 state = &svs.snapshotEntities[svs.nextSnapshotEntities % svs.numSnapshotEntities];
702 *state = ent->s;
703
704 svs.nextSnapshotEntities++;
705 // this should never hit, map should always be restarted first in SV_Frame
706 if ( svs.nextSnapshotEntities >= 0x7FFFFFFE ) {
707 Com_Error( ERR_FATAL, "svs.nextSnapshotEntities wrapped" );
708 }
709 frame->num_entities++;
710 }
711 }
712
713 #ifdef USE_VOIP
714 /*
715 ==================
716 SV_WriteVoipToClient
717
718 Check to see if there is any VoIP queued for a client, and send if there is.
719 ==================
720 */
SV_WriteVoipToClient(client_t * cl,msg_t * msg)721 static void SV_WriteVoipToClient(client_t *cl, msg_t *msg)
722 {
723 int totalbytes = 0;
724 int i;
725 voipServerPacket_t *packet;
726
727 if(cl->queuedVoipPackets)
728 {
729 // Write as many VoIP packets as we reasonably can...
730 for(i = 0; i < cl->queuedVoipPackets; i++)
731 {
732 packet = cl->voipPacket[(i + cl->queuedVoipIndex) % ARRAY_LEN(cl->voipPacket)];
733
734 if(!*cl->downloadName)
735 {
736 totalbytes += packet->len;
737 if (totalbytes > (msg->maxsize - msg->cursize) / 2)
738 break;
739
740 MSG_WriteByte(msg, svc_voipOpus);
741 MSG_WriteShort(msg, packet->sender);
742 MSG_WriteByte(msg, (byte) packet->generation);
743 MSG_WriteLong(msg, packet->sequence);
744 MSG_WriteByte(msg, packet->frames);
745 MSG_WriteShort(msg, packet->len);
746 MSG_WriteBits(msg, packet->flags, VOIP_FLAGCNT);
747 MSG_WriteData(msg, packet->data, packet->len);
748 }
749
750 Z_Free(packet);
751 }
752
753 cl->queuedVoipPackets -= i;
754 cl->queuedVoipIndex += i;
755 cl->queuedVoipIndex %= ARRAY_LEN(cl->voipPacket);
756 }
757 }
758 #endif
759
760 /*
761 =======================
762 SV_SendMessageToClient
763
764 Called by SV_SendClientSnapshot and SV_SendClientGameState
765 =======================
766 */
SV_SendMessageToClient(msg_t * msg,client_t * client)767 void SV_SendMessageToClient(msg_t *msg, client_t *client)
768 {
769
770 // record information about the message
771 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSize = msg->cursize;
772 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSent = svs.time;
773 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageAcked = -1;
774
775 // send the datagram
776 SV_Netchan_Transmit(client, msg);
777 }
778
779
780 /*
781 =======================
782 SV_SendClientSnapshot
783
784 Also called by SV_FinalMessage
785
786 =======================
787 */
SV_SendClientSnapshot(client_t * client)788 void SV_SendClientSnapshot( client_t *client ) {
789 byte msg_buf[MAX_MSGLEN];
790 msg_t msg;
791
792 // build the snapshot
793 SV_BuildClientSnapshot( client );
794
795 // bots need to have their snapshots build, but
796 // the query them directly without needing to be sent
797 if ( client->gentity && client->gentity->r.svFlags & SVF_BOT ) {
798 return;
799 }
800
801 MSG_Init( &msg, msg_buf, sizeof( msg_buf ) );
802 msg.allowoverflow = qtrue;
803
804 // NOTE, MRE: all server->client messages now acknowledge
805 // let the client know which reliable clientCommands we have received
806 MSG_WriteLong( &msg, client->lastClientCommand );
807
808 // (re)send any reliable server commands
809 SV_UpdateServerCommandsToClient( client, &msg );
810
811 // send over all the relevant entityState_t
812 // and the playerState_t
813 SV_WriteSnapshotToClient( client, &msg );
814
815 #ifdef USE_VOIP
816 SV_WriteVoipToClient( client, &msg );
817 #endif
818
819 // check for overflow
820 if ( msg.overflowed ) {
821 Com_Printf( "WARNING: msg overflowed for %s\n", client->name );
822 MSG_Clear( &msg );
823 }
824
825 SV_SendMessageToClient( &msg, client );
826
827 sv.bpsTotalBytes += msg.cursize; // NERVE - SMF - net debugging
828 sv.ubpsTotalBytes += msg.uncompsize / 8; // NERVE - SMF - net debugging
829 }
830
831
832 /*
833 =======================
834 SV_SendClientMessages
835 =======================
836 */
837
SV_SendClientMessages(void)838 void SV_SendClientMessages( void ) {
839 int i;
840 client_t *c;
841 int numclients = 0; // NERVE - SMF - net debugging
842
843 sv.bpsTotalBytes = 0; // NERVE - SMF - net debugging
844 sv.ubpsTotalBytes = 0; // NERVE - SMF - net debugging
845
846 // send a message to each connected client
847 for(i=0; i < sv_maxclients->integer; i++)
848 {
849 c = &svs.clients[i];
850
851 if(!c->state)
852 continue; // not connected
853
854 if(svs.time - c->lastSnapshotTime < c->snapshotMsec * com_timescale->value)
855 continue; // It's not time yet
856
857 if(*c->downloadName)
858 continue; // Client is downloading, don't send snapshots
859
860 numclients++; // NERVE - SMF - net debugging
861
862 if(c->netchan.unsentFragments || c->netchan_start_queue)
863 {
864 c->rateDelayed = qtrue;
865 continue; // Drop this snapshot if the packet queue is still full or delta compression will break
866 }
867
868 if(!(c->netchan.remoteAddress.type == NA_LOOPBACK ||
869 (sv_lanForceRate->integer && Sys_IsLANAddress(c->netchan.remoteAddress))))
870 {
871 // rate control for clients not on LAN
872 if(SV_RateMsec(c) > 0)
873 {
874 // Not enough time since last packet passed through the line
875 c->rateDelayed = qtrue;
876 continue;
877 }
878 }
879
880 // generate and send a new message
881 SV_SendClientSnapshot(c);
882 c->lastSnapshotTime = svs.time;
883 c->rateDelayed = qfalse;
884 }
885
886 // NERVE - SMF - net debugging
887 if ( sv_showAverageBPS->integer && numclients > 0 ) {
888 float ave = 0, uave = 0;
889
890 for ( i = 0; i < MAX_BPS_WINDOW - 1; i++ ) {
891 sv.bpsWindow[i] = sv.bpsWindow[i + 1];
892 ave += sv.bpsWindow[i];
893
894 sv.ubpsWindow[i] = sv.ubpsWindow[i + 1];
895 uave += sv.ubpsWindow[i];
896 }
897
898 sv.bpsWindow[MAX_BPS_WINDOW - 1] = sv.bpsTotalBytes;
899 ave += sv.bpsTotalBytes;
900
901 sv.ubpsWindow[MAX_BPS_WINDOW - 1] = sv.ubpsTotalBytes;
902 uave += sv.ubpsTotalBytes;
903
904 if ( sv.bpsTotalBytes >= sv.bpsMaxBytes ) {
905 sv.bpsMaxBytes = sv.bpsTotalBytes;
906 }
907
908 if ( sv.ubpsTotalBytes >= sv.ubpsMaxBytes ) {
909 sv.ubpsMaxBytes = sv.ubpsTotalBytes;
910 }
911
912 sv.bpsWindowSteps++;
913
914 if ( sv.bpsWindowSteps >= MAX_BPS_WINDOW ) {
915 float comp_ratio;
916
917 sv.bpsWindowSteps = 0;
918
919 ave = ( ave / (float)MAX_BPS_WINDOW );
920 uave = ( uave / (float)MAX_BPS_WINDOW );
921
922 comp_ratio = ( 1 - ave / uave ) * 100.f;
923 sv.ucompAve += comp_ratio;
924 sv.ucompNum++;
925
926 Com_DPrintf( "bpspc(%2.0f) bps(%2.0f) pk(%i) ubps(%2.0f) upk(%i) cr(%2.2f) acr(%2.2f)\n",
927 ave / (float)numclients, ave, sv.bpsMaxBytes, uave, sv.ubpsMaxBytes, comp_ratio, sv.ucompAve / sv.ucompNum );
928 }
929 }
930 // -NERVE - SMF
931 }
932