1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2013 - 2015, OpenJK contributors
7
8 This file is part of the OpenJK source code.
9
10 OpenJK is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
13
14 This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
21 ===========================================================================
22 */
23
24 #include "server.h"
25 #include "qcommon/cm_public.h"
26
27 /*
28 =============================================================================
29
30 Delta encode a client frame onto the network channel
31
32 A normal server packet will look like:
33
34 4 sequence number (high bit set if an oversize fragment)
35 <optional reliable commands>
36 1 svc_snapshot
37 4 last client reliable command
38 4 serverTime
39 1 lastframe for delta compression
40 1 snapFlags
41 1 areaBytes
42 <areabytes>
43 <playerstate>
44 <packetentities>
45
46 =============================================================================
47 */
48
49 /*
50 =============
51 SV_EmitPacketEntities
52
53 Writes a delta update of an entityState_t list to the message.
54 =============
55 */
SV_EmitPacketEntities(clientSnapshot_t * from,clientSnapshot_t * to,msg_t * msg)56 static void SV_EmitPacketEntities( clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg ) {
57 entityState_t *oldent, *newent;
58 int oldindex, newindex;
59 int oldnum, newnum;
60 int from_num_entities;
61
62 // generate the delta update
63 if ( !from ) {
64 from_num_entities = 0;
65 } else {
66 from_num_entities = from->num_entities;
67 }
68
69 newent = NULL;
70 oldent = NULL;
71 newindex = 0;
72 oldindex = 0;
73 while ( newindex < to->num_entities || oldindex < from_num_entities ) {
74 if ( newindex >= to->num_entities ) {
75 newnum = 9999;
76 } else {
77 newent = &svs.snapshotEntities[(to->first_entity+newindex) % svs.numSnapshotEntities];
78 newnum = newent->number;
79 }
80
81 if ( oldindex >= from_num_entities ) {
82 oldnum = 9999;
83 } else {
84 oldent = &svs.snapshotEntities[(from->first_entity+oldindex) % svs.numSnapshotEntities];
85 oldnum = oldent->number;
86 }
87
88 if ( newnum == oldnum ) {
89 // delta update from old position
90 // because the force parm is qfalse, this will not result
91 // in any bytes being emited if the entity has not changed at all
92 MSG_WriteDeltaEntity (msg, oldent, newent, qfalse );
93 oldindex++;
94 newindex++;
95 continue;
96 }
97
98 if ( newnum < oldnum ) {
99 // this is a new entity, send it from the baseline
100 MSG_WriteDeltaEntity (msg, &sv.svEntities[newnum].baseline, newent, qtrue );
101 newindex++;
102 continue;
103 }
104
105 if ( newnum > oldnum ) {
106 // the old entity isn't present in the new message
107 MSG_WriteDeltaEntity (msg, oldent, NULL, qtrue );
108 oldindex++;
109 continue;
110 }
111 }
112
113 MSG_WriteBits( msg, (MAX_GENTITIES-1), GENTITYNUM_BITS ); // end of packetentities
114 }
115
116
117
118 /*
119 ==================
120 SV_WriteSnapshotToClient
121 ==================
122 */
SV_WriteSnapshotToClient(client_t * client,msg_t * msg)123 static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) {
124 clientSnapshot_t *frame, *oldframe;
125 int lastframe;
126 int i;
127 int snapFlags;
128 int deltaMessage;
129
130 // this is the snapshot we are creating
131 frame = &client->frames[ client->netchan.outgoingSequence & PACKET_MASK ];
132
133 // bots never acknowledge, but it doesn't matter since the only use case is for serverside demos
134 // in which case we can delta against the very last message every time
135 deltaMessage = client->deltaMessage;
136 if ( client->demo.isBot ) {
137 client->deltaMessage = client->netchan.outgoingSequence;
138 }
139
140 // try to use a previous frame as the source for delta compressing the snapshot
141 if ( deltaMessage <= 0 || client->state != CS_ACTIVE ) {
142 // client is asking for a retransmit
143 oldframe = NULL;
144 lastframe = 0;
145 } else if ( client->netchan.outgoingSequence - deltaMessage
146 >= (PACKET_BACKUP - 3) ) {
147 // client hasn't gotten a good message through in a long time
148 Com_DPrintf ("%s: Delta request from out of date packet.\n", client->name);
149 oldframe = NULL;
150 lastframe = 0;
151 } else if ( client->demo.demorecording && client->demo.demowaiting ) {
152 // demo is waiting for a non-delta-compressed frame for this client, so don't delta compress
153 oldframe = NULL;
154 lastframe = 0;
155 } else if ( client->demo.minDeltaFrame > deltaMessage ) {
156 // we saved a non-delta frame to the demo and sent it to the client, but the client didn't ack it
157 // we can't delta against an old frame that's not in the demo without breaking the demo. so send
158 // non-delta frames until the client acks.
159 oldframe = NULL;
160 lastframe = 0;
161 } else {
162 // we have a valid snapshot to delta from
163 oldframe = &client->frames[ deltaMessage & PACKET_MASK ];
164 lastframe = client->netchan.outgoingSequence - deltaMessage;
165
166 // the snapshot's entities may still have rolled off the buffer, though
167 if ( oldframe->first_entity <= svs.nextSnapshotEntities - svs.numSnapshotEntities ) {
168 Com_DPrintf ("%s: Delta request from out of date entities.\n", client->name);
169 oldframe = NULL;
170 lastframe = 0;
171 }
172 }
173
174 if ( oldframe == NULL ) {
175 if ( client->demo.demowaiting ) {
176 // this is a non-delta frame, so we can delta against it in the demo
177 client->demo.minDeltaFrame = client->netchan.outgoingSequence;
178 }
179 client->demo.demowaiting = qfalse;
180 }
181
182 MSG_WriteByte (msg, svc_snapshot);
183
184 // NOTE, MRE: now sent at the start of every message from server to client
185 // let the client know which reliable clientCommands we have received
186 //MSG_WriteLong( msg, client->lastClientCommand );
187
188 // send over the current server time so the client can drift
189 // its view of time to try to match
190 if( client->oldServerTime &&
191 !( client->demo.demorecording && client->demo.isBot ) ) {
192 // The server has not yet got an acknowledgement of the
193 // new gamestate from this client, so continue to send it
194 // a time as if the server has not restarted. Note from
195 // the client's perspective this time is strictly speaking
196 // incorrect, but since it'll be busy loading a map at
197 // the time it doesn't really matter.
198 MSG_WriteLong (msg, sv.time + client->oldServerTime);
199 } else {
200 MSG_WriteLong (msg, sv.time);
201 }
202
203 // what we are delta'ing from
204 MSG_WriteByte (msg, lastframe);
205
206 snapFlags = svs.snapFlagServerBit;
207 if ( client->rateDelayed ) {
208 snapFlags |= SNAPFLAG_RATE_DELAYED;
209 }
210 if ( client->state != CS_ACTIVE ) {
211 snapFlags |= SNAPFLAG_NOT_ACTIVE;
212 }
213
214 MSG_WriteByte (msg, snapFlags);
215
216 // send over the areabits
217 MSG_WriteByte (msg, frame->areabytes);
218 MSG_WriteData (msg, frame->areabits, frame->areabytes);
219
220 // delta encode the playerstate
221 if ( oldframe ) {
222 #ifdef _ONEBIT_COMBO
223 MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps, frame->pDeltaOneBit, frame->pDeltaNumBit );
224 #else
225 MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps );
226 #endif
227 if (frame->ps.m_iVehicleNum)
228 { //then write the vehicle's playerstate too
229 if (!oldframe->ps.m_iVehicleNum)
230 { //if last frame didn't have vehicle, then the old vps isn't gonna delta
231 //properly (because our vps on the client could be anything)
232 #ifdef _ONEBIT_COMBO
233 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, NULL, NULL, qtrue );
234 #else
235 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, qtrue );
236 #endif
237 }
238 else
239 {
240 #ifdef _ONEBIT_COMBO
241 MSG_WriteDeltaPlayerstate( msg, &oldframe->vps, &frame->vps, frame->pDeltaOneBitVeh, frame->pDeltaNumBitVeh, qtrue );
242 #else
243 MSG_WriteDeltaPlayerstate( msg, &oldframe->vps, &frame->vps, qtrue );
244 #endif
245 }
246 }
247 } else {
248 #ifdef _ONEBIT_COMBO
249 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps, NULL, NULL );
250 #else
251 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps );
252 #endif
253 if (frame->ps.m_iVehicleNum)
254 { //then write the vehicle's playerstate too
255 #ifdef _ONEBIT_COMBO
256 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, NULL, NULL, qtrue );
257 #else
258 MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, qtrue );
259 #endif
260 }
261 }
262
263 // delta encode the entities
264 SV_EmitPacketEntities (oldframe, frame, msg);
265
266 // padding for rate debugging
267 if ( sv_padPackets->integer ) {
268 for ( i = 0 ; i < sv_padPackets->integer ; i++ ) {
269 MSG_WriteByte (msg, svc_nop);
270 }
271 }
272 }
273
274
275 /*
276 ==================
277 SV_UpdateServerCommandsToClient
278
279 (re)send all server commands the client hasn't acknowledged yet
280 ==================
281 */
SV_UpdateServerCommandsToClient(client_t * client,msg_t * msg)282 void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg ) {
283 int i;
284 int reliableAcknowledge;
285
286 if ( client->demo.isBot && client->demo.demorecording ) {
287 reliableAcknowledge = client->demo.botReliableAcknowledge;
288 } else {
289 reliableAcknowledge = client->reliableAcknowledge;
290 }
291
292 // write any unacknowledged serverCommands
293 for ( i = reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
294 MSG_WriteByte( msg, svc_serverCommand );
295 MSG_WriteLong( msg, i );
296 MSG_WriteString( msg, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
297 }
298 client->reliableSent = client->reliableSequence;
299 }
300
301 /*
302 =============================================================================
303
304 Build a client snapshot structure
305
306 =============================================================================
307 */
308
309 typedef struct snapshotEntityNumbers_s {
310 int numSnapshotEntities;
311 int snapshotEntities[MAX_SNAPSHOT_ENTITIES];
312 } snapshotEntityNumbers_t;
313
314 /*
315 =======================
316 SV_QsortEntityNumbers
317 =======================
318 */
SV_QsortEntityNumbers(const void * a,const void * b)319 static int QDECL SV_QsortEntityNumbers( const void *a, const void *b ) {
320 int *ea, *eb;
321
322 ea = (int *)a;
323 eb = (int *)b;
324
325 if ( *ea == *eb ) {
326 Com_Error( ERR_DROP, "SV_QsortEntityStates: duplicated entity" );
327 }
328
329 if ( *ea < *eb ) {
330 return -1;
331 }
332
333 return 1;
334 }
335
336
337 /*
338 ===============
339 SV_AddEntToSnapshot
340 ===============
341 */
SV_AddEntToSnapshot(svEntity_t * svEnt,sharedEntity_t * gEnt,snapshotEntityNumbers_t * eNums)342 static void SV_AddEntToSnapshot( svEntity_t *svEnt, sharedEntity_t *gEnt, snapshotEntityNumbers_t *eNums ) {
343 // if we have already added this entity to this snapshot, don't add again
344 if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
345 return;
346 }
347 svEnt->snapshotCounter = sv.snapshotCounter;
348
349 // if we are full, silently discard entities
350 if ( eNums->numSnapshotEntities == MAX_SNAPSHOT_ENTITIES ) {
351 return;
352 }
353
354 eNums->snapshotEntities[ eNums->numSnapshotEntities ] = gEnt->s.number;
355 eNums->numSnapshotEntities++;
356 }
357
358 /*
359 ===============
360 SV_AddEntitiesVisibleFromPoint
361 ===============
362 */
363 float g_svCullDist = -1.0f;
SV_AddEntitiesVisibleFromPoint(vec3_t origin,clientSnapshot_t * frame,snapshotEntityNumbers_t * eNums,qboolean portal)364 static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
365 snapshotEntityNumbers_t *eNums, qboolean portal ) {
366 int e, i;
367 sharedEntity_t *ent;
368 svEntity_t *svEnt;
369 int l;
370 int clientarea, clientcluster;
371 int leafnum;
372 byte *clientpvs;
373 byte *bitvector;
374 vec3_t difference;
375 float length, radius;
376
377 // during an error shutdown message we may need to transmit
378 // the shutdown message after the server has shutdown, so
379 // specfically check for it
380 if ( !sv.state ) {
381 return;
382 }
383
384 leafnum = CM_PointLeafnum (origin);
385 clientarea = CM_LeafArea (leafnum);
386 clientcluster = CM_LeafCluster (leafnum);
387
388 // calculate the visible areas
389 frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );
390
391 clientpvs = CM_ClusterPVS (clientcluster);
392
393 for ( e = 0 ; e < sv.num_entities ; e++ ) {
394 ent = SV_GentityNum(e);
395
396 // never send entities that aren't linked in
397 if ( !ent->r.linked ) {
398 continue;
399 }
400
401 if (ent->s.eFlags & EF_PERMANENT)
402 { // he's permanent, so don't send him down!
403 continue;
404 }
405
406 if (ent->s.number != e) {
407 Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
408 ent->s.number = e;
409 }
410
411 // entities can be flagged to explicitly not be sent to the client
412 if ( ent->r.svFlags & SVF_NOCLIENT ) {
413 continue;
414 }
415
416 // entities can be flagged to be sent to only one client
417 if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
418 if ( ent->r.singleClient != frame->ps.clientNum ) {
419 continue;
420 }
421 }
422 // entities can be flagged to be sent to everyone but one client
423 if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
424 if ( ent->r.singleClient == frame->ps.clientNum ) {
425 continue;
426 }
427 }
428
429 svEnt = SV_SvEntityForGentity( ent );
430
431 // don't double add an entity through portals
432 if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
433 continue;
434 }
435
436 // entities can request not to be sent to certain clients (NOTE: always send to ourselves)
437 if ( e != frame->ps.clientNum && (ent->r.svFlags & SVF_BROADCASTCLIENTS)
438 && !(ent->r.broadcastClients[frame->ps.clientNum/32] & (1 << (frame->ps.clientNum % 32))) )
439 {
440 continue;
441 }
442 // broadcast entities are always sent, and so is the main player so we don't see noclip weirdness
443 if ( (ent->r.svFlags & SVF_BROADCAST) || e == frame->ps.clientNum
444 || (ent->r.broadcastClients[frame->ps.clientNum/32] & (1 << (frame->ps.clientNum % 32))) )
445 {
446 SV_AddEntToSnapshot( svEnt, ent, eNums );
447 continue;
448 }
449
450 if (ent->s.isPortalEnt)
451 { //rww - portal entities are always sent as well
452 SV_AddEntToSnapshot( svEnt, ent, eNums );
453 continue;
454 }
455
456 // ignore if not touching a PV leaf
457 // check area
458 if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
459 // doors can legally straddle two areas, so
460 // we may need to check another one
461 if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
462 continue; // blocked by a door
463 }
464 }
465
466 bitvector = clientpvs;
467
468 // check individual leafs
469 if ( !svEnt->numClusters ) {
470 continue;
471 }
472 l = 0;
473 for ( i=0 ; i < svEnt->numClusters ; i++ ) {
474 l = svEnt->clusternums[i];
475 if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
476 break;
477 }
478 }
479
480 // if we haven't found it to be visible,
481 // check overflow clusters that coudln't be stored
482 if ( i == svEnt->numClusters ) {
483 if ( svEnt->lastCluster ) {
484 for ( ; l <= svEnt->lastCluster ; l++ ) {
485 if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
486 break;
487 }
488 }
489 if ( l == svEnt->lastCluster ) {
490 continue; // not visible
491 }
492 } else {
493 continue;
494 }
495 }
496
497 if (g_svCullDist != -1.0f)
498 { //do a distance cull check
499 VectorAdd(ent->r.absmax, ent->r.absmin, difference);
500 VectorScale(difference, 0.5f, difference);
501 VectorSubtract(origin, difference, difference);
502 length = VectorLength(difference);
503
504 // calculate the diameter
505 VectorSubtract(ent->r.absmax, ent->r.absmin, difference);
506 radius = VectorLength(difference);
507 if (length-radius >= g_svCullDist)
508 { //then don't add it
509 continue;
510 }
511 }
512
513 // add it
514 SV_AddEntToSnapshot( svEnt, ent, eNums );
515
516 // if its a portal entity, add everything visible from its camera position
517 if ( ent->r.svFlags & SVF_PORTAL ) {
518 if ( ent->s.generic1 ) {
519 vec3_t dir;
520 VectorSubtract(ent->s.origin, origin, dir);
521 if ( VectorLengthSquared(dir) > (float) ent->s.generic1 * ent->s.generic1 ) {
522 continue;
523 }
524 }
525 SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
526 }
527 }
528 }
529
530 /*
531 =============
532 SV_BuildClientSnapshot
533
534 Decides which entities are going to be visible to the client, and
535 copies off the playerstate and areabits.
536
537 This properly handles multiple recursive portals, but the render
538 currently doesn't.
539
540 For viewing through other player's eyes, client can be something other than client->gentity
541 =============
542 */
SV_BuildClientSnapshot(client_t * client)543 static void SV_BuildClientSnapshot( client_t *client ) {
544 vec3_t org;
545 clientSnapshot_t *frame;
546 snapshotEntityNumbers_t entityNumbers;
547 int i;
548 sharedEntity_t *ent;
549 entityState_t *state;
550 svEntity_t *svEnt;
551 sharedEntity_t *clent;
552 playerState_t *ps;
553
554 // bump the counter used to prevent double adding
555 sv.snapshotCounter++;
556
557 // this is the frame we are creating
558 frame = &client->frames[ client->netchan.outgoingSequence & PACKET_MASK ];
559
560 // clear everything in this snapshot
561 entityNumbers.numSnapshotEntities = 0;
562 Com_Memset( frame->areabits, 0, sizeof( frame->areabits ) );
563
564 frame->num_entities = 0;
565
566 clent = client->gentity;
567 if ( !clent || client->state == CS_ZOMBIE ) {
568 return;
569 }
570
571 // grab the current playerState_t
572 ps = SV_GameClientNum( client - svs.clients );
573 frame->ps = *ps;
574 #ifdef _ONEBIT_COMBO
575 frame->pDeltaOneBit = &ps->deltaOneBits;
576 frame->pDeltaNumBit = &ps->deltaNumBits;
577 #endif
578
579 if (ps->m_iVehicleNum)
580 { //get the vehicle's playerstate too then
581 sharedEntity_t *veh = SV_GentityNum(ps->m_iVehicleNum);
582
583 if (veh && veh->playerState)
584 { //Now VMA it and we've got ourselves a playerState
585 playerState_t *vps = ((playerState_t *)VM_ArgPtr((intptr_t)veh->playerState));
586
587 frame->vps = *vps;
588 #ifdef _ONEBIT_COMBO
589 frame->pDeltaOneBitVeh = &vps->deltaOneBits;
590 frame->pDeltaNumBitVeh = &vps->deltaNumBits;
591 #endif
592 }
593 }
594
595 int clientNum;
596 // never send client's own entity, because it can
597 // be regenerated from the playerstate
598 clientNum = frame->ps.clientNum;
599 if ( clientNum < 0 || clientNum >= MAX_GENTITIES ) {
600 Com_Error( ERR_DROP, "SV_SvEntityForGentity: bad gEnt" );
601 }
602 svEnt = &sv.svEntities[ clientNum ];
603 svEnt->snapshotCounter = sv.snapshotCounter;
604
605
606 // find the client's viewpoint
607 VectorCopy( ps->origin, org );
608 org[2] += ps->viewheight;
609
610 // add all the entities directly visible to the eye, which
611 // may include portal entities that merge other viewpoints
612 SV_AddEntitiesVisibleFromPoint( org, frame, &entityNumbers, qfalse );
613
614 // if there were portals visible, there may be out of order entities
615 // in the list which will need to be resorted for the delta compression
616 // to work correctly. This also catches the error condition
617 // of an entity being included twice.
618 qsort( entityNumbers.snapshotEntities, entityNumbers.numSnapshotEntities,
619 sizeof( entityNumbers.snapshotEntities[0] ), SV_QsortEntityNumbers );
620
621 // now that all viewpoint's areabits have been OR'd together, invert
622 // all of them to make it a mask vector, which is what the renderer wants
623 for ( i = 0 ; i < MAX_MAP_AREA_BYTES/4 ; i++ ) {
624 ((int *)frame->areabits)[i] = ((int *)frame->areabits)[i] ^ -1;
625 }
626
627 // copy the entity states out
628 frame->num_entities = 0;
629 frame->first_entity = svs.nextSnapshotEntities;
630 for ( i = 0 ; i < entityNumbers.numSnapshotEntities ; i++ ) {
631 ent = SV_GentityNum(entityNumbers.snapshotEntities[i]);
632 state = &svs.snapshotEntities[svs.nextSnapshotEntities % svs.numSnapshotEntities];
633 *state = ent->s;
634 svs.nextSnapshotEntities++;
635 // this should never hit, map should always be restarted first in SV_Frame
636 if ( svs.nextSnapshotEntities >= 0x7FFFFFFE ) {
637 Com_Error(ERR_FATAL, "svs.nextSnapshotEntities wrapped");
638 }
639 frame->num_entities++;
640 }
641 }
642
643
644 /*
645 ====================
646 SV_RateMsec
647
648 Return the number of msec a given size message is supposed
649 to take to clear, based on the current rate
650 ====================
651 */
652 #define HEADER_RATE_BYTES 48 // include our header, IP header, and some overhead
SV_RateMsec(client_t * client,int messageSize)653 static int SV_RateMsec( client_t *client, int messageSize ) {
654 int rate;
655 int rateMsec;
656
657 // individual messages will never be larger than fragment size
658 if ( messageSize > 1500 ) {
659 messageSize = 1500;
660 }
661 rate = client->rate;
662 if ( sv_maxRate->integer ) {
663 if ( sv_maxRate->integer < 1000 ) {
664 Cvar_Set( "sv_MaxRate", "1000" );
665 }
666 if ( sv_maxRate->integer < rate ) {
667 rate = sv_maxRate->integer;
668 }
669 }
670 if ( sv_minRate->integer ) {
671 if ( sv_minRate->integer < 1000 ) {
672 Cvar_Set( "sv_minRate", "1000" );
673 }
674 if ( sv_minRate->integer > rate ) {
675 rate = sv_minRate->integer;
676 }
677 }
678
679 rateMsec = ( messageSize + HEADER_RATE_BYTES ) * 1000 / ((int) (rate * com_timescale->value));
680
681 return rateMsec;
682 }
683
684 extern void SV_WriteDemoMessage ( client_t *cl, msg_t *msg, int headerBytes );
685 /*
686 =======================
687 SV_SendMessageToClient
688
689 Called by SV_SendClientSnapshot and SV_SendClientGameState
690 =======================
691 */
SV_SendMessageToClient(msg_t * msg,client_t * client)692 void SV_SendMessageToClient( msg_t *msg, client_t *client ) {
693 int rateMsec;
694
695 // MW - my attempt to fix illegible server message errors caused by
696 // packet fragmentation of initial snapshot.
697 while(client->state&&client->netchan.unsentFragments)
698 {
699 // send additional message fragments if the last message
700 // was too large to send at once
701 Com_Printf ("[ISM]SV_SendClientGameState() [1] for %s, writing out old fragments\n", client->name);
702 SV_Netchan_TransmitNextFragment(&client->netchan);
703 }
704
705 // record information about the message
706 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSize = msg->cursize;
707 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSent = svs.time;
708 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageAcked = -1;
709
710 // save the message to demo. this must happen before sending over network as that encodes the backing databuf
711 if ( client->demo.demorecording && !client->demo.demowaiting ) {
712 msg_t msgcopy = *msg;
713 MSG_WriteByte( &msgcopy, svc_EOF );
714 SV_WriteDemoMessage( client, &msgcopy, 0 );
715 }
716
717 // bots need to have their snapshots built, but
718 // they query them directly without needing to be sent
719 if ( client->demo.isBot ) {
720 client->netchan.outgoingSequence++;
721 client->demo.botReliableAcknowledge = client->reliableSent;
722 return;
723 }
724
725 // send the datagram
726 SV_Netchan_Transmit( client, msg ); //msg->cursize, msg->data );
727
728 // set nextSnapshotTime based on rate and requested number of updates
729
730 // local clients get snapshots every server frame
731 // TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=491
732 // added sv_lanForceRate check
733 if ( client->netchan.remoteAddress.type == NA_LOOPBACK || (sv_lanForceRate->integer && Sys_IsLANAddress (client->netchan.remoteAddress)) ) {
734 client->nextSnapshotTime = svs.time + ((int) (1000.0 / sv_fps->integer * com_timescale->value));
735 return;
736 }
737
738 // normal rate / snapshotMsec calculation
739 rateMsec = SV_RateMsec( client, msg->cursize );
740
741 if ( rateMsec < client->snapshotMsec ) {
742 // never send more packets than this, no matter what the rate is at
743 rateMsec = client->snapshotMsec;
744 client->rateDelayed = qfalse;
745 } else {
746 client->rateDelayed = qtrue;
747 }
748
749 client->nextSnapshotTime = svs.time + ((int) (rateMsec * com_timescale->value));
750
751 // don't pile up empty snapshots while connecting
752 if ( client->state != CS_ACTIVE ) {
753 // a gigantic connection message may have already put the nextSnapshotTime
754 // more than a second away, so don't shorten it
755 // do shorten if client is downloading
756 if ( !*client->downloadName && client->nextSnapshotTime < svs.time + ((int) (1000.0 * com_timescale->value)) ) {
757 client->nextSnapshotTime = svs.time + ((int) (1000 * com_timescale->value));
758 }
759 }
760 }
761
762
763 /*
764 =======================
765 SV_SendClientSnapshot
766
767 Also called by SV_FinalMessage
768
769 =======================
770 */
771 extern cvar_t *fs_gamedirvar;
SV_SendClientSnapshot(client_t * client)772 void SV_SendClientSnapshot( client_t *client ) {
773 byte msg_buf[MAX_MSGLEN];
774 msg_t msg;
775
776 if (!client->sentGamedir)
777 { //rww - if this is the case then make sure there is an svc_setgame sent before this snap
778 int i = 0;
779
780 MSG_Init (&msg, msg_buf, sizeof(msg_buf));
781
782 //have to include this for each message.
783 MSG_WriteLong( &msg, client->lastClientCommand );
784
785 MSG_WriteByte (&msg, svc_setgame);
786
787 const char *gamedir = FS_GetCurrentGameDir(true);
788
789 while (gamedir[i])
790 {
791 MSG_WriteByte(&msg, gamedir[i]);
792 i++;
793 }
794 MSG_WriteByte(&msg, 0);
795
796 // MW - my attempt to fix illegible server message errors caused by
797 // packet fragmentation of initial snapshot.
798 //rww - reusing this code here
799 while(client->state&&client->netchan.unsentFragments)
800 {
801 // send additional message fragments if the last message
802 // was too large to send at once
803 Com_Printf ("[ISM]SV_SendClientGameState() [1] for %s, writing out old fragments\n", client->name);
804 SV_Netchan_TransmitNextFragment(&client->netchan);
805 }
806
807 // record information about the message
808 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSize = msg.cursize;
809 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSent = svs.time;
810 client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageAcked = -1;
811
812 // send the datagram
813 SV_Netchan_Transmit( client, &msg ); //msg->cursize, msg->data );
814
815 client->sentGamedir = qtrue;
816 }
817
818 // build the snapshot
819 SV_BuildClientSnapshot( client );
820
821 if ( sv_autoDemo->integer && !client->demo.demorecording ) {
822 if ( client->netchan.remoteAddress.type != NA_BOT || sv_autoDemoBots->integer ) {
823 SV_BeginAutoRecordDemos();
824 }
825 }
826
827 // bots need to have their snapshots built, but
828 // they query them directly without needing to be sent
829 if ( client->netchan.remoteAddress.type == NA_BOT && !client->demo.demorecording ) {
830 return;
831 }
832
833 MSG_Init (&msg, msg_buf, sizeof(msg_buf));
834 msg.allowoverflow = qtrue;
835
836 // NOTE, MRE: all server->client messages now acknowledge
837 // let the client know which reliable clientCommands we have received
838 MSG_WriteLong( &msg, client->lastClientCommand );
839
840 // (re)send any reliable server commands
841 SV_UpdateServerCommandsToClient( client, &msg );
842
843 // send over all the relevant entityState_t
844 // and the playerState_t
845 SV_WriteSnapshotToClient( client, &msg );
846
847 // Add any download data if the client is downloading
848 SV_WriteDownloadToClient( client, &msg );
849
850 // check for overflow
851 if ( msg.overflowed ) {
852 Com_Printf ("WARNING: msg overflowed for %s\n", client->name);
853 MSG_Clear (&msg);
854 }
855
856 SV_SendMessageToClient( &msg, client );
857 }
858
859
860 /*
861 =======================
862 SV_SendClientMessages
863 =======================
864 */
SV_SendClientMessages(void)865 void SV_SendClientMessages( void ) {
866 int i;
867 client_t *c;
868
869 // send a message to each connected client
870 for (i=0, c = svs.clients ; i < sv_maxclients->integer ; i++, c++) {
871 if (!c->state) {
872 continue; // not connected
873 }
874
875 if ( svs.time < c->nextSnapshotTime ) {
876 continue; // not time yet
877 }
878
879 // send additional message fragments if the last message
880 // was too large to send at once
881 if ( c->netchan.unsentFragments ) {
882 c->nextSnapshotTime = svs.time +
883 SV_RateMsec( c, c->netchan.unsentLength - c->netchan.unsentFragmentStart );
884 SV_Netchan_TransmitNextFragment( &c->netchan );
885 continue;
886 }
887
888 // generate and send a new message
889 SV_SendClientSnapshot( c );
890 }
891 }
892
893