|
|
1.1 ! root 1: // net_main.c ! 2: ! 3: #include "quakedef.h" ! 4: #include "net_vcr.h" ! 5: ! 6: qsocket_t *net_activeSockets = NULL; ! 7: qsocket_t *net_freeSockets = NULL; ! 8: int net_numsockets = 0; ! 9: ! 10: qboolean serialAvailable = false; ! 11: qboolean ipxAvailable = false; ! 12: qboolean tcpipAvailable = false; ! 13: ! 14: int net_hostport; ! 15: int DEFAULTnet_hostport = 26000; ! 16: ! 17: char my_ipx_address[NET_NAMELEN]; ! 18: char my_tcpip_address[NET_NAMELEN]; ! 19: ! 20: void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); ! 21: void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); ! 22: void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); ! 23: void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); ! 24: ! 25: static qboolean listening = false; ! 26: ! 27: qboolean slistInProgress = false; ! 28: qboolean slistSilent = false; ! 29: qboolean slistLocal = true; ! 30: static double slistStartTime; ! 31: static int slistLastShown; ! 32: ! 33: static void Slist_Send(void); ! 34: static void Slist_Poll(void); ! 35: PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send}; ! 36: PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll}; ! 37: ! 38: ! 39: sizebuf_t net_message; ! 40: int net_activeconnections = 0; ! 41: ! 42: int messagesSent = 0; ! 43: int messagesReceived = 0; ! 44: int unreliableMessagesSent = 0; ! 45: int unreliableMessagesReceived = 0; ! 46: ! 47: cvar_t net_messagetimeout = {"net_messagetimeout","300"}; ! 48: cvar_t hostname = {"hostname", "UNNAMED"}; ! 49: ! 50: qboolean configRestored = false; ! 51: cvar_t config_com_port = {"_config_com_port", "0x3f8", true}; ! 52: cvar_t config_com_irq = {"_config_com_irq", "4", true}; ! 53: cvar_t config_com_baud = {"_config_com_baud", "57600", true}; ! 54: cvar_t config_com_modem = {"_config_com_modem", "1", true}; ! 55: cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true}; ! 56: cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true}; ! 57: cvar_t config_modem_init = {"_config_modem_init", "", true}; ! 58: cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true}; ! 59: ! 60: #ifdef IDGODS ! 61: cvar_t idgods = {"idgods", "0"}; ! 62: #endif ! 63: ! 64: int vcrFile = -1; ! 65: qboolean recording = false; ! 66: ! 67: // these two macros are to make the code more readable ! 68: #define sfunc net_drivers[sock->driver] ! 69: #define dfunc net_drivers[net_driverlevel] ! 70: ! 71: int net_driverlevel; ! 72: ! 73: ! 74: double net_time; ! 75: ! 76: double SetNetTime(void) ! 77: { ! 78: net_time = Sys_FloatTime(); ! 79: return net_time; ! 80: } ! 81: ! 82: ! 83: /* ! 84: =================== ! 85: NET_NewQSocket ! 86: ! 87: Called by drivers when a new communications endpoint is required ! 88: The sequence and buffer fields will be filled in properly ! 89: =================== ! 90: */ ! 91: qsocket_t *NET_NewQSocket (void) ! 92: { ! 93: qsocket_t *sock; ! 94: ! 95: if (net_freeSockets == NULL) ! 96: return NULL; ! 97: ! 98: if (net_activeconnections >= svs.maxclients) ! 99: return NULL; ! 100: ! 101: // get one from free list ! 102: sock = net_freeSockets; ! 103: net_freeSockets = sock->next; ! 104: ! 105: // add it to active list ! 106: sock->next = net_activeSockets; ! 107: net_activeSockets = sock; ! 108: ! 109: sock->disconnected = false; ! 110: sock->connecttime = net_time; ! 111: Q_strcpy (sock->address,"UNSET ADDRESS"); ! 112: sock->driver = net_driverlevel; ! 113: sock->socket = 0; ! 114: sock->driverdata = NULL; ! 115: sock->canSend = true; ! 116: sock->sendNext = false; ! 117: sock->lastMessageTime = net_time; ! 118: sock->ackSequence = 0; ! 119: sock->sendSequence = 0; ! 120: sock->unreliableSendSequence = 0; ! 121: sock->sendMessageLength = 0; ! 122: sock->receiveSequence = 0; ! 123: sock->unreliableReceiveSequence = 0; ! 124: sock->receiveMessageLength = 0; ! 125: ! 126: return sock; ! 127: } ! 128: ! 129: ! 130: void NET_FreeQSocket(qsocket_t *sock) ! 131: { ! 132: qsocket_t *s; ! 133: ! 134: // remove it from active list ! 135: if (sock == net_activeSockets) ! 136: net_activeSockets = net_activeSockets->next; ! 137: else ! 138: { ! 139: for (s = net_activeSockets; s; s = s->next) ! 140: if (s->next == sock) ! 141: { ! 142: s->next = sock->next; ! 143: break; ! 144: } ! 145: if (!s) ! 146: Sys_Error ("NET_FreeQSocket: not active\n"); ! 147: } ! 148: ! 149: // add it to free list ! 150: sock->next = net_freeSockets; ! 151: net_freeSockets = sock; ! 152: sock->disconnected = true; ! 153: } ! 154: ! 155: ! 156: static void NET_Listen_f (void) ! 157: { ! 158: if (Cmd_Argc () != 2) ! 159: { ! 160: Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0); ! 161: return; ! 162: } ! 163: ! 164: listening = Q_atoi(Cmd_Argv(1)) ? true : false; ! 165: ! 166: for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++) ! 167: { ! 168: if (net_drivers[net_driverlevel].initialized == false) ! 169: continue; ! 170: dfunc.Listen (listening); ! 171: } ! 172: } ! 173: ! 174: ! 175: static void MaxPlayers_f (void) ! 176: { ! 177: int n; ! 178: ! 179: if (Cmd_Argc () != 2) ! 180: { ! 181: Con_Printf ("\"maxplayers\" is \"%u\"\n", svs.maxclients); ! 182: return; ! 183: } ! 184: ! 185: if (sv.active) ! 186: { ! 187: Con_Printf ("maxplayers can not be changed while a server is running.\n"); ! 188: return; ! 189: } ! 190: ! 191: n = Q_atoi(Cmd_Argv(1)); ! 192: if (n < 1) ! 193: n = 1; ! 194: if (n > svs.maxclientslimit) ! 195: { ! 196: n = svs.maxclientslimit; ! 197: Con_Printf ("\"maxplayers\" set to \"%u\"\n", n); ! 198: } ! 199: ! 200: if (n == 1 && svs.maxclients > 1) ! 201: Cbuf_AddText ("listen 0\n"); ! 202: ! 203: if (n > 1 && svs.maxclients == 1) ! 204: Cbuf_AddText ("listen 1\n"); ! 205: ! 206: svs.maxclients = n; ! 207: if (n == 1) ! 208: Cvar_Set ("deathmatch", "0"); ! 209: else ! 210: Cvar_Set ("deathmatch", "1"); ! 211: } ! 212: ! 213: ! 214: static void NET_Port_f (void) ! 215: { ! 216: int n; ! 217: ! 218: if (Cmd_Argc () != 2) ! 219: { ! 220: Con_Printf ("\"port\" is \"%u\"\n", net_hostport); ! 221: return; ! 222: } ! 223: ! 224: n = Q_atoi(Cmd_Argv(1)); ! 225: if (n < 1 || n > 65534) ! 226: { ! 227: Con_Printf ("Bad value, must be between 1 and 65534\n"); ! 228: return; ! 229: } ! 230: ! 231: DEFAULTnet_hostport = n; ! 232: net_hostport = n; ! 233: ! 234: if (listening) ! 235: { ! 236: // force a change to the new port ! 237: Cbuf_AddText ("listen 0\n"); ! 238: Cbuf_AddText ("listen 1\n"); ! 239: } ! 240: } ! 241: ! 242: ! 243: static void PrintSlistHeader(void) ! 244: { ! 245: Con_Printf("Server Map Users\n"); ! 246: Con_Printf("--------------- --------------- -----\n"); ! 247: slistLastShown = 0; ! 248: } ! 249: ! 250: ! 251: static void PrintSlist(void) ! 252: { ! 253: int n; ! 254: ! 255: for (n = slistLastShown; n < hostCacheCount; n++) ! 256: { ! 257: if (hostcache[n].maxusers) ! 258: Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); ! 259: else ! 260: Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); ! 261: } ! 262: slistLastShown = n; ! 263: } ! 264: ! 265: ! 266: static void PrintSlistTrailer(void) ! 267: { ! 268: if (hostCacheCount) ! 269: Con_Printf("== end list ==\n\n"); ! 270: else ! 271: Con_Printf("No Quake servers found.\n\n"); ! 272: } ! 273: ! 274: ! 275: void NET_Slist_f (void) ! 276: { ! 277: if (slistInProgress) ! 278: return; ! 279: ! 280: if (! slistSilent) ! 281: { ! 282: Con_Printf("Looking for Quake servers...\n"); ! 283: PrintSlistHeader(); ! 284: } ! 285: ! 286: slistInProgress = true; ! 287: slistStartTime = Sys_FloatTime(); ! 288: ! 289: SchedulePollProcedure(&slistSendProcedure, 0.0); ! 290: SchedulePollProcedure(&slistPollProcedure, 0.1); ! 291: ! 292: hostCacheCount = 0; ! 293: } ! 294: ! 295: ! 296: static void Slist_Send(void) ! 297: { ! 298: for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) ! 299: { ! 300: if (!slistLocal && net_driverlevel == 0) ! 301: continue; ! 302: if (net_drivers[net_driverlevel].initialized == false) ! 303: continue; ! 304: dfunc.SearchForHosts (true); ! 305: } ! 306: ! 307: if ((Sys_FloatTime() - slistStartTime) < 0.5) ! 308: SchedulePollProcedure(&slistSendProcedure, 0.75); ! 309: } ! 310: ! 311: ! 312: static void Slist_Poll(void) ! 313: { ! 314: for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) ! 315: { ! 316: if (!slistLocal && net_driverlevel == 0) ! 317: continue; ! 318: if (net_drivers[net_driverlevel].initialized == false) ! 319: continue; ! 320: dfunc.SearchForHosts (false); ! 321: } ! 322: ! 323: if (! slistSilent) ! 324: PrintSlist(); ! 325: ! 326: if ((Sys_FloatTime() - slistStartTime) < 1.5) ! 327: { ! 328: SchedulePollProcedure(&slistPollProcedure, 0.1); ! 329: return; ! 330: } ! 331: ! 332: if (! slistSilent) ! 333: PrintSlistTrailer(); ! 334: slistInProgress = false; ! 335: slistSilent = false; ! 336: slistLocal = true; ! 337: } ! 338: ! 339: ! 340: /* ! 341: =================== ! 342: NET_Connect ! 343: =================== ! 344: */ ! 345: ! 346: int hostCacheCount = 0; ! 347: hostcache_t hostcache[HOSTCACHESIZE]; ! 348: ! 349: qsocket_t *NET_Connect (char *host) ! 350: { ! 351: qsocket_t *ret; ! 352: int n; ! 353: ! 354: SetNetTime(); ! 355: ! 356: if (host && *host == 0) ! 357: host = NULL; ! 358: ! 359: if (host && hostCacheCount) ! 360: { ! 361: for (n = 0; n < hostCacheCount; n++) ! 362: if (Q_strcasecmp (host, hostcache[n].name) == 0) ! 363: { ! 364: host = hostcache[n].cname; ! 365: break; ! 366: } ! 367: if (n < hostCacheCount) ! 368: goto JustDoIt; ! 369: } ! 370: ! 371: slistSilent = host ? true : false; ! 372: NET_Slist_f (); ! 373: ! 374: while(slistInProgress) ! 375: NET_Poll(); ! 376: ! 377: if (host == NULL) ! 378: { ! 379: if (hostCacheCount != 1) ! 380: return NULL; ! 381: host = hostcache[0].cname; ! 382: Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host); ! 383: } ! 384: ! 385: if (hostCacheCount) ! 386: for (n = 0; n < hostCacheCount; n++) ! 387: if (Q_strcasecmp (host, hostcache[n].name) == 0) ! 388: { ! 389: host = hostcache[n].cname; ! 390: break; ! 391: } ! 392: ! 393: JustDoIt: ! 394: for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++) ! 395: { ! 396: if (net_drivers[net_driverlevel].initialized == false) ! 397: continue; ! 398: ret = dfunc.Connect (host); ! 399: if (ret) ! 400: return ret; ! 401: } ! 402: ! 403: if (host) ! 404: { ! 405: Con_Printf("\n"); ! 406: PrintSlistHeader(); ! 407: PrintSlist(); ! 408: PrintSlistTrailer(); ! 409: } ! 410: ! 411: return NULL; ! 412: } ! 413: ! 414: ! 415: /* ! 416: =================== ! 417: NET_CheckNewConnections ! 418: =================== ! 419: */ ! 420: ! 421: struct ! 422: { ! 423: double time; ! 424: int op; ! 425: long session; ! 426: } vcrConnect; ! 427: ! 428: qsocket_t *NET_CheckNewConnections (void) ! 429: { ! 430: qsocket_t *ret; ! 431: ! 432: SetNetTime(); ! 433: ! 434: for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++) ! 435: { ! 436: if (net_drivers[net_driverlevel].initialized == false) ! 437: continue; ! 438: if (net_driverlevel && listening == false) ! 439: continue; ! 440: ret = dfunc.CheckNewConnections (); ! 441: if (ret) ! 442: { ! 443: if (recording) ! 444: { ! 445: vcrConnect.time = host_time; ! 446: vcrConnect.op = VCR_OP_CONNECT; ! 447: vcrConnect.session = (long)ret; ! 448: Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect)); ! 449: Sys_FileWrite (vcrFile, ret->address, NET_NAMELEN); ! 450: } ! 451: return ret; ! 452: } ! 453: } ! 454: ! 455: if (recording) ! 456: { ! 457: vcrConnect.time = host_time; ! 458: vcrConnect.op = VCR_OP_CONNECT; ! 459: vcrConnect.session = 0; ! 460: Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect)); ! 461: } ! 462: ! 463: return NULL; ! 464: } ! 465: ! 466: /* ! 467: =================== ! 468: NET_Close ! 469: =================== ! 470: */ ! 471: void NET_Close (qsocket_t *sock) ! 472: { ! 473: if (!sock) ! 474: return; ! 475: ! 476: if (sock->disconnected) ! 477: return; ! 478: ! 479: SetNetTime(); ! 480: ! 481: // call the driver_Close function ! 482: sfunc.Close (sock); ! 483: ! 484: NET_FreeQSocket(sock); ! 485: } ! 486: ! 487: ! 488: /* ! 489: ================= ! 490: NET_GetMessage ! 491: ! 492: If there is a complete message, return it in net_message ! 493: ! 494: returns 0 if no data is waiting ! 495: returns 1 if a message was received ! 496: returns -1 if connection is invalid ! 497: ================= ! 498: */ ! 499: ! 500: struct ! 501: { ! 502: double time; ! 503: int op; ! 504: long session; ! 505: int ret; ! 506: int len; ! 507: } vcrGetMessage; ! 508: ! 509: extern void PrintStats(qsocket_t *s); ! 510: ! 511: int NET_GetMessage (qsocket_t *sock) ! 512: { ! 513: int ret; ! 514: ! 515: if (!sock) ! 516: return -1; ! 517: ! 518: if (sock->disconnected) ! 519: { ! 520: Con_Printf("NET_GetMessage: disconnected socket\n"); ! 521: return -1; ! 522: } ! 523: ! 524: SetNetTime(); ! 525: ! 526: ret = sfunc.GetMessage(sock); ! 527: ! 528: // see if this connection has timed out ! 529: if (ret == 0 && sock->driver) ! 530: { ! 531: if (net_time - sock->lastMessageTime > net_messagetimeout.value) ! 532: { ! 533: NET_Close(sock); ! 534: return -1; ! 535: } ! 536: } ! 537: ! 538: ! 539: if (ret > 0) ! 540: { ! 541: if (sock->driver) ! 542: { ! 543: sock->lastMessageTime = net_time; ! 544: if (ret == 1) ! 545: messagesReceived++; ! 546: else if (ret == 2) ! 547: unreliableMessagesReceived++; ! 548: } ! 549: ! 550: if (recording) ! 551: { ! 552: vcrGetMessage.time = host_time; ! 553: vcrGetMessage.op = VCR_OP_GETMESSAGE; ! 554: vcrGetMessage.session = (long)sock; ! 555: vcrGetMessage.ret = ret; ! 556: vcrGetMessage.len = net_message.cursize; ! 557: Sys_FileWrite (vcrFile, &vcrGetMessage, 24); ! 558: Sys_FileWrite (vcrFile, net_message.data, net_message.cursize); ! 559: } ! 560: } ! 561: else ! 562: { ! 563: if (recording) ! 564: { ! 565: vcrGetMessage.time = host_time; ! 566: vcrGetMessage.op = VCR_OP_GETMESSAGE; ! 567: vcrGetMessage.session = (long)sock; ! 568: vcrGetMessage.ret = ret; ! 569: Sys_FileWrite (vcrFile, &vcrGetMessage, 20); ! 570: } ! 571: } ! 572: ! 573: return ret; ! 574: } ! 575: ! 576: ! 577: /* ! 578: ================== ! 579: NET_SendMessage ! 580: ! 581: Try to send a complete length+message unit over the reliable stream. ! 582: returns 0 if the message cannot be delivered reliably, but the connection ! 583: is still considered valid ! 584: returns 1 if the message was sent properly ! 585: returns -1 if the connection died ! 586: ================== ! 587: */ ! 588: struct ! 589: { ! 590: double time; ! 591: int op; ! 592: long session; ! 593: int r; ! 594: } vcrSendMessage; ! 595: ! 596: int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) ! 597: { ! 598: int r; ! 599: ! 600: if (!sock) ! 601: return -1; ! 602: ! 603: if (sock->disconnected) ! 604: { ! 605: Con_Printf("NET_SendMessage: disconnected socket\n"); ! 606: return -1; ! 607: } ! 608: ! 609: SetNetTime(); ! 610: r = sfunc.SendMessage(sock, data); ! 611: if (r == 1 && sock->driver) ! 612: messagesSent++; ! 613: ! 614: if (recording) ! 615: { ! 616: vcrSendMessage.time = host_time; ! 617: vcrSendMessage.op = VCR_OP_SENDMESSAGE; ! 618: vcrSendMessage.session = (long)sock; ! 619: vcrSendMessage.r = r; ! 620: Sys_FileWrite (vcrFile, &vcrSendMessage, 20); ! 621: } ! 622: ! 623: return r; ! 624: } ! 625: ! 626: ! 627: int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) ! 628: { ! 629: int r; ! 630: ! 631: if (!sock) ! 632: return -1; ! 633: ! 634: if (sock->disconnected) ! 635: { ! 636: Con_Printf("NET_SendMessage: disconnected socket\n"); ! 637: return -1; ! 638: } ! 639: ! 640: SetNetTime(); ! 641: r = sfunc.SendUnreliableMessage(sock, data); ! 642: if (r == 1 && sock->driver) ! 643: unreliableMessagesSent++; ! 644: ! 645: if (recording) ! 646: { ! 647: vcrSendMessage.time = host_time; ! 648: vcrSendMessage.op = VCR_OP_SENDMESSAGE; ! 649: vcrSendMessage.session = (long)sock; ! 650: vcrSendMessage.r = r; ! 651: Sys_FileWrite (vcrFile, &vcrSendMessage, 20); ! 652: } ! 653: ! 654: return r; ! 655: } ! 656: ! 657: ! 658: /* ! 659: ================== ! 660: NET_CanSendMessage ! 661: ! 662: Returns true or false if the given qsocket can currently accept a ! 663: message to be transmitted. ! 664: ================== ! 665: */ ! 666: qboolean NET_CanSendMessage (qsocket_t *sock) ! 667: { ! 668: int r; ! 669: ! 670: if (!sock) ! 671: return false; ! 672: ! 673: if (sock->disconnected) ! 674: return false; ! 675: ! 676: SetNetTime(); ! 677: ! 678: r = sfunc.CanSendMessage(sock); ! 679: ! 680: if (recording) ! 681: { ! 682: vcrSendMessage.time = host_time; ! 683: vcrSendMessage.op = VCR_OP_CANSENDMESSAGE; ! 684: vcrSendMessage.session = (long)sock; ! 685: vcrSendMessage.r = r; ! 686: Sys_FileWrite (vcrFile, &vcrSendMessage, 20); ! 687: } ! 688: ! 689: return r; ! 690: } ! 691: ! 692: ! 693: int NET_SendToAll(sizebuf_t *data, int blocktime) ! 694: { ! 695: double start; ! 696: int i; ! 697: int count = 0; ! 698: qboolean state1 [MAX_SCOREBOARD]; ! 699: qboolean state2 [MAX_SCOREBOARD]; ! 700: ! 701: for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++) ! 702: { ! 703: if (!host_client->netconnection) ! 704: continue; ! 705: if (host_client->active) ! 706: { ! 707: if (host_client->netconnection->driver == 0) ! 708: { ! 709: NET_SendMessage(host_client->netconnection, data); ! 710: state1[i] = true; ! 711: state2[i] = true; ! 712: continue; ! 713: } ! 714: count++; ! 715: state1[i] = false; ! 716: state2[i] = false; ! 717: } ! 718: else ! 719: { ! 720: state1[i] = true; ! 721: state2[i] = true; ! 722: } ! 723: } ! 724: ! 725: start = Sys_FloatTime(); ! 726: while (count) ! 727: { ! 728: count = 0; ! 729: for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++) ! 730: { ! 731: if (! state1[i]) ! 732: { ! 733: if (NET_CanSendMessage (host_client->netconnection)) ! 734: { ! 735: state1[i] = true; ! 736: NET_SendMessage(host_client->netconnection, data); ! 737: } ! 738: else ! 739: { ! 740: NET_GetMessage (host_client->netconnection); ! 741: } ! 742: count++; ! 743: continue; ! 744: } ! 745: ! 746: if (! state2[i]) ! 747: { ! 748: if (NET_CanSendMessage (host_client->netconnection)) ! 749: { ! 750: state2[i] = true; ! 751: } ! 752: else ! 753: { ! 754: NET_GetMessage (host_client->netconnection); ! 755: } ! 756: count++; ! 757: continue; ! 758: } ! 759: } ! 760: if ((Sys_FloatTime() - start) > blocktime) ! 761: break; ! 762: } ! 763: return count; ! 764: } ! 765: ! 766: ! 767: //============================================================================= ! 768: ! 769: /* ! 770: ==================== ! 771: NET_Init ! 772: ==================== ! 773: */ ! 774: ! 775: void NET_Init (void) ! 776: { ! 777: int i; ! 778: int controlSocket; ! 779: qsocket_t *s; ! 780: ! 781: if (COM_CheckParm("-playback")) ! 782: { ! 783: net_numdrivers = 1; ! 784: net_drivers[0].Init = VCR_Init; ! 785: } ! 786: ! 787: if (COM_CheckParm("-record")) ! 788: recording = true; ! 789: ! 790: i = COM_CheckParm ("-port"); ! 791: if (!i) ! 792: i = COM_CheckParm ("-udpport"); ! 793: if (!i) ! 794: i = COM_CheckParm ("-ipxport"); ! 795: ! 796: if (i) ! 797: { ! 798: if (i < com_argc-1) ! 799: DEFAULTnet_hostport = Q_atoi (com_argv[i+1]); ! 800: else ! 801: Sys_Error ("NET_Init: you must specify a number after -port"); ! 802: } ! 803: net_hostport = DEFAULTnet_hostport; ! 804: ! 805: if (COM_CheckParm("-listen") || cls.state == ca_dedicated) ! 806: listening = true; ! 807: net_numsockets = svs.maxclientslimit; ! 808: if (cls.state != ca_dedicated) ! 809: net_numsockets++; ! 810: ! 811: SetNetTime(); ! 812: ! 813: for (i = 0; i < net_numsockets; i++) ! 814: { ! 815: s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket"); ! 816: s->next = net_freeSockets; ! 817: net_freeSockets = s; ! 818: s->disconnected = true; ! 819: } ! 820: ! 821: // allocate space for network message buffer ! 822: SZ_Alloc (&net_message, NET_MAXMESSAGE); ! 823: ! 824: Cvar_RegisterVariable (&net_messagetimeout); ! 825: Cvar_RegisterVariable (&hostname); ! 826: Cvar_RegisterVariable (&config_com_port); ! 827: Cvar_RegisterVariable (&config_com_irq); ! 828: Cvar_RegisterVariable (&config_com_baud); ! 829: Cvar_RegisterVariable (&config_com_modem); ! 830: Cvar_RegisterVariable (&config_modem_dialtype); ! 831: Cvar_RegisterVariable (&config_modem_clear); ! 832: Cvar_RegisterVariable (&config_modem_init); ! 833: Cvar_RegisterVariable (&config_modem_hangup); ! 834: #ifdef IDGODS ! 835: Cvar_RegisterVariable (&idgods); ! 836: #endif ! 837: ! 838: Cmd_AddCommand ("slist", NET_Slist_f); ! 839: Cmd_AddCommand ("listen", NET_Listen_f); ! 840: Cmd_AddCommand ("maxplayers", MaxPlayers_f); ! 841: Cmd_AddCommand ("port", NET_Port_f); ! 842: ! 843: // initialize all the drivers ! 844: for (net_driverlevel=0 ; net_driverlevel<net_numdrivers ; net_driverlevel++) ! 845: { ! 846: controlSocket = net_drivers[net_driverlevel].Init(); ! 847: if (controlSocket == -1) ! 848: continue; ! 849: net_drivers[net_driverlevel].initialized = true; ! 850: net_drivers[net_driverlevel].controlSock = controlSocket; ! 851: if (listening) ! 852: net_drivers[net_driverlevel].Listen (true); ! 853: } ! 854: ! 855: if (*my_ipx_address) ! 856: Con_DPrintf("IPX address %s\n", my_ipx_address); ! 857: if (*my_tcpip_address) ! 858: Con_DPrintf("TCP/IP address %s\n", my_tcpip_address); ! 859: } ! 860: ! 861: /* ! 862: ==================== ! 863: NET_Shutdown ! 864: ==================== ! 865: */ ! 866: ! 867: void NET_Shutdown (void) ! 868: { ! 869: qsocket_t *sock; ! 870: ! 871: SetNetTime(); ! 872: ! 873: for (sock = net_activeSockets; sock; sock = sock->next) ! 874: NET_Close(sock); ! 875: ! 876: // ! 877: // shutdown the drivers ! 878: // ! 879: for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) ! 880: { ! 881: if (net_drivers[net_driverlevel].initialized == true) ! 882: { ! 883: net_drivers[net_driverlevel].Shutdown (); ! 884: net_drivers[net_driverlevel].initialized = false; ! 885: } ! 886: } ! 887: ! 888: if (vcrFile != -1) ! 889: { ! 890: Con_Printf ("Closing vcrfile.\n"); ! 891: Sys_FileClose(vcrFile); ! 892: } ! 893: } ! 894: ! 895: ! 896: static PollProcedure *pollProcedureList = NULL; ! 897: ! 898: void NET_Poll(void) ! 899: { ! 900: PollProcedure *pp; ! 901: qboolean useModem; ! 902: ! 903: if (!configRestored) ! 904: { ! 905: if (serialAvailable) ! 906: { ! 907: if (config_com_modem.value == 1.0) ! 908: useModem = true; ! 909: else ! 910: useModem = false; ! 911: SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem); ! 912: SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string); ! 913: } ! 914: configRestored = true; ! 915: } ! 916: ! 917: SetNetTime(); ! 918: ! 919: for (pp = pollProcedureList; pp; pp = pp->next) ! 920: { ! 921: if (pp->nextTime > net_time) ! 922: break; ! 923: pollProcedureList = pp->next; ! 924: pp->procedure(pp->arg); ! 925: } ! 926: } ! 927: ! 928: ! 929: void SchedulePollProcedure(PollProcedure *proc, double timeOffset) ! 930: { ! 931: PollProcedure *pp, *prev; ! 932: ! 933: proc->nextTime = Sys_FloatTime() + timeOffset; ! 934: for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next) ! 935: { ! 936: if (pp->nextTime >= proc->nextTime) ! 937: break; ! 938: prev = pp; ! 939: } ! 940: ! 941: if (prev == NULL) ! 942: { ! 943: proc->next = pollProcedureList; ! 944: pollProcedureList = proc; ! 945: return; ! 946: } ! 947: ! 948: proc->next = pp; ! 949: prev->next = proc; ! 950: } ! 951: ! 952: ! 953: #ifdef IDGODS ! 954: #define IDNET 0xc0f62800 ! 955: ! 956: qboolean IsID(struct qsockaddr *addr) ! 957: { ! 958: if (idgods.value == 0.0) ! 959: return false; ! 960: ! 961: if (addr->sa_family != 2) ! 962: return false; ! 963: ! 964: if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET) ! 965: return true; ! 966: return false; ! 967: } ! 968: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.