icculus quake2 doxygen  1.0 dev
sv_send.c
Go to the documentation of this file.
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 // sv_main.c -- server main program
21 
22 #include "server.h"
23 
24 /*
25 =============================================================================
26 
27 Com_Printf redirection
28 
29 =============================================================================
30 */
31 
33 
34 void SV_FlushRedirect (int sv_redirected, char *outputbuf)
35 {
36  if (sv_redirected == RD_PACKET)
37  {
38  Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", outputbuf);
39  }
40  else if (sv_redirected == RD_CLIENT)
41  {
45  }
46 }
47 
48 
49 /*
50 =============================================================================
51 
52 EVENT MESSAGES
53 
54 =============================================================================
55 */
56 
57 
58 /*
59 =================
60 SV_ClientPrintf
61 
62 Sends text across to be displayed if the level passes
63 =================
64 */
65 void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...)
66 {
67  va_list argptr;
68  char string[1024];
69 
70  if (level < cl->messagelevel)
71  return;
72 
73  va_start (argptr,fmt);
74  vsprintf (string, fmt,argptr);
75  va_end (argptr);
76 
77  MSG_WriteByte (&cl->netchan.message, svc_print);
78  MSG_WriteByte (&cl->netchan.message, level);
79  MSG_WriteString (&cl->netchan.message, string);
80 }
81 
82 /*
83 =================
84 SV_BroadcastPrintf
85 
86 Sends text to all active clients
87 =================
88 */
89 void SV_BroadcastPrintf (int level, char *fmt, ...)
90 {
91  va_list argptr;
92  char string[2048];
93  client_t *cl;
94  int i;
95 
96  va_start (argptr,fmt);
97  vsprintf (string, fmt,argptr);
98  va_end (argptr);
99 
100  // echo to console
101  if (dedicated->value)
102  {
103  char copy[1024];
104  int i;
105 
106  // mask off high bits
107  for (i=0 ; i<1023 && string[i] ; i++)
108  copy[i] = string[i]&127;
109  copy[i] = 0;
110  Com_Printf ("%s", copy);
111  }
112 
113  for (i=0, cl = svs.clients ; i<maxclients->value; i++, cl++)
114  {
115  if (level < cl->messagelevel)
116  continue;
117  if (cl->state != cs_spawned)
118  continue;
119  MSG_WriteByte (&cl->netchan.message, svc_print);
120  MSG_WriteByte (&cl->netchan.message, level);
121  MSG_WriteString (&cl->netchan.message, string);
122  }
123 }
124 
125 /*
126 =================
127 SV_BroadcastCommand
128 
129 Sends text to all active clients
130 =================
131 */
132 void SV_BroadcastCommand (char *fmt, ...)
133 {
134  va_list argptr;
135  char string[1024];
136 
137  if (!sv.state)
138  return;
139  va_start (argptr,fmt);
140  vsprintf (string, fmt,argptr);
141  va_end (argptr);
142 
144  MSG_WriteString (&sv.multicast, string);
146 }
147 
148 
149 /*
150 =================
151 SV_Multicast
152 
153 Sends the contents of sv.multicast to a subset of the clients,
154 then clears sv.multicast.
155 
156 MULTICAST_ALL same as broadcast (origin can be NULL)
157 MULTICAST_PVS send to clients potentially visible from org
158 MULTICAST_PHS send to clients potentially hearable from org
159 =================
160 */
161 void SV_Multicast (vec3_t origin, multicast_t to)
162 {
163  client_t *client;
164  byte *mask;
165  int leafnum, cluster;
166  int j;
167  qboolean reliable;
168  int area1, area2;
169 
170  reliable = false;
171 
172  if (to != MULTICAST_ALL_R && to != MULTICAST_ALL)
173  {
174  leafnum = CM_PointLeafnum (origin);
175  area1 = CM_LeafArea (leafnum);
176  }
177  else
178  {
179  leafnum = 0; // just to avoid compiler warnings
180  area1 = 0;
181  }
182 
183  // if doing a serverrecord, store everything
184  if (svs.demofile)
186 
187  switch (to)
188  {
189  case MULTICAST_ALL_R:
190  reliable = true; // intentional fallthrough
191  case MULTICAST_ALL:
192  leafnum = 0;
193  mask = NULL;
194  break;
195 
196  case MULTICAST_PHS_R:
197  reliable = true; // intentional fallthrough
198  case MULTICAST_PHS:
199  leafnum = CM_PointLeafnum (origin);
200  cluster = CM_LeafCluster (leafnum);
201  mask = CM_ClusterPHS (cluster);
202  break;
203 
204  case MULTICAST_PVS_R:
205  reliable = true; // intentional fallthrough
206  case MULTICAST_PVS:
207  leafnum = CM_PointLeafnum (origin);
208  cluster = CM_LeafCluster (leafnum);
209  mask = CM_ClusterPVS (cluster);
210  break;
211 
212  default:
213  mask = NULL;
214  Com_Error (ERR_FATAL, "SV_Multicast: bad to:%i", to);
215  }
216 
217  // send the data to all relevent clients
218  for (j = 0, client = svs.clients; j < maxclients->value; j++, client++)
219  {
220  if (client->state == cs_free || client->state == cs_zombie)
221  continue;
222  if (client->state != cs_spawned && !reliable)
223  continue;
224 
225  if (mask)
226  {
227  leafnum = CM_PointLeafnum (client->edict->s.origin);
228  cluster = CM_LeafCluster (leafnum);
229  area2 = CM_LeafArea (leafnum);
230  if (!CM_AreasConnected (area1, area2))
231  continue;
232  if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
233  continue;
234  }
235 
236  if (reliable)
238  else
240  }
241 
242  SZ_Clear (&sv.multicast);
243 }
244 
245 
246 /*
247 ==================
248 SV_StartSound
249 
250 Each entity can have eight independant sound sources, like voice,
251 weapon, feet, etc.
252 
253 If cahnnel & 8, the sound will be sent to everyone, not just
254 things in the PHS.
255 
256 FIXME: if entity isn't in PHS, they must be forced to be sent or
257 have the origin explicitly sent.
258 
259 Channel 0 is an auto-allocate channel, the others override anything
260 already running on that entity/channel pair.
261 
262 An attenuation of 0 will play full volume everywhere in the level.
263 Larger attenuations will drop off. (max 4 attenuation)
264 
265 Timeofs can range from 0.0 to 0.1 to cause sounds to be started
266 later in the frame than they normally would.
267 
268 If origin is NULL, the origin is determined from the entity origin
269 or the midpoint of the entity box for bmodels.
270 ==================
271 */
272 void SV_StartSound (vec3_t origin, edict_t *entity, int channel,
273  int soundindex, float volume,
274  float attenuation, float timeofs)
275 {
276  int sendchan;
277  int flags;
278  int i;
279  int ent;
280  vec3_t origin_v;
281  qboolean use_phs;
282 
283  if (volume < 0 || volume > 1.0)
284  Com_Error (ERR_FATAL, "SV_StartSound: volume = %f", volume);
285 
286  if (attenuation < 0 || attenuation > 4)
287  Com_Error (ERR_FATAL, "SV_StartSound: attenuation = %f", attenuation);
288 
289 // if (channel < 0 || channel > 15)
290 // Com_Error (ERR_FATAL, "SV_StartSound: channel = %i", channel);
291 
292  if (timeofs < 0 || timeofs > 0.255)
293  Com_Error (ERR_FATAL, "SV_StartSound: timeofs = %f", timeofs);
294 
295  ent = NUM_FOR_EDICT(entity);
296 
297  if (channel & 8) // no PHS flag
298  {
299  use_phs = false;
300  channel &= 7;
301  }
302  else
303  use_phs = true;
304 
305  sendchan = (ent<<3) | (channel&7);
306 
307  flags = 0;
308  if (volume != DEFAULT_SOUND_PACKET_VOLUME)
309  flags |= SND_VOLUME;
310  if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
311  flags |= SND_ATTENUATION;
312 
313  // the client doesn't know that bmodels have weird origins
314  // the origin can also be explicitly set
315  if ( (entity->svflags & SVF_NOCLIENT)
316  || (entity->solid == SOLID_BSP)
317  || origin )
318  flags |= SND_POS;
319 
320  // always send the entity number for channel overrides
321  flags |= SND_ENT;
322 
323  if (timeofs)
324  flags |= SND_OFFSET;
325 
326  // use the entity origin unless it is a bmodel or explicitly specified
327  if (!origin)
328  {
329  origin = origin_v;
330  if (entity->solid == SOLID_BSP)
331  {
332  for (i=0 ; i<3 ; i++)
333  origin_v[i] = entity->s.origin[i]+0.5*(entity->mins[i]+entity->maxs[i]);
334  }
335  else
336  {
337  VectorCopy (entity->s.origin, origin_v);
338  }
339  }
340 
342  MSG_WriteByte (&sv.multicast, flags);
343  MSG_WriteByte (&sv.multicast, soundindex);
344 
345  if (flags & SND_VOLUME)
346  MSG_WriteByte (&sv.multicast, volume*255);
347  if (flags & SND_ATTENUATION)
348  MSG_WriteByte (&sv.multicast, attenuation*64);
349  if (flags & SND_OFFSET)
350  MSG_WriteByte (&sv.multicast, timeofs*1000);
351 
352  if (flags & SND_ENT)
353  MSG_WriteShort (&sv.multicast, sendchan);
354 
355  if (flags & SND_POS)
356  MSG_WritePos (&sv.multicast, origin);
357 
358  // if the sound doesn't attenuate,send it to everyone
359  // (global radio chatter, voiceovers, etc)
360  if (attenuation == ATTN_NONE)
361  use_phs = false;
362 
363  if (channel & CHAN_RELIABLE)
364  {
365  if (use_phs)
366  SV_Multicast (origin, MULTICAST_PHS_R);
367  else
368  SV_Multicast (origin, MULTICAST_ALL_R);
369  }
370  else
371  {
372  if (use_phs)
373  SV_Multicast (origin, MULTICAST_PHS);
374  else
375  SV_Multicast (origin, MULTICAST_ALL);
376  }
377 }
378 
379 
380 /*
381 ===============================================================================
382 
383 FRAME UPDATES
384 
385 ===============================================================================
386 */
387 
388 
389 
390 /*
391 =======================
392 SV_SendClientDatagram
393 =======================
394 */
396 {
397  byte msg_buf[MAX_MSGLEN];
398  sizebuf_t msg;
399 
400  SV_BuildClientFrame (client);
401 
402  SZ_Init (&msg, msg_buf, sizeof(msg_buf));
403  msg.allowoverflow = true;
404 
405  // send over all the relevant entity_state_t
406  // and the player_state_t
407  SV_WriteFrameToClient (client, &msg);
408 
409  // copy the accumulated multicast datagram
410  // for this client out to the message
411  // it is necessary for this to be after the WriteEntities
412  // so that entity references will be current
413  if (client->datagram.overflowed)
414  Com_Printf ("WARNING: datagram overflowed for %s\n", client->name);
415  else
416  SZ_Write (&msg, client->datagram.data, client->datagram.cursize);
417  SZ_Clear (&client->datagram);
418 
419  if (msg.overflowed)
420  { // must have room left for the packet header
421  Com_Printf ("WARNING: msg overflowed for %s\n", client->name);
422  SZ_Clear (&msg);
423  }
424 
425  // send the datagram
426  Netchan_Transmit (&client->netchan, msg.cursize, msg.data);
427 
428  // record the size for rate estimation
429  client->message_size[sv.framenum % RATE_MESSAGES] = msg.cursize;
430 
431  return true;
432 }
433 
434 
435 /*
436 ==================
437 SV_DemoCompleted
438 ==================
439 */
440 void SV_DemoCompleted (void)
441 {
442  if (sv.demofile)
443  {
444  fclose (sv.demofile);
445  sv.demofile = NULL;
446  }
447  SV_Nextserver ();
448 }
449 
450 
451 /*
452 =======================
453 SV_RateDrop
454 
455 Returns true if the client is over its current
456 bandwidth estimation and should not be sent another packet
457 =======================
458 */
460 {
461  int total;
462  int i;
463 
464  // never drop over the loopback
466  return false;
467 
468  total = 0;
469 
470  for (i = 0 ; i < RATE_MESSAGES ; i++)
471  {
472  total += c->message_size[i];
473  }
474 
475  if (total > c->rate)
476  {
477  c->surpressCount++;
479  return true;
480  }
481 
482  return false;
483 }
484 
485 /*
486 =======================
487 SV_SendClientMessages
488 =======================
489 */
491 {
492  int i;
493  client_t *c;
494  int msglen;
495  byte msgbuf[MAX_MSGLEN];
496  int r;
497 
498  msglen = 0;
499 
500  // read the next demo message if needed
501  if (sv.state == ss_demo && sv.demofile)
502  {
503  if (sv_paused->value)
504  msglen = 0;
505  else
506  {
507  // get the next message
508  r = fread (&msglen, 4, 1, sv.demofile);
509  if (r != 1)
510  {
511  SV_DemoCompleted ();
512  return;
513  }
514  msglen = LittleLong (msglen);
515  if (msglen == -1)
516  {
517  SV_DemoCompleted ();
518  return;
519  }
520  if (msglen > MAX_MSGLEN)
521  Com_Error (ERR_DROP, "SV_SendClientMessages: msglen > MAX_MSGLEN");
522  r = fread (msgbuf, msglen, 1, sv.demofile);
523  if (r != 1)
524  {
525  SV_DemoCompleted ();
526  return;
527  }
528  }
529  }
530 
531  // send a message to each connected client
532  for (i=0, c = svs.clients ; i<maxclients->value; i++, c++)
533  {
534  if (!c->state)
535  continue;
536  // if the reliable message overflowed,
537  // drop the client
538  if (c->netchan.message.overflowed)
539  {
540  SZ_Clear (&c->netchan.message);
541  SZ_Clear (&c->datagram);
542  SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name);
543  SV_DropClient (c);
544  }
545 
546  if (sv.state == ss_cinematic
547  || sv.state == ss_demo
548  || sv.state == ss_pic
549  )
550  Netchan_Transmit (&c->netchan, msglen, msgbuf);
551  else if (c->state == cs_spawned)
552  {
553  // don't overrun bandwidth
554  if (SV_RateDrop (c))
555  continue;
556 
558  }
559  else
560  {
561  // just update reliable if needed
562  if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1000 )
563  Netchan_Transmit (&c->netchan, 0, NULL);
564  }
565  }
566 }
567 
server_t::framenum
int framenum
Definition: server.h:51
cs_zombie
@ cs_zombie
Definition: server.h:76
sv
server_t sv
Definition: sv_init.c:24
SV_DemoCompleted
void SV_DemoCompleted(void)
Definition: sv_send.c:440
edict_s::s
entity_state_t s
Definition: g_local.h:964
dedicated
cvar_t * dedicated
Definition: common.c:47
curtime
int curtime
Definition: q_shwin.c:119
sizebuf_s
Definition: qcommon.h:75
value
GLfloat value
Definition: qgl_win.c:63
client_s::datagram
sizebuf_t datagram
Definition: server.h:120
client_s::message_size
int message_size[RATE_MESSAGES]
Definition: server.h:110
SND_POS
#define SND_POS
Definition: qcommon.h:286
SND_OFFSET
#define SND_OFFSET
Definition: qcommon.h:288
NS_SERVER
@ NS_SERVER
Definition: qcommon.h:536
RD_CLIENT
@ RD_CLIENT
Definition: server.h:242
netchan_t::message
sizebuf_t message
Definition: qcommon.h:600
entity_state_s::origin
vec3_t origin
Definition: q_shared.h:1173
SVF_NOCLIENT
#define SVF_NOCLIENT
Definition: game.h:27
net_from
netadr_t net_from
Definition: net_chan.c:81
sizebuf_s::overflowed
qboolean overflowed
Definition: qcommon.h:78
DEFAULT_SOUND_PACKET_VOLUME
#define DEFAULT_SOUND_PACKET_VOLUME
Definition: qcommon.h:290
qboolean
qboolean
Definition: q_shared.h:56
i
int i
Definition: q_shared.c:305
server_t::multicast
sizebuf_t multicast
Definition: server.h:61
RATE_MESSAGES
#define RATE_MESSAGES
Definition: server.h:93
client_s::name
char name[32]
Definition: server.h:115
SZ_Init
void SZ_Init(sizebuf_t *buf, byte *data, int length)
Definition: common.c:904
client_s::state
client_state_t state
Definition: server.h:97
edict_s::mins
vec3_t mins
Definition: g_local.h:984
sizebuf_s::data
byte * data
Definition: qcommon.h:79
server_t::demofile
FILE * demofile
Definition: server.h:65
CHAN_RELIABLE
#define CHAN_RELIABLE
Definition: q_shared.h:1014
SZ_Write
void SZ_Write(sizebuf_t *buf, void *data, int length)
Definition: common.c:940
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: common.c:911
CM_LeafArea
int CM_LeafArea(int leafnum)
Definition: cmodel.c:681
j
GLint j
Definition: qgl_win.c:150
msg
cvar_t * msg
Definition: cl_main.c:98
ATTN_NONE
#define ATTN_NONE
Definition: q_shared.h:1018
server_static_t::clients
client_t * clients
Definition: server.h:168
MULTICAST_PHS
@ MULTICAST_PHS
Definition: q_shared.h:110
client_s::netchan
netchan_t netchan
Definition: server.h:134
ss_cinematic
@ ss_cinematic
Definition: server.h:36
edict_s::svflags
int svflags
Definition: g_local.h:983
SND_ATTENUATION
#define SND_ATTENUATION
Definition: qcommon.h:285
edict_s
Definition: g_local.h:962
CM_ClusterPVS
byte * CM_ClusterPVS(int cluster)
Definition: cmodel.c:1575
r
GLdouble GLdouble r
Definition: qgl_win.c:336
CM_AreasConnected
qboolean CM_AreasConnected(int area1, int area2)
Definition: cmodel.c:1662
LittleLong
int LittleLong(int l)
Definition: q_shared.c:948
SV_BuildClientFrame
void SV_BuildClientFrame(client_t *client)
Definition: sv_ents.c:524
netchan_t::last_sent
int last_sent
Definition: qcommon.h:583
NUM_FOR_EDICT
#define NUM_FOR_EDICT(e)
Definition: server.h:70
ss_demo
@ ss_demo
Definition: server.h:37
multicast_t
multicast_t
Definition: q_shared.h:107
sv_client
client_t * sv_client
Definition: sv_main.c:25
cs_free
@ cs_free
Definition: server.h:75
SV_DropClient
void SV_DropClient(client_t *drop)
Definition: sv_main.c:70
MULTICAST_ALL_R
@ MULTICAST_ALL_R
Definition: q_shared.h:112
SV_Multicast
void SV_Multicast(vec3_t origin, multicast_t to)
Definition: sv_send.c:161
DEFAULT_SOUND_PACKET_ATTENUATION
#define DEFAULT_SOUND_PACKET_ATTENUATION
Definition: qcommon.h:291
cvar_s::value
float value
Definition: q_shared.h:324
SV_FlushRedirect
void SV_FlushRedirect(int sv_redirected, char *outputbuf)
Definition: sv_send.c:34
SV_StartSound
void SV_StartSound(vec3_t origin, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
Definition: sv_send.c:272
MSG_WritePos
void MSG_WritePos(sizebuf_t *sb, vec3_t pos)
Definition: common.c:388
PRINT_HIGH
#define PRINT_HIGH
Definition: q_shared.h:92
SV_Nextserver
void SV_Nextserver(void)
Definition: sv_user.c:405
MSG_WriteString
void MSG_WriteString(sizebuf_t *sb, char *s)
Definition: common.c:375
NULL
#define NULL
Definition: q_shared.h:60
edict_s::solid
solid_t solid
Definition: g_local.h:986
MSG_WriteShort
void MSG_WriteShort(sizebuf_t *sb, int c)
Definition: common.c:335
MSG_WriteByte
void MSG_WriteByte(sizebuf_t *sb, int c)
Definition: common.c:322
Com_Error
void Com_Error(int code, char *fmt,...)
Definition: common.c:203
ERR_DROP
#define ERR_DROP
Definition: qcommon.h:736
svs
server_static_t svs
Definition: sv_init.c:23
SV_OUTPUTBUF_LENGTH
#define SV_OUTPUTBUF_LENGTH
Definition: server.h:243
SND_VOLUME
#define SND_VOLUME
Definition: qcommon.h:284
netchan_t::remote_address
netadr_t remote_address
Definition: qcommon.h:585
ERR_FATAL
#define ERR_FATAL
Definition: qcommon.h:735
sv_outputbuf
char sv_outputbuf[SV_OUTPUTBUF_LENGTH]
Definition: sv_send.c:32
MAX_MSGLEN
#define MAX_MSGLEN
Definition: qcommon.h:527
netadr_t::type
netadrtype_t type
Definition: qcommon.h:540
SV_BroadcastCommand
void SV_BroadcastCommand(char *fmt,...)
Definition: sv_send.c:132
client_s::surpressCount
int surpressCount
Definition: server.h:112
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:158
SV_RateDrop
qboolean SV_RateDrop(client_t *c)
Definition: sv_send.c:459
CM_ClusterPHS
byte * CM_ClusterPHS(int cluster)
Definition: cmodel.c:1584
cs_spawned
@ cs_spawned
Definition: server.h:79
SV_ClientPrintf
void SV_ClientPrintf(client_t *cl, int level, char *fmt,...)
Definition: sv_send.c:65
MULTICAST_PHS_R
@ MULTICAST_PHS_R
Definition: q_shared.h:113
SV_WriteFrameToClient
void SV_WriteFrameToClient(client_t *client, sizebuf_t *msg)
Definition: sv_ents.c:415
level
GLint level
Definition: qgl_win.c:116
CM_LeafCluster
int CM_LeafCluster(int leafnum)
Definition: cmodel.c:674
MULTICAST_PVS_R
@ MULTICAST_PVS_R
Definition: q_shared.h:114
SOLID_BSP
@ SOLID_BSP
Definition: game.h:38
edict_s::maxs
vec3_t maxs
Definition: g_local.h:984
SV_SendClientDatagram
qboolean SV_SendClientDatagram(client_t *client)
Definition: sv_send.c:395
Netchan_Transmit
void Netchan_Transmit(netchan_t *chan, int length, byte *data)
Definition: net_chan.c:213
server_t::state
server_state_t state
Definition: server.h:45
sizebuf_s::cursize
int cursize
Definition: qcommon.h:81
Netchan_OutOfBandPrint
void Netchan_OutOfBandPrint(int net_socket, netadr_t adr, char *format,...)
Definition: net_chan.c:132
sv_paused
cvar_t * sv_paused
Definition: sv_main.c:27
client_s
Definition: server.h:95
Com_Printf
void Com_Printf(char *fmt,...)
Definition: common.c:102
MULTICAST_ALL
@ MULTICAST_ALL
Definition: q_shared.h:109
SND_ENT
#define SND_ENT
Definition: qcommon.h:287
server.h
mask
GLint GLuint mask
Definition: qgl_win.c:317
svc_sound
@ svc_sound
Definition: qcommon.h:218
client_s::rate
int rate
Definition: server.h:111
ss_pic
@ ss_pic
Definition: server.h:38
server_static_t::demo_multicast
sizebuf_t demo_multicast
Definition: server.h:179
svc_stufftext
@ svc_stufftext
Definition: qcommon.h:220
RD_PACKET
@ RD_PACKET
Definition: server.h:242
cl
client_state_t cl
Definition: cl_main.c:106
SV_SendClientMessages
void SV_SendClientMessages(void)
Definition: sv_send.c:490
MULTICAST_PVS
@ MULTICAST_PVS
Definition: q_shared.h:111
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:127
NA_LOOPBACK
@ NA_LOOPBACK
Definition: qcommon.h:533
CM_PointLeafnum
int CM_PointLeafnum(vec3_t p)
Definition: cmodel.c:826
svc_print
@ svc_print
Definition: qcommon.h:219
server_static_t::demofile
FILE * demofile
Definition: server.h:178
SV_BroadcastPrintf
void SV_BroadcastPrintf(int level, char *fmt,...)
Definition: sv_send.c:89
client_s::edict
edict_t * edict
Definition: server.h:114