123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- /*
- Copyright (C) 1996-1997 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- // net_main.c
- #include "quakedef.h"
- #include "net_vcr.h"
- qsocket_t *net_activeSockets = NULL;
- qsocket_t *net_freeSockets = NULL;
- int net_numsockets = 0;
- qboolean serialAvailable = false;
- qboolean ipxAvailable = false;
- qboolean tcpipAvailable = false;
- int net_hostport;
- int DEFAULTnet_hostport = 26000;
- char my_ipx_address[NET_NAMELEN];
- char my_tcpip_address[NET_NAMELEN];
- void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem);
- void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem);
- void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
- void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
- static qboolean listening = false;
- qboolean slistInProgress = false;
- qboolean slistSilent = false;
- qboolean slistLocal = true;
- static double slistStartTime;
- static int slistLastShown;
- static void Slist_Send(void);
- static void Slist_Poll(void);
- PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send};
- PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll};
- sizebuf_t net_message;
- int net_activeconnections = 0;
- int messagesSent = 0;
- int messagesReceived = 0;
- int unreliableMessagesSent = 0;
- int unreliableMessagesReceived = 0;
- cvar_t net_messagetimeout = {"net_messagetimeout","300"};
- cvar_t hostname = {"hostname", "UNNAMED"};
- qboolean configRestored = false;
- cvar_t config_com_port = {"_config_com_port", "0x3f8", true};
- cvar_t config_com_irq = {"_config_com_irq", "4", true};
- cvar_t config_com_baud = {"_config_com_baud", "57600", true};
- cvar_t config_com_modem = {"_config_com_modem", "1", true};
- cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true};
- cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true};
- cvar_t config_modem_init = {"_config_modem_init", "", true};
- cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true};
- #ifdef IDGODS
- cvar_t idgods = {"idgods", "0"};
- #endif
- int vcrFile = -1;
- qboolean recording = false;
- // these two macros are to make the code more readable
- #define sfunc net_drivers[sock->driver]
- #define dfunc net_drivers[net_driverlevel]
- int net_driverlevel;
- double net_time;
- double SetNetTime(void)
- {
- net_time = Sys_FloatTime();
- return net_time;
- }
- /*
- ===================
- NET_NewQSocket
- Called by drivers when a new communications endpoint is required
- The sequence and buffer fields will be filled in properly
- ===================
- */
- qsocket_t *NET_NewQSocket (void)
- {
- qsocket_t *sock;
- if (net_freeSockets == NULL)
- return NULL;
- if (net_activeconnections >= svs.maxclients)
- return NULL;
- // get one from free list
- sock = net_freeSockets;
- net_freeSockets = sock->next;
- // add it to active list
- sock->next = net_activeSockets;
- net_activeSockets = sock;
- sock->disconnected = false;
- sock->connecttime = net_time;
- Q_strcpy (sock->address,"UNSET ADDRESS");
- sock->driver = net_driverlevel;
- sock->socket = 0;
- sock->driverdata = NULL;
- sock->canSend = true;
- sock->sendNext = false;
- sock->lastMessageTime = net_time;
- sock->ackSequence = 0;
- sock->sendSequence = 0;
- sock->unreliableSendSequence = 0;
- sock->sendMessageLength = 0;
- sock->receiveSequence = 0;
- sock->unreliableReceiveSequence = 0;
- sock->receiveMessageLength = 0;
- return sock;
- }
- void NET_FreeQSocket(qsocket_t *sock)
- {
- qsocket_t *s;
- // remove it from active list
- if (sock == net_activeSockets)
- net_activeSockets = net_activeSockets->next;
- else
- {
- for (s = net_activeSockets; s; s = s->next)
- if (s->next == sock)
- {
- s->next = sock->next;
- break;
- }
- if (!s)
- Sys_Error ("NET_FreeQSocket: not active\n");
- }
- // add it to free list
- sock->next = net_freeSockets;
- net_freeSockets = sock;
- sock->disconnected = true;
- }
- static void NET_Listen_f (void)
- {
- if (Cmd_Argc () != 2)
- {
- Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0);
- return;
- }
- listening = Q_atoi(Cmd_Argv(1)) ? true : false;
- for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
- {
- if (net_drivers[net_driverlevel].initialized == false)
- continue;
- dfunc.Listen (listening);
- }
- }
- static void MaxPlayers_f (void)
- {
- int n;
- if (Cmd_Argc () != 2)
- {
- Con_Printf ("\"maxplayers\" is \"%u\"\n", svs.maxclients);
- return;
- }
- if (sv.active)
- {
- Con_Printf ("maxplayers can not be changed while a server is running.\n");
- return;
- }
- n = Q_atoi(Cmd_Argv(1));
- if (n < 1)
- n = 1;
- if (n > svs.maxclientslimit)
- {
- n = svs.maxclientslimit;
- Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
- }
- if ((n == 1) && listening)
- Cbuf_AddText ("listen 0\n");
- if ((n > 1) && (!listening))
- Cbuf_AddText ("listen 1\n");
- svs.maxclients = n;
- if (n == 1)
- Cvar_Set ("deathmatch", "0");
- else
- Cvar_Set ("deathmatch", "1");
- }
- static void NET_Port_f (void)
- {
- int n;
- if (Cmd_Argc () != 2)
- {
- Con_Printf ("\"port\" is \"%u\"\n", net_hostport);
- return;
- }
- n = Q_atoi(Cmd_Argv(1));
- if (n < 1 || n > 65534)
- {
- Con_Printf ("Bad value, must be between 1 and 65534\n");
- return;
- }
- DEFAULTnet_hostport = n;
- net_hostport = n;
- if (listening)
- {
- // force a change to the new port
- Cbuf_AddText ("listen 0\n");
- Cbuf_AddText ("listen 1\n");
- }
- }
- static void PrintSlistHeader(void)
- {
- Con_Printf("Server Map Users\n");
- Con_Printf("--------------- --------------- -----\n");
- slistLastShown = 0;
- }
- static void PrintSlist(void)
- {
- int n;
- for (n = slistLastShown; n < hostCacheCount; n++)
- {
- if (hostcache[n].maxusers)
- Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
- else
- Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map);
- }
- slistLastShown = n;
- }
- static void PrintSlistTrailer(void)
- {
- if (hostCacheCount)
- Con_Printf("== end list ==\n\n");
- else
- Con_Printf("No Quake servers found.\n\n");
- }
- void NET_Slist_f (void)
- {
- if (slistInProgress)
- return;
- if (! slistSilent)
- {
- Con_Printf("Looking for Quake servers...\n");
- PrintSlistHeader();
- }
- slistInProgress = true;
- slistStartTime = Sys_FloatTime();
- SchedulePollProcedure(&slistSendProcedure, 0.0);
- SchedulePollProcedure(&slistPollProcedure, 0.1);
- hostCacheCount = 0;
- }
- static void Slist_Send(void)
- {
- for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
- {
- if (!slistLocal && net_driverlevel == 0)
- continue;
- if (net_drivers[net_driverlevel].initialized == false)
- continue;
- dfunc.SearchForHosts (true);
- }
- if ((Sys_FloatTime() - slistStartTime) < 0.5)
- SchedulePollProcedure(&slistSendProcedure, 0.75);
- }
- static void Slist_Poll(void)
- {
- for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
- {
- if (!slistLocal && net_driverlevel == 0)
- continue;
- if (net_drivers[net_driverlevel].initialized == false)
- continue;
- dfunc.SearchForHosts (false);
- }
- if (! slistSilent)
- PrintSlist();
- if ((Sys_FloatTime() - slistStartTime) < 1.5)
- {
- SchedulePollProcedure(&slistPollProcedure, 0.1);
- return;
- }
- if (! slistSilent)
- PrintSlistTrailer();
- slistInProgress = false;
- slistSilent = false;
- slistLocal = true;
- }
- /*
- ===================
- NET_Connect
- ===================
- */
- int hostCacheCount = 0;
- hostcache_t hostcache[HOSTCACHESIZE];
- qsocket_t *NET_Connect (char *host)
- {
- qsocket_t *ret;
- int n;
- int numdrivers = net_numdrivers;
- SetNetTime();
- if (host && *host == 0)
- host = NULL;
- if (host)
- {
- if (Q_strcasecmp (host, "local") == 0)
- {
- numdrivers = 1;
- goto JustDoIt;
- }
- if (hostCacheCount)
- {
- for (n = 0; n < hostCacheCount; n++)
- if (Q_strcasecmp (host, hostcache[n].name) == 0)
- {
- host = hostcache[n].cname;
- break;
- }
- if (n < hostCacheCount)
- goto JustDoIt;
- }
- }
- slistSilent = host ? true : false;
- NET_Slist_f ();
- while(slistInProgress)
- NET_Poll();
- if (host == NULL)
- {
- if (hostCacheCount != 1)
- return NULL;
- host = hostcache[0].cname;
- Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host);
- }
- if (hostCacheCount)
- for (n = 0; n < hostCacheCount; n++)
- if (Q_strcasecmp (host, hostcache[n].name) == 0)
- {
- host = hostcache[n].cname;
- break;
- }
- JustDoIt:
- for (net_driverlevel=0 ; net_driverlevel<numdrivers; net_driverlevel++)
- {
- if (net_drivers[net_driverlevel].initialized == false)
- continue;
- ret = dfunc.Connect (host);
- if (ret)
- return ret;
- }
- if (host)
- {
- Con_Printf("\n");
- PrintSlistHeader();
- PrintSlist();
- PrintSlistTrailer();
- }
-
- return NULL;
- }
- /*
- ===================
- NET_CheckNewConnections
- ===================
- */
- struct
- {
- double time;
- int op;
- long session;
- } vcrConnect;
- qsocket_t *NET_CheckNewConnections (void)
- {
- qsocket_t *ret;
- SetNetTime();
- for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
- {
- if (net_drivers[net_driverlevel].initialized == false)
- continue;
- if (net_driverlevel && listening == false)
- continue;
- ret = dfunc.CheckNewConnections ();
- if (ret)
- {
- if (recording)
- {
- vcrConnect.time = host_time;
- vcrConnect.op = VCR_OP_CONNECT;
- vcrConnect.session = (long)ret;
- Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
- Sys_FileWrite (vcrFile, ret->address, NET_NAMELEN);
- }
- return ret;
- }
- }
-
- if (recording)
- {
- vcrConnect.time = host_time;
- vcrConnect.op = VCR_OP_CONNECT;
- vcrConnect.session = 0;
- Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
- }
- return NULL;
- }
- /*
- ===================
- NET_Close
- ===================
- */
- void NET_Close (qsocket_t *sock)
- {
- if (!sock)
- return;
- if (sock->disconnected)
- return;
- SetNetTime();
- // call the driver_Close function
- sfunc.Close (sock);
- NET_FreeQSocket(sock);
- }
- /*
- =================
- NET_GetMessage
- If there is a complete message, return it in net_message
- returns 0 if no data is waiting
- returns 1 if a message was received
- returns -1 if connection is invalid
- =================
- */
- struct
- {
- double time;
- int op;
- long session;
- int ret;
- int len;
- } vcrGetMessage;
- extern void PrintStats(qsocket_t *s);
- int NET_GetMessage (qsocket_t *sock)
- {
- int ret;
- if (!sock)
- return -1;
- if (sock->disconnected)
- {
- Con_Printf("NET_GetMessage: disconnected socket\n");
- return -1;
- }
- SetNetTime();
- ret = sfunc.QGetMessage(sock);
- // see if this connection has timed out
- if (ret == 0 && sock->driver)
- {
- if (net_time - sock->lastMessageTime > net_messagetimeout.value)
- {
- NET_Close(sock);
- return -1;
- }
- }
- if (ret > 0)
- {
- if (sock->driver)
- {
- sock->lastMessageTime = net_time;
- if (ret == 1)
- messagesReceived++;
- else if (ret == 2)
- unreliableMessagesReceived++;
- }
- if (recording)
- {
- vcrGetMessage.time = host_time;
- vcrGetMessage.op = VCR_OP_GETMESSAGE;
- vcrGetMessage.session = (long)sock;
- vcrGetMessage.ret = ret;
- vcrGetMessage.len = net_message.cursize;
- Sys_FileWrite (vcrFile, &vcrGetMessage, 24);
- Sys_FileWrite (vcrFile, net_message.data, net_message.cursize);
- }
- }
- else
- {
- if (recording)
- {
- vcrGetMessage.time = host_time;
- vcrGetMessage.op = VCR_OP_GETMESSAGE;
- vcrGetMessage.session = (long)sock;
- vcrGetMessage.ret = ret;
- Sys_FileWrite (vcrFile, &vcrGetMessage, 20);
- }
- }
- return ret;
- }
- /*
- ==================
- NET_SendMessage
- Try to send a complete length+message unit over the reliable stream.
- returns 0 if the message cannot be delivered reliably, but the connection
- is still considered valid
- returns 1 if the message was sent properly
- returns -1 if the connection died
- ==================
- */
- struct
- {
- double time;
- int op;
- long session;
- int r;
- } vcrSendMessage;
- int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
- {
- int r;
-
- if (!sock)
- return -1;
- if (sock->disconnected)
- {
- Con_Printf("NET_SendMessage: disconnected socket\n");
- return -1;
- }
- SetNetTime();
- r = sfunc.QSendMessage(sock, data);
- if (r == 1 && sock->driver)
- messagesSent++;
- if (recording)
- {
- vcrSendMessage.time = host_time;
- vcrSendMessage.op = VCR_OP_SENDMESSAGE;
- vcrSendMessage.session = (long)sock;
- vcrSendMessage.r = r;
- Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
- }
-
- return r;
- }
- int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
- {
- int r;
-
- if (!sock)
- return -1;
- if (sock->disconnected)
- {
- Con_Printf("NET_SendMessage: disconnected socket\n");
- return -1;
- }
- SetNetTime();
- r = sfunc.SendUnreliableMessage(sock, data);
- if (r == 1 && sock->driver)
- unreliableMessagesSent++;
- if (recording)
- {
- vcrSendMessage.time = host_time;
- vcrSendMessage.op = VCR_OP_SENDMESSAGE;
- vcrSendMessage.session = (long)sock;
- vcrSendMessage.r = r;
- Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
- }
-
- return r;
- }
- /*
- ==================
- NET_CanSendMessage
- Returns true or false if the given qsocket can currently accept a
- message to be transmitted.
- ==================
- */
- qboolean NET_CanSendMessage (qsocket_t *sock)
- {
- int r;
-
- if (!sock)
- return false;
- if (sock->disconnected)
- return false;
- SetNetTime();
- r = sfunc.CanSendMessage(sock);
-
- if (recording)
- {
- vcrSendMessage.time = host_time;
- vcrSendMessage.op = VCR_OP_CANSENDMESSAGE;
- vcrSendMessage.session = (long)sock;
- vcrSendMessage.r = r;
- Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
- }
-
- return r;
- }
- int NET_SendToAll(sizebuf_t *data, int blocktime)
- {
- double start;
- int i;
- int count = 0;
- qboolean state1 [MAX_SCOREBOARD];
- qboolean state2 [MAX_SCOREBOARD];
- for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
- {
- if (!host_client->netconnection)
- continue;
- if (host_client->active)
- {
- if (host_client->netconnection->driver == 0)
- {
- NET_SendMessage(host_client->netconnection, data);
- state1[i] = true;
- state2[i] = true;
- continue;
- }
- count++;
- state1[i] = false;
- state2[i] = false;
- }
- else
- {
- state1[i] = true;
- state2[i] = true;
- }
- }
- start = Sys_FloatTime();
- while (count)
- {
- count = 0;
- for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
- {
- if (! state1[i])
- {
- if (NET_CanSendMessage (host_client->netconnection))
- {
- state1[i] = true;
- NET_SendMessage(host_client->netconnection, data);
- }
- else
- {
- NET_GetMessage (host_client->netconnection);
- }
- count++;
- continue;
- }
- if (! state2[i])
- {
- if (NET_CanSendMessage (host_client->netconnection))
- {
- state2[i] = true;
- }
- else
- {
- NET_GetMessage (host_client->netconnection);
- }
- count++;
- continue;
- }
- }
- if ((Sys_FloatTime() - start) > blocktime)
- break;
- }
- return count;
- }
- //=============================================================================
- /*
- ====================
- NET_Init
- ====================
- */
- void NET_Init (void)
- {
- int i;
- int controlSocket;
- qsocket_t *s;
- if (COM_CheckParm("-playback"))
- {
- net_numdrivers = 1;
- net_drivers[0].Init = VCR_Init;
- }
- if (COM_CheckParm("-record"))
- recording = true;
- i = COM_CheckParm ("-port");
- if (!i)
- i = COM_CheckParm ("-udpport");
- if (!i)
- i = COM_CheckParm ("-ipxport");
- if (i)
- {
- if (i < com_argc-1)
- DEFAULTnet_hostport = Q_atoi (com_argv[i+1]);
- else
- Sys_Error ("NET_Init: you must specify a number after -port");
- }
- net_hostport = DEFAULTnet_hostport;
- if (COM_CheckParm("-listen") || cls.state == ca_dedicated)
- listening = true;
- net_numsockets = svs.maxclientslimit;
- if (cls.state != ca_dedicated)
- net_numsockets++;
- SetNetTime();
- for (i = 0; i < net_numsockets; i++)
- {
- s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket");
- s->next = net_freeSockets;
- net_freeSockets = s;
- s->disconnected = true;
- }
- // allocate space for network message buffer
- SZ_Alloc (&net_message, NET_MAXMESSAGE);
- Cvar_RegisterVariable (&net_messagetimeout);
- Cvar_RegisterVariable (&hostname);
- Cvar_RegisterVariable (&config_com_port);
- Cvar_RegisterVariable (&config_com_irq);
- Cvar_RegisterVariable (&config_com_baud);
- Cvar_RegisterVariable (&config_com_modem);
- Cvar_RegisterVariable (&config_modem_dialtype);
- Cvar_RegisterVariable (&config_modem_clear);
- Cvar_RegisterVariable (&config_modem_init);
- Cvar_RegisterVariable (&config_modem_hangup);
- #ifdef IDGODS
- Cvar_RegisterVariable (&idgods);
- #endif
- Cmd_AddCommand ("slist", NET_Slist_f);
- Cmd_AddCommand ("listen", NET_Listen_f);
- Cmd_AddCommand ("maxplayers", MaxPlayers_f);
- Cmd_AddCommand ("port", NET_Port_f);
- // initialize all the drivers
- for (net_driverlevel=0 ; net_driverlevel<net_numdrivers ; net_driverlevel++)
- {
- controlSocket = net_drivers[net_driverlevel].Init();
- if (controlSocket == -1)
- continue;
- net_drivers[net_driverlevel].initialized = true;
- net_drivers[net_driverlevel].controlSock = controlSocket;
- if (listening)
- net_drivers[net_driverlevel].Listen (true);
- }
- if (*my_ipx_address)
- Con_DPrintf("IPX address %s\n", my_ipx_address);
- if (*my_tcpip_address)
- Con_DPrintf("TCP/IP address %s\n", my_tcpip_address);
- }
- /*
- ====================
- NET_Shutdown
- ====================
- */
- void NET_Shutdown (void)
- {
- qsocket_t *sock;
- SetNetTime();
- for (sock = net_activeSockets; sock; sock = sock->next)
- NET_Close(sock);
- //
- // shutdown the drivers
- //
- for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++)
- {
- if (net_drivers[net_driverlevel].initialized == true)
- {
- net_drivers[net_driverlevel].Shutdown ();
- net_drivers[net_driverlevel].initialized = false;
- }
- }
- if (vcrFile != -1)
- {
- Con_Printf ("Closing vcrfile.\n");
- Sys_FileClose(vcrFile);
- }
- }
- static PollProcedure *pollProcedureList = NULL;
- void NET_Poll(void)
- {
- PollProcedure *pp;
- qboolean useModem;
- if (!configRestored)
- {
- if (serialAvailable)
- {
- if (config_com_modem.value == 1.0)
- useModem = true;
- else
- useModem = false;
- SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem);
- SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string);
- }
- configRestored = true;
- }
- SetNetTime();
- for (pp = pollProcedureList; pp; pp = pp->next)
- {
- if (pp->nextTime > net_time)
- break;
- pollProcedureList = pp->next;
- pp->procedure(pp->arg);
- }
- }
- void SchedulePollProcedure(PollProcedure *proc, double timeOffset)
- {
- PollProcedure *pp, *prev;
- proc->nextTime = Sys_FloatTime() + timeOffset;
- for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next)
- {
- if (pp->nextTime >= proc->nextTime)
- break;
- prev = pp;
- }
- if (prev == NULL)
- {
- proc->next = pollProcedureList;
- pollProcedureList = proc;
- return;
- }
- proc->next = pp;
- prev->next = proc;
- }
- #ifdef IDGODS
- #define IDNET 0xc0f62800
- qboolean IsID(struct qsockaddr *addr)
- {
- if (idgods.value == 0.0)
- return false;
- if (addr->sa_family != 2)
- return false;
- if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET)
- return true;
- return false;
- }
- #endif
|