|
|
1.1.1.2 ! root 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: */ 1.1 root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.