sv_send.c (12612B)
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