git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / net_main.c
blob75c683cf3cb3a241001a73ff4e5e9f1eef0926ed
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // net_main.c
22 #include "quakedef.h"
23 #include "net_vcr.h"
25 qsocket_t *net_activeSockets = NULL;
26 qsocket_t *net_freeSockets = NULL;
27 int net_numsockets = 0;
29 qboolean serialAvailable = false;
30 qboolean ipxAvailable = false;
31 qboolean tcpipAvailable = false;
32 qboolean tcpipAdhoc = false;
34 int net_hostport;
35 int DEFAULTnet_hostport = 26000;
37 char my_ipx_address[NET_NAMELEN];
38 char my_tcpip_address[NET_NAMELEN];
40 void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem);
41 void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem);
42 void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
43 void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
45 static qboolean listening = false;
47 qboolean slistInProgress = false;
48 qboolean slistSilent = false;
49 qboolean slistLocal = true;
50 static double slistStartTime;
51 static int slistLastShown;
53 static void Slist_Send(void);
54 static void Slist_Poll(void);
55 PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send};
56 PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll};
59 sizebuf_t net_message;
60 int net_activeconnections = 0;
62 int messagesSent = 0;
63 int messagesReceived = 0;
64 int unreliableMessagesSent = 0;
65 int unreliableMessagesReceived = 0;
67 cvar_t net_messagetimeout = {"net_messagetimeout","300"};
68 cvar_t hostname = {"hostname", "Unnamed Server"};
70 qboolean configRestored = false;
71 cvar_t config_com_port = {"_config_com_port", "0x3f8", true};
72 cvar_t config_com_irq = {"_config_com_irq", "4", true};
73 cvar_t config_com_baud = {"_config_com_baud", "57600", true};
74 cvar_t config_com_modem = {"_config_com_modem", "1", true};
75 cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true};
76 cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true};
77 cvar_t config_modem_init = {"_config_modem_init", "", true};
78 cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true};
80 #ifdef IDGODS
81 cvar_t idgods = {"idgods", "0"};
82 #endif
84 int vcrFile = -1;
85 qboolean recording = false;
87 // these two macros are to make the code more readable
88 #define sfunc net_drivers[sock->driver]
89 #define dfunc net_drivers[net_driverlevel]
91 int net_driverlevel;
94 double net_time;
96 double SetNetTime(void)
98 net_time = Sys_FloatTime();
99 return net_time;
104 ===================
105 NET_NewQSocket
107 Called by drivers when a new communications endpoint is required
108 The sequence and buffer fields will be filled in properly
109 ===================
111 qsocket_t *NET_NewQSocket (void)
113 qsocket_t *sock;
115 if (net_freeSockets == NULL)
116 return NULL;
118 if (net_activeconnections >= svs.maxclients)
119 return NULL;
121 // get one from free list
122 sock = net_freeSockets;
123 net_freeSockets = sock->next;
125 // add it to active list
126 sock->next = net_activeSockets;
127 net_activeSockets = sock;
129 sock->disconnected = false;
130 sock->connecttime = net_time;
131 Q_strcpy (sock->address,"UNSET ADDRESS");
132 sock->driver = net_driverlevel;
133 sock->socket = 0;
134 sock->driverdata = NULL;
135 sock->canSend = true;
136 sock->sendNext = false;
137 sock->lastMessageTime = net_time;
138 sock->ackSequence = 0;
139 sock->sendSequence = 0;
140 sock->unreliableSendSequence = 0;
141 sock->sendMessageLength = 0;
142 sock->receiveSequence = 0;
143 sock->unreliableReceiveSequence = 0;
144 sock->receiveMessageLength = 0;
146 return sock;
150 void NET_FreeQSocket(qsocket_t *sock)
152 qsocket_t *s;
154 // remove it from active list
155 if (sock == net_activeSockets)
156 net_activeSockets = net_activeSockets->next;
157 else
159 for (s = net_activeSockets; s; s = s->next)
160 if (s->next == sock)
162 s->next = sock->next;
163 break;
165 if (!s)
166 Sys_Error ("NET_FreeQSocket: not active\n");
169 // add it to free list
170 sock->next = net_freeSockets;
171 net_freeSockets = sock;
172 sock->disconnected = true;
176 static void NET_Listen_f (void)
178 if (Cmd_Argc () != 2)
180 Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0);
181 return;
184 listening = Q_atoi(Cmd_Argv(1)) ? true : false;
186 for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
188 if (net_drivers[net_driverlevel].initialized == false)
189 continue;
190 dfunc.Listen (listening);
195 static void MaxPlayers_f (void)
197 int n;
199 if (Cmd_Argc () != 2)
201 Con_Printf ("\"maxplayers\" is \"%u\"\n", svs.maxclients);
202 return;
205 if (sv.active)
207 Con_Printf ("maxplayers can not be changed while a server is running.\n");
208 return;
211 n = Q_atoi(Cmd_Argv(1));
212 if (n < 1)
213 n = 1;
214 if (n > svs.maxclientslimit)
216 n = svs.maxclientslimit;
217 Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
220 if ((n == 1) && listening)
221 Cbuf_AddText ("listen 0\n");
223 if ((n > 1) && (!listening))
224 Cbuf_AddText ("listen 1\n");
226 svs.maxclients = n;
227 if (n == 1)
229 Cvar_Set ("deathmatch", "0");
230 Cvar_Set ("coop", "0");
232 else
234 if (coop.value)
235 Cvar_Set ("deathmatch", "0");
236 else
238 if (deathmatch.value > 1)
239 Cvar_SetValue ("deathmatch", deathmatch.value);
240 else
241 Cvar_Set ("deathmatch", "1");
247 static void NET_Port_f (void)
249 int n;
251 if (Cmd_Argc () != 2)
253 Con_Printf ("\"port\" is \"%u\"\n", net_hostport);
254 return;
257 n = Q_atoi(Cmd_Argv(1));
258 if (n < 1 || n > 65534)
260 Con_Printf ("Bad value, must be between 1 and 65534\n");
261 return;
264 DEFAULTnet_hostport = n;
265 net_hostport = n;
267 if (listening)
269 // force a change to the new port
270 Cbuf_AddText ("listen 0\n");
271 Cbuf_AddText ("listen 1\n");
276 static void PrintSlistHeader(void)
278 Con_Printf("Server Map Users\n");
279 Con_Printf("--------------- --------------- -----\n");
280 slistLastShown = 0;
284 static void PrintSlist(void)
286 int n;
288 for (n = slistLastShown; n < hostCacheCount; n++)
290 if (hostcache[n].maxusers)
291 Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
292 else
293 Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map);
295 slistLastShown = n;
299 static void PrintSlistTrailer(void)
301 if (hostCacheCount)
302 Con_Printf("== end list ==\n\n");
303 else
304 Con_Printf("No Quake servers found.\n\n");
308 void NET_Slist_f (void)
310 if (slistInProgress)
311 return;
313 if (! slistSilent)
315 if (kurok)
316 Con_Printf("Looking for Kurok servers...\n");
317 else
318 Con_Printf("Looking for Quake servers...\n");
319 PrintSlistHeader();
322 slistInProgress = true;
323 slistStartTime = Sys_FloatTime();
325 SchedulePollProcedure(&slistSendProcedure, 0.0);
326 SchedulePollProcedure(&slistPollProcedure, 0.1);
328 hostCacheCount = 0;
332 static void Slist_Send(void)
334 for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
336 if (!slistLocal && net_driverlevel == 0)
337 continue;
338 if (net_drivers[net_driverlevel].initialized == false)
339 continue;
340 dfunc.SearchForHosts (true);
343 if ((Sys_FloatTime() - slistStartTime) < 0.5)
344 SchedulePollProcedure(&slistSendProcedure, 0.75);
348 static void Slist_Poll(void)
350 for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
352 if (!slistLocal && net_driverlevel == 0)
353 continue;
354 if (net_drivers[net_driverlevel].initialized == false)
355 continue;
356 dfunc.SearchForHosts (false);
359 if (! slistSilent)
360 PrintSlist();
362 if ((Sys_FloatTime() - slistStartTime) < 1.5)
364 SchedulePollProcedure(&slistPollProcedure, 0.1);
365 return;
368 if (! slistSilent)
369 PrintSlistTrailer();
370 slistInProgress = false;
371 slistSilent = false;
372 slistLocal = true;
377 ===================
378 NET_Connect
379 ===================
382 int hostCacheCount = 0;
383 hostcache_t hostcache[HOSTCACHESIZE];
385 qsocket_t *NET_Connect (char *host)
387 qsocket_t *ret;
388 int n;
389 int numdrivers = net_numdrivers;
391 SetNetTime();
393 if (host && *host == 0)
394 host = NULL;
396 if (host)
398 if (Q_strcasecmp (host, "local") == 0)
400 numdrivers = 1;
401 goto JustDoIt;
404 if (hostCacheCount)
406 for (n = 0; n < hostCacheCount; n++)
407 if (Q_strcasecmp (host, hostcache[n].name) == 0)
409 host = hostcache[n].cname;
410 break;
412 if (n < hostCacheCount)
413 goto JustDoIt;
417 slistSilent = host ? true : false;
418 NET_Slist_f ();
420 while(slistInProgress)
421 NET_Poll();
423 if (host == NULL)
425 if (hostCacheCount != 1)
426 return NULL;
427 host = hostcache[0].cname;
428 Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host);
431 if (hostCacheCount)
432 for (n = 0; n < hostCacheCount; n++)
433 if (Q_strcasecmp (host, hostcache[n].name) == 0)
435 host = hostcache[n].cname;
436 break;
439 JustDoIt:
440 for (net_driverlevel=0 ; net_driverlevel<numdrivers; net_driverlevel++)
442 if (net_drivers[net_driverlevel].initialized == false)
443 continue;
444 ret = dfunc.Connect (host);
445 if (ret)
446 return ret;
449 if (host)
451 Con_Printf("\n");
452 PrintSlistHeader();
453 PrintSlist();
454 PrintSlistTrailer();
457 return NULL;
462 ===================
463 NET_CheckNewConnections
464 ===================
467 struct
469 double time;
470 int op;
471 long session;
472 } vcrConnect;
474 qsocket_t *NET_CheckNewConnections (void)
476 qsocket_t *ret;
478 SetNetTime();
480 for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
482 if (net_drivers[net_driverlevel].initialized == false)
483 continue;
484 if (net_driverlevel && listening == false)
485 continue;
486 ret = dfunc.CheckNewConnections ();
487 if (ret)
489 if (recording)
491 vcrConnect.time = host_time;
492 vcrConnect.op = VCR_OP_CONNECT;
493 vcrConnect.session = (long)ret;
494 Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
495 Sys_FileWrite (vcrFile, ret->address, NET_NAMELEN);
497 return ret;
501 if (recording)
503 vcrConnect.time = host_time;
504 vcrConnect.op = VCR_OP_CONNECT;
505 vcrConnect.session = 0;
506 Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
509 return NULL;
513 ===================
514 NET_Close
515 ===================
517 void NET_Close (qsocket_t *sock)
519 if (!sock)
520 return;
522 if (sock->disconnected)
523 return;
525 SetNetTime();
527 // call the driver_Close function
528 sfunc.Close (sock);
530 NET_FreeQSocket(sock);
535 =================
536 NET_GetMessage
538 If there is a complete message, return it in net_message
540 returns 0 if no data is waiting
541 returns 1 if a message was received
542 returns -1 if connection is invalid
543 =================
546 struct
548 double time;
549 int op;
550 long session;
551 int ret;
552 int len;
553 } vcrGetMessage;
555 extern void PrintStats(qsocket_t *s);
557 int NET_GetMessage (qsocket_t *sock)
559 int ret;
561 if (!sock)
562 return -1;
564 if (sock->disconnected)
566 Con_Printf("NET_GetMessage: disconnected socket\n");
567 return -1;
570 SetNetTime();
572 ret = sfunc.QGetMessage(sock);
574 // see if this connection has timed out
575 if (ret == 0 && sock->driver)
577 if (net_time - sock->lastMessageTime > net_messagetimeout.value)
579 NET_Close(sock);
580 return -1;
585 if (ret > 0)
587 if (sock->driver)
589 sock->lastMessageTime = net_time;
590 if (ret == 1)
591 messagesReceived++;
592 else if (ret == 2)
593 unreliableMessagesReceived++;
596 if (recording)
598 vcrGetMessage.time = host_time;
599 vcrGetMessage.op = VCR_OP_GETMESSAGE;
600 vcrGetMessage.session = (long)sock;
601 vcrGetMessage.ret = ret;
602 vcrGetMessage.len = net_message.cursize;
603 Sys_FileWrite (vcrFile, &vcrGetMessage, 24);
604 Sys_FileWrite (vcrFile, net_message.data, net_message.cursize);
607 else
609 if (recording)
611 vcrGetMessage.time = host_time;
612 vcrGetMessage.op = VCR_OP_GETMESSAGE;
613 vcrGetMessage.session = (long)sock;
614 vcrGetMessage.ret = ret;
615 Sys_FileWrite (vcrFile, &vcrGetMessage, 20);
619 return ret;
624 ==================
625 NET_SendMessage
627 Try to send a complete length+message unit over the reliable stream.
628 returns 0 if the message cannot be delivered reliably, but the connection
629 is still considered valid
630 returns 1 if the message was sent properly
631 returns -1 if the connection died
632 ==================
634 struct
636 double time;
637 int op;
638 long session;
639 int r;
640 } vcrSendMessage;
642 int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
644 int r;
646 if (!sock)
647 return -1;
649 if (sock->disconnected)
651 Con_Printf("NET_SendMessage: disconnected socket\n");
652 return -1;
655 SetNetTime();
656 r = sfunc.QSendMessage(sock, data);
657 if (r == 1 && sock->driver)
658 messagesSent++;
660 if (recording)
662 vcrSendMessage.time = host_time;
663 vcrSendMessage.op = VCR_OP_SENDMESSAGE;
664 vcrSendMessage.session = (long)sock;
665 vcrSendMessage.r = r;
666 Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
669 return r;
673 int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
675 int r;
677 if (!sock)
678 return -1;
680 if (sock->disconnected)
682 Con_Printf("NET_SendMessage: disconnected socket\n");
683 return -1;
686 SetNetTime();
687 r = sfunc.SendUnreliableMessage(sock, data);
688 if (r == 1 && sock->driver)
689 unreliableMessagesSent++;
691 if (recording)
693 vcrSendMessage.time = host_time;
694 vcrSendMessage.op = VCR_OP_SENDMESSAGE;
695 vcrSendMessage.session = (long)sock;
696 vcrSendMessage.r = r;
697 Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
700 return r;
705 ==================
706 NET_CanSendMessage
708 Returns true or false if the given qsocket can currently accept a
709 message to be transmitted.
710 ==================
712 qboolean NET_CanSendMessage (qsocket_t *sock)
714 int r;
716 if (!sock)
717 return false;
719 if (sock->disconnected)
720 return false;
722 SetNetTime();
724 r = sfunc.CanSendMessage(sock);
726 if (recording)
728 vcrSendMessage.time = host_time;
729 vcrSendMessage.op = VCR_OP_CANSENDMESSAGE;
730 vcrSendMessage.session = (long)sock;
731 vcrSendMessage.r = r;
732 Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
735 return r;
739 int NET_SendToAll(sizebuf_t *data, int blocktime)
741 double start;
742 int i;
743 int count = 0;
744 qboolean state1 [MAX_SCOREBOARD];
745 qboolean state2 [MAX_SCOREBOARD];
747 for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
749 if (!host_client->netconnection)
750 continue;
751 if (host_client->active)
753 if (host_client->netconnection->driver == 0)
755 NET_SendMessage(host_client->netconnection, data);
756 state1[i] = true;
757 state2[i] = true;
758 continue;
760 count++;
761 state1[i] = false;
762 state2[i] = false;
764 else
766 state1[i] = true;
767 state2[i] = true;
771 start = Sys_FloatTime();
772 while (count)
774 count = 0;
775 for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
777 if (! state1[i])
779 if (NET_CanSendMessage (host_client->netconnection))
781 state1[i] = true;
782 NET_SendMessage(host_client->netconnection, data);
784 else
786 NET_GetMessage (host_client->netconnection);
788 count++;
789 continue;
792 if (! state2[i])
794 if (NET_CanSendMessage (host_client->netconnection))
796 state2[i] = true;
798 else
800 NET_GetMessage (host_client->netconnection);
802 count++;
803 continue;
806 if ((Sys_FloatTime() - start) > blocktime)
807 break;
809 return count;
813 //=============================================================================
816 ====================
817 NET_Init
818 ====================
821 void NET_Init (void)
823 int i;
824 int controlSocket;
825 qsocket_t *s;
827 if (COM_CheckParm("-playback"))
829 net_numdrivers = 1;
830 net_drivers[0].Init = VCR_Init;
833 if (COM_CheckParm("-record"))
834 recording = true;
836 i = COM_CheckParm ("-port");
837 if (!i)
838 i = COM_CheckParm ("-udpport");
839 if (!i)
840 i = COM_CheckParm ("-ipxport");
842 if (i)
844 if (i < com_argc-1)
845 DEFAULTnet_hostport = Q_atoi (com_argv[i+1]);
846 else
847 Sys_Error ("NET_Init: you must specify a number after -port");
849 net_hostport = DEFAULTnet_hostport;
851 if (COM_CheckParm("-listen") || cls.state == ca_dedicated)
852 listening = true;
853 net_numsockets = svs.maxclientslimit;
854 if (cls.state != ca_dedicated)
855 net_numsockets++;
857 SetNetTime();
859 for (i = 0; i < net_numsockets; i++)
861 s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket");
862 s->next = net_freeSockets;
863 net_freeSockets = s;
864 s->disconnected = true;
867 // allocate space for network message buffer
868 SZ_Alloc (&net_message, NET_MAXMESSAGE);
870 Cvar_RegisterVariable (&net_messagetimeout);
871 Cvar_RegisterVariable (&hostname);
872 Cvar_RegisterVariable (&config_com_port);
873 Cvar_RegisterVariable (&config_com_irq);
874 Cvar_RegisterVariable (&config_com_baud);
875 Cvar_RegisterVariable (&config_com_modem);
876 Cvar_RegisterVariable (&config_modem_dialtype);
877 Cvar_RegisterVariable (&config_modem_clear);
878 Cvar_RegisterVariable (&config_modem_init);
879 Cvar_RegisterVariable (&config_modem_hangup);
880 #ifdef IDGODS
881 Cvar_RegisterVariable (&idgods);
882 #endif
884 if(!host_initialized)
886 Cmd_AddCommand ("slist", NET_Slist_f);
887 Cmd_AddCommand ("listen", NET_Listen_f);
888 Cmd_AddCommand ("maxplayers", MaxPlayers_f);
889 Cmd_AddCommand ("port", NET_Port_f);
892 // initialize all the drivers
893 for (net_driverlevel=0 ; net_driverlevel<net_numdrivers ; net_driverlevel++)
895 controlSocket = net_drivers[net_driverlevel].Init();
896 if (controlSocket == -1)
897 continue;
898 net_drivers[net_driverlevel].initialized = true;
899 net_drivers[net_driverlevel].controlSock = controlSocket;
900 if (listening)
901 net_drivers[net_driverlevel].Listen (true);
904 if (*my_ipx_address)
905 Con_DPrintf("IPX address %s\n", my_ipx_address);
906 if (*my_tcpip_address)
907 Con_DPrintf("TCP/IP address %s\n", my_tcpip_address);
911 ====================
912 NET_Shutdown
913 ====================
916 void NET_Shutdown (void)
918 qsocket_t *sock;
920 SetNetTime();
922 for (sock = net_activeSockets; sock; sock = sock->next)
923 NET_Close(sock);
926 // shutdown the drivers
928 for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++)
930 if (net_drivers[net_driverlevel].initialized == true)
932 net_drivers[net_driverlevel].Shutdown ();
933 net_drivers[net_driverlevel].initialized = false;
937 if (vcrFile != -1)
939 Con_Printf ("Closing vcrfile.\n");
940 Sys_FileClose(vcrFile);
945 static PollProcedure *pollProcedureList = NULL;
947 void NET_Poll(void)
949 PollProcedure *pp;
950 qboolean useModem;
952 if (!configRestored)
954 if (serialAvailable)
956 if (config_com_modem.value == 1.0)
957 useModem = true;
958 else
959 useModem = false;
960 SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem);
961 SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string);
963 configRestored = true;
966 SetNetTime();
968 for (pp = pollProcedureList; pp; pp = pp->next)
970 if (pp->nextTime > net_time)
971 break;
972 pollProcedureList = pp->next;
973 pp->procedure(pp->arg);
978 void SchedulePollProcedure(PollProcedure *proc, double timeOffset)
980 PollProcedure *pp, *prev;
982 proc->nextTime = Sys_FloatTime() + timeOffset;
983 for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next)
985 if (pp->nextTime >= proc->nextTime)
986 break;
987 prev = pp;
990 if (prev == NULL)
992 proc->next = pollProcedureList;
993 pollProcedureList = proc;
994 return;
997 proc->next = pp;
998 prev->next = proc;
1002 #ifdef IDGODS
1003 #define IDNET 0xc0f62800
1005 qboolean IsID(struct qsockaddr *addr)
1007 if (idgods.value == 0.0)
1008 return false;
1010 if (addr->sa_family != 2)
1011 return false;
1013 if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET)
1014 return true;
1015 return false;
1017 #endif