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