File: server\sv_send.c
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
32 char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
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 {
42 MSG_WriteByte (&sv_client->netchan.message, svc_print);
43 MSG_WriteByte (&sv_client->netchan.message, PRINT_HIGH);
44 MSG_WriteString (&sv_client->netchan.message, outputbuf);
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
143 MSG_WriteByte (&sv.multicast, svc_stufftext);
144 MSG_WriteString (&sv.multicast, string);
145 SV_Multicast (NULL, MULTICAST_ALL_R);
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)
185 SZ_Write (&svs.demo_multicast, sv.multicast.data, sv.multicast.cursize);
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)
237 SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
238 else
239 SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
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
341 MSG_WriteByte (&sv.multicast, svc_sound);
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 */
395 qboolean SV_SendClientDatagram (client_t *client)
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 */
459 qboolean SV_RateDrop (client_t *c)
460 {
461 int total;
462 int i;
463
464 // never drop over the loopback
465 if (c->netchan.remote_address.type == NA_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++;
478 c->message_size[sv.framenum % RATE_MESSAGES] = 0;
479 return true;
480 }
481
482 return false;
483 }
484
485 /*
486 =======================
487 SV_SendClientMessages
488 =======================
489 */
490 void SV_SendClientMessages (void)
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
557 SV_SendClientDatagram (c);
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
568