Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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