network.c
changeset 193 0a7025304867
parent 188 30f27b5c1ee5
child 206 7f8c26d8526b
equal deleted inserted replaced
192:614bba52258d 193:0a7025304867
   230 static byte *_transmit_file;
   230 static byte *_transmit_file;
   231 static size_t _transmit_file_size;
   231 static size_t _transmit_file_size;
   232 
   232 
   233 static FILE *_recv_file;
   233 static FILE *_recv_file;
   234 
   234 
   235 typedef struct NetworkGameInfo {	
   235 typedef struct NetworkGameInfo {
   236 	char server_name[40];			// name of the game
   236 	char server_name[40];			// name of the game
   237 	char server_revision[8];	// server game version
   237 	char server_revision[8];	// server game version
   238 	byte server_lang;					// langid
   238 	byte server_lang;					// langid
   239 	byte players_max;					// max players allowed on server
   239 	byte players_max;					// max players allowed on server
   240 	byte players_on;					// current count of players on server
   240 	byte players_on;					// current count of players on server
   261 void CSleep(int milliseconds) {
   261 void CSleep(int milliseconds) {
   262 #if defined(WIN32)
   262 #if defined(WIN32)
   263 Sleep(milliseconds);
   263 Sleep(milliseconds);
   264 #endif
   264 #endif
   265 #if defined(UNIX)
   265 #if defined(UNIX)
   266 #if !defined(__BEOS__) && !defined(__MORPHOS__) && !defined(__AMIGAOS__) 
   266 #if !defined(__BEOS__) && !defined(__MORPHOS__) && !defined(__AMIGAOS__)
   267 usleep(milliseconds*1000);
   267 usleep(milliseconds*1000);
   268 #endif
   268 #endif
   269 #ifdef __BEOS__
   269 #ifdef __BEOS__
   270 snooze(milliseconds*1000);
   270 snooze(milliseconds*1000);
   271 #endif
   271 #endif
   272 #if defined(__MORPHOS__) 
   272 #if defined(__MORPHOS__)
   273 usleep(milliseconds*1000);
   273 usleep(milliseconds*1000);
   274 #endif
   274 #endif
   275 #if defined(__AMIGAOS__) && !defined(__MORPHOS__) 
   275 #if defined(__AMIGAOS__) && !defined(__MORPHOS__)
   276 { 
   276 {
   277 	ULONG signals;
   277 	ULONG signals;
   278 	ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
   278 	ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
   279 
   279 
   280 	// send IORequest
   280 	// send IORequest
   281 	TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
   281 	TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
   824 		ClientState *c	= _clients;
   824 		ClientState *c	= _clients;
   825 
   825 
   826 		rp->packet_type = 5;
   826 		rp->packet_type = 5;
   827 		rp->packet_length = sizeof(rp);
   827 		rp->packet_length = sizeof(rp);
   828 		SendBytes(c, rp, sizeof(rp));
   828 		SendBytes(c, rp, sizeof(rp));
   829 		_network_ready_sent = true;	
   829 		_network_ready_sent = true;
   830 	}
   830 	}
   831 }
   831 }
   832 
   832 
   833 static void NetworkAcceptClients()
   833 static void NetworkAcceptClients()
   834 {
   834 {
   953 	s = socket(AF_INET, SOCK_STREAM, 0);
   953 	s = socket(AF_INET, SOCK_STREAM, 0);
   954 	if (s == INVALID_SOCKET) error("socket() failed");
   954 	if (s == INVALID_SOCKET) error("socket() failed");
   955 
   955 
   956 	b = 1;
   956 	b = 1;
   957 	setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));
   957 	setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));
   958 	
   958 
   959 	sin.sin_family = AF_INET;
   959 	sin.sin_family = AF_INET;
   960 	sin.sin_addr.s_addr = NetworkResolveHost(hostname);
   960 	sin.sin_addr.s_addr = NetworkResolveHost(hostname);
   961 	sin.sin_port = htons(port);
   961 	sin.sin_port = htons(port);
   962 
   962 
   963 	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) {
   963 	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) {
   978 	return true;
   978 	return true;
   979 }
   979 }
   980 
   980 
   981 void NetworkListen()
   981 void NetworkListen()
   982 {
   982 {
   983 		
   983 
   984 	SOCKET ls;
   984 	SOCKET ls;
   985 	struct sockaddr_in sin;
   985 	struct sockaddr_in sin;
   986 	int port;
   986 	int port;
   987 
   987 
   988 	port = _network_server_port;
   988 	port = _network_server_port;
   990 	DEBUG(net, 1) ("[NET][TCP] listening on port %d", port);
   990 	DEBUG(net, 1) ("[NET][TCP] listening on port %d", port);
   991 
   991 
   992 	ls = socket(AF_INET, SOCK_STREAM, 0);
   992 	ls = socket(AF_INET, SOCK_STREAM, 0);
   993 	if (ls == INVALID_SOCKET)
   993 	if (ls == INVALID_SOCKET)
   994 		error("socket() on listen socket failed");
   994 		error("socket() on listen socket failed");
   995 	
   995 
   996 	// reuse the socket
   996 	// reuse the socket
   997 	{
   997 	{
   998 		int reuse = 1; if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1)
   998 		int reuse = 1; if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1)
   999 			error("setsockopt() on listen socket failed");
   999 			error("setsockopt() on listen socket failed");
  1000 	}
  1000 	}
  1019 {
  1019 {
  1020 	ClientState *cs;
  1020 	ClientState *cs;
  1021 	int n;
  1021 	int n;
  1022 	fd_set read_fd, write_fd;
  1022 	fd_set read_fd, write_fd;
  1023 	struct timeval tv;
  1023 	struct timeval tv;
  1024 	
  1024 
  1025 	FD_ZERO(&read_fd);
  1025 	FD_ZERO(&read_fd);
  1026 	FD_ZERO(&write_fd);
  1026 	FD_ZERO(&write_fd);
  1027 
  1027 
  1028 	for(cs=_clients;cs->socket != INVALID_SOCKET; cs++) {
  1028 	for(cs=_clients;cs->socket != INVALID_SOCKET; cs++) {
  1029 		FD_SET(cs->socket, &read_fd);
  1029 		FD_SET(cs->socket, &read_fd);
  1117 				if (!ready_all) {
  1117 				if (!ready_all) {
  1118 					NetworkReceive();
  1118 					NetworkReceive();
  1119 					CSleep(5);
  1119 					CSleep(5);
  1120 					}
  1120 					}
  1121 			}
  1121 			}
  1122 				
  1122 
  1123 			_not_packet = 0;
  1123 			_not_packet = 0;
  1124 
  1124 
  1125 			new_max = max(_frame_counter + (int)_network_ahead_frames, _frame_counter_max);
  1125 			new_max = max(_frame_counter + (int)_network_ahead_frames, _frame_counter_max);
  1126 			
  1126 
  1127 			DEBUG(net,3) ("net: serv: sync max=%i, seed1=%i, seed2=%i",new_max,_sync_seed_1,_sync_seed_2);
  1127 			DEBUG(net,3) ("net: serv: sync max=%i, seed1=%i, seed2=%i",new_max,_sync_seed_1,_sync_seed_2);
  1128 			
  1128 
  1129 			sp.packet_length = sizeof(sp);
  1129 			sp.packet_length = sizeof(sp);
  1130 			sp.packet_type = 1;
  1130 			sp.packet_type = 1;
  1131 			sp.frames = new_max - _frame_counter_max;
  1131 			sp.frames = new_max - _frame_counter_max;
  1132 			sp.server = _frame_counter_max - _frame_counter;
  1132 			sp.server = _frame_counter_max - _frame_counter;
  1133 			sp.random_seed_1 = TO_LE32(_sync_seed_1);
  1133 			sp.random_seed_1 = TO_LE32(_sync_seed_1);
  1194 		}
  1194 		}
  1195 }
  1195 }
  1196 
  1196 
  1197 void NetworkShutdown()
  1197 void NetworkShutdown()
  1198 {
  1198 {
  1199 	_networking_server = false;	
  1199 	_networking_server = false;
  1200 	_networking = false;
  1200 	_networking = false;
  1201 	_networking_sync = false;
  1201 	_networking_sync = false;
  1202 	_frame_counter = 0;
  1202 	_frame_counter = 0;
  1203 	_frame_counter_max = 0;
  1203 	_frame_counter_max = 0;
  1204 	_frame_counter_srv = 0;
  1204 	_frame_counter_srv = 0;
  1253 	if (client) { port = _network_client_port; } else { port = _network_server_port; };
  1253 	if (client) { port = _network_client_port; } else { port = _network_server_port; };
  1254 
  1254 
  1255 	DEBUG(net, 1) ("[NET][UDP] listening on port %i", port);
  1255 	DEBUG(net, 1) ("[NET][UDP] listening on port %i", port);
  1256 
  1256 
  1257 	udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  1257 	udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  1258 	
  1258 
  1259 	// this disables network
  1259 	// this disables network
  1260 	_network_available = !(udp == INVALID_SOCKET);
  1260 	_network_available = !(udp == INVALID_SOCKET);
  1261 	
  1261 
  1262 	// set nonblocking mode for socket
  1262 	// set nonblocking mode for socket
  1263 	{ unsigned long blocking = 1; ioctlsocket(udp, FIONBIO, &blocking); }
  1263 	{ unsigned long blocking = 1; ioctlsocket(udp, FIONBIO, &blocking); }
  1264 
  1264 
  1265 	sin.sin_family = AF_INET;
  1265 	sin.sin_family = AF_INET;
  1266 	sin.sin_addr.s_addr = 0;
  1266 	sin.sin_addr.s_addr = 0;
  1267 	sin.sin_port = htons(port);
  1267 	sin.sin_port = htons(port);
  1268 
  1268 
  1269 	if (bind(udp, (struct sockaddr*)&sin, sizeof(sin)) != 0)
  1269 	if (bind(udp, (struct sockaddr*)&sin, sizeof(sin)) != 0)
  1270 		DEBUG(net, 1) ("[NET][UDP] error: bind failed on port %i", port);
  1270 		DEBUG(net, 1) ("[NET][UDP] error: bind failed on port %i", port);
  1271 		
  1271 
  1272 
  1272 
  1273 	// enable broadcasting
  1273 	// enable broadcasting
  1274 	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); }
  1274 	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); }
  1275 	// allow reusing
  1275 	// allow reusing
  1276 	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_REUSEADDR, (char *) &val , sizeof(val)); }
  1276 	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_REUSEADDR, (char *) &val , sizeof(val)); }
  1278 	if (client) { _udp_client_socket = udp; } else { _udp_server_socket = udp; } ;
  1278 	if (client) { _udp_client_socket = udp; } else { _udp_server_socket = udp; } ;
  1279 
  1279 
  1280 }
  1280 }
  1281 
  1281 
  1282 void NetworkUDPClose(bool client) {
  1282 void NetworkUDPClose(bool client) {
  1283 	if (client) { 
  1283 	if (client) {
  1284 		DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_client_port);
  1284 		DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_client_port);
  1285 		closesocket(_udp_client_socket);
  1285 		closesocket(_udp_client_socket);
  1286 		_udp_client_socket = INVALID_SOCKET;
  1286 		_udp_client_socket = INVALID_SOCKET;
  1287 		} else {
  1287 		} else {
  1288 		DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_server_port);
  1288 		DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_server_port);
  1299 	LONG client_len; // for some reason we need a 'LONG' under MorphOS
  1299 	LONG client_len; // for some reason we need a 'LONG' under MorphOS
  1300 #endif
  1300 #endif
  1301 	int nbytes;
  1301 	int nbytes;
  1302 	struct UDPPacket packet;
  1302 	struct UDPPacket packet;
  1303 	int packet_len;
  1303 	int packet_len;
  1304 	
  1304 
  1305 	SOCKET udp;
  1305 	SOCKET udp;
  1306 	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
  1306 	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
  1307 
  1307 
  1308 	packet_len = sizeof(packet);
  1308 	packet_len = sizeof(packet);
  1309 	client_len = sizeof(client_addr);	
  1309 	client_len = sizeof(client_addr);
  1310 	
  1310 
  1311 	nbytes = recvfrom(udp, (char *) &packet, packet_len , 0, (struct sockaddr *) &client_addr, &client_len);
  1311 	nbytes = recvfrom(udp, (char *) &packet, packet_len , 0, (struct sockaddr *) &client_addr, &client_len);
  1312 	if (nbytes>0) {
  1312 	if (nbytes>0) {
  1313 		if (packet.command_code==packet.command_check) switch (packet.command_code) {
  1313 		if (packet.command_code==packet.command_check) switch (packet.command_code) {
  1314 		
  1314 
  1315  		case NET_UDPCMD_SERVERSEARCH:
  1315  		case NET_UDPCMD_SERVERSEARCH:
  1316  			if (!client) {
  1316  			if (!client) {
  1317 				packet.command_check=packet.command_code=NET_UDPCMD_SERVERINFO;
  1317 				packet.command_check=packet.command_code=NET_UDPCMD_SERVERINFO;
  1318 				memcpy(&packet.data,&_network_game,sizeof(_network_game));
  1318 				memcpy(&packet.data,&_network_game,sizeof(_network_game));
  1319 				packet.data_len=sizeof(_network_game);
  1319 				packet.data_len=sizeof(_network_game);
  1333 				NetworkGameList * item;
  1333 				NetworkGameList * item;
  1334 
  1334 
  1335 				item = (NetworkGameList *) NetworkGameListAdd();
  1335 				item = (NetworkGameList *) NetworkGameListAdd();
  1336 				item -> ip = inet_addr(inet_ntoa(client_addr.sin_addr));
  1336 				item -> ip = inet_addr(inet_ntoa(client_addr.sin_addr));
  1337 				item -> port = ntohs(client_addr.sin_port);
  1337 				item -> port = ntohs(client_addr.sin_port);
  1338 				
  1338 
  1339 				memcpy(item,&packet.data,packet.data_len);
  1339 				memcpy(item,&packet.data,packet.data_len);
  1340  			}
  1340  			}
  1341  			break;
  1341  			break;
  1342 		}
  1342 		}
  1343 	}
  1343 	}
  1363 		out_addr.sin_addr.s_addr = bcaddr;
  1363 		out_addr.sin_addr.s_addr = bcaddr;
  1364 		res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
  1364 		res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
  1365 		if (res==-1) DEBUG(net, 1)("udp: broadcast error: %i",GET_LAST_ERROR());
  1365 		if (res==-1) DEBUG(net, 1)("udp: broadcast error: %i",GET_LAST_ERROR());
  1366 		i++;
  1366 		i++;
  1367 	}
  1367 	}
  1368 	
  1368 
  1369 }
  1369 }
  1370 
  1370 
  1371 void NetworkUDPSend(bool client, struct sockaddr_in recv,struct UDPPacket packet) {
  1371 void NetworkUDPSend(bool client, struct sockaddr_in recv,struct UDPPacket packet) {
  1372 
  1372 
  1373 	SOCKET udp;
  1373 	SOCKET udp;
  1374 	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
  1374 	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
  1375 	
  1375 
  1376 	sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &recv,sizeof(recv));
  1376 	sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &recv,sizeof(recv));
  1377 }
  1377 }
  1378 
  1378 
  1379 
  1379 
  1380 bool NetworkUDPSearchGame(const byte ** _network_detected_serverip, unsigned short * _network_detected_serverport) {
  1380 bool NetworkUDPSearchGame(const byte ** _network_detected_serverip, unsigned short * _network_detected_serverport) {
  1381 	struct UDPPacket packet;
  1381 	struct UDPPacket packet;
  1382 	int timeout=3000;
  1382 	int timeout=3000;
  1383 	
  1383 
  1384 	NetworkGameListClear();
  1384 	NetworkGameListClear();
  1385 
  1385 
  1386 	DEBUG(net, 0) ("[NET][UDP] searching server");
  1386 	DEBUG(net, 0) ("[NET][UDP] searching server");
  1387 	*_network_detected_serverip = "255.255.255.255";
  1387 	*_network_detected_serverip = "255.255.255.255";
  1388 	*_network_detected_serverport = 0;
  1388 	*_network_detected_serverport = 0;
  1389 	
  1389 
  1390 	packet.command_check=packet.command_code=NET_UDPCMD_SERVERSEARCH;
  1390 	packet.command_check=packet.command_code=NET_UDPCMD_SERVERSEARCH;
  1391 	packet.data_len=0;
  1391 	packet.data_len=0;
  1392 	NetworkUDPBroadCast(true, packet);
  1392 	NetworkUDPBroadCast(true, packet);
  1393 	while (timeout>=0) {
  1393 	while (timeout>=0) {
  1394 		CSleep(100);
  1394 		CSleep(100);
  1401 			*_network_detected_serverip=inet_ntoa(*(struct in_addr *) &item->ip);
  1401 			*_network_detected_serverip=inet_ntoa(*(struct in_addr *) &item->ip);
  1402 			*_network_detected_serverport=item->port;
  1402 			*_network_detected_serverport=item->port;
  1403  			timeout=-1;
  1403  			timeout=-1;
  1404  			DEBUG(net, 0) ("[NET][UDP] server found on %s", *_network_detected_serverip);
  1404  			DEBUG(net, 0) ("[NET][UDP] server found on %s", *_network_detected_serverip);
  1405  			}
  1405  			}
  1406 	
  1406 
  1407 		}
  1407 		}
  1408 
  1408 
  1409 	return (*_network_detected_serverport>0);
  1409 	return (*_network_detected_serverport>0);
  1410 		
  1410 
  1411 }
  1411 }
  1412 
  1412 
  1413 
  1413 
  1414 // *************************** //
  1414 // *************************** //
  1415 // * New Network Core System * //
  1415 // * New Network Core System * //
  1418 void NetworkIPListInit() {
  1418 void NetworkIPListInit() {
  1419 	struct hostent* he = NULL;
  1419 	struct hostent* he = NULL;
  1420 	char hostname[250];
  1420 	char hostname[250];
  1421 	uint32 bcaddr;
  1421 	uint32 bcaddr;
  1422 	int i=0;
  1422 	int i=0;
  1423 		
  1423 
  1424 	gethostname(hostname,250);
  1424 	gethostname(hostname,250);
  1425 	DEBUG(net, 2) ("[NET][IP] init for host %s", hostname);
  1425 	DEBUG(net, 2) ("[NET][IP] init for host %s", hostname);
  1426 	he=gethostbyname((char *) hostname);
  1426 	he=gethostbyname((char *) hostname);
  1427 
  1427 
  1428 	if (he == NULL) {
  1428 	if (he == NULL) {
  1429 		he = gethostbyname("localhost");
  1429 		he = gethostbyname("localhost");
  1430 		}
  1430 		}
  1431 	
  1431 
  1432 	if (he == NULL) {
  1432 	if (he == NULL) {
  1433 		bcaddr = inet_addr("127.0.0.1");
  1433 		bcaddr = inet_addr("127.0.0.1");
  1434 		he = gethostbyaddr(inet_ntoa(*(struct in_addr *) &bcaddr), sizeof(bcaddr), AF_INET);
  1434 		he = gethostbyaddr(inet_ntoa(*(struct in_addr *) &bcaddr), sizeof(bcaddr), AF_INET);
  1435 		}
  1435 		}
  1436 
  1436 
  1437 	if (he == NULL) {
  1437 	if (he == NULL) {
  1438 		DEBUG(net, 2) ("[NET][IP] cannot resolve %s", hostname);
  1438 		DEBUG(net, 2) ("[NET][IP] cannot resolve %s", hostname);
  1439 	} else {
  1439 	} else {
  1440 		while(he->h_addr_list[i]) { 
  1440 		while(he->h_addr_list[i]) {
  1441 			bcaddr = inet_addr(inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
  1441 			bcaddr = inet_addr(inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
  1442 			_network_ip_list[i]=bcaddr;
  1442 			_network_ip_list[i]=bcaddr;
  1443 			DEBUG(net, 2) ("[NET][IP] add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
  1443 			DEBUG(net, 2) ("[NET][IP] add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
  1444 			i++;
  1444 			i++;
  1445 		}
  1445 		}
  1446 
  1446 
  1447 	}
  1447 	}
  1448 	_network_ip_list[i]=0;
  1448 	_network_ip_list[i]=0;
  1449 	
  1449 
  1450 }
  1450 }
  1451 
  1451 
  1452 /* *************************************************** */
  1452 /* *************************************************** */
  1453 
  1453 
  1454 void NetworkCoreInit() {
  1454 void NetworkCoreInit() {
  1466 	if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
  1466 	if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
  1467 		DEBUG(net, 3) ("[NET][Core] error: WSAStartup failed");
  1467 		DEBUG(net, 3) ("[NET][Core] error: WSAStartup failed");
  1468 		_network_available=false;
  1468 		_network_available=false;
  1469 		}
  1469 		}
  1470 }
  1470 }
  1471 #else 
  1471 #else
  1472 
  1472 
  1473 // [morphos/amigaos] bsd-socket startup
  1473 // [morphos/amigaos] bsd-socket startup
  1474 
  1474 
  1475 #if defined(__MORPHOS__) || defined(__AMIGA__)
  1475 #if defined(__MORPHOS__) || defined(__AMIGA__)
  1476 {
  1476 {
  1484 	// for usleep() implementation (only required for legacy AmigaOS builds)
  1484 	// for usleep() implementation (only required for legacy AmigaOS builds)
  1485 	if ( (TimerPort = CreateMsgPort()) ) {
  1485 	if ( (TimerPort = CreateMsgPort()) ) {
  1486 		if ( (TimerRequest = (struct timerequest *) CreateIORequest(TimerPort, sizeof(struct timerequest))) ) {
  1486 		if ( (TimerRequest = (struct timerequest *) CreateIORequest(TimerPort, sizeof(struct timerequest))) ) {
  1487 			if ( OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *) TimerRequest, 0) == 0 ) {
  1487 			if ( OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *) TimerRequest, 0) == 0 ) {
  1488 				if ( !(TimerBase = TimerRequest->tr_node.io_Device) ) {
  1488 				if ( !(TimerBase = TimerRequest->tr_node.io_Device) ) {
  1489 					// free ressources... 
  1489 					// free ressources...
  1490 					DEBUG(net, 3) ("[NET][Core] Couldn't initialize timer.");
  1490 					DEBUG(net, 3) ("[NET][Core] Couldn't initialize timer.");
  1491 					_network_available=false;
  1491 					_network_available=false;
  1492 				}
  1492 				}
  1493 			}
  1493 			}
  1494 		}
  1494 		}
  1495 	}
  1495 	}
  1496 	#endif 
  1496 	#endif
  1497 
  1497 
  1498 }
  1498 }
  1499 #else
  1499 #else
  1500 
  1500 
  1501 // [linux/macos] unix-socket startup
  1501 // [linux/macos] unix-socket startup
  1525 void NetworkCoreShutdown() {
  1525 void NetworkCoreShutdown() {
  1526 
  1526 
  1527 DEBUG(net, 3) ("[NET][Core] shutdown()");
  1527 DEBUG(net, 3) ("[NET][Core] shutdown()");
  1528 
  1528 
  1529 #if defined(__MORPHOS__) || defined(__AMIGA__)
  1529 #if defined(__MORPHOS__) || defined(__AMIGA__)
  1530 {	
  1530 {
  1531 	// free allocated ressources
  1531 	// free allocated ressources
  1532 	#if !defined(__MORPHOS__) 
  1532 	#if !defined(__MORPHOS__)
  1533   if (TimerBase)    { CloseDevice((struct IORequest *) TimerRequest); }
  1533   if (TimerBase)    { CloseDevice((struct IORequest *) TimerRequest); }
  1534   if (TimerRequest) { DeleteIORequest(TimerRequest); }
  1534   if (TimerRequest) { DeleteIORequest(TimerRequest); }
  1535   if (TimerPort)    { DeleteMsgPort(TimerPort); }
  1535   if (TimerPort)    { DeleteMsgPort(TimerPort); }
  1536 	#endif
  1536 	#endif
  1537 
  1537 
  1572 	NetworkInitialize();
  1572 	NetworkInitialize();
  1573 	_networking = NetworkConnect(b, port);
  1573 	_networking = NetworkConnect(b, port);
  1574 	if (_networking) {
  1574 	if (_networking) {
  1575 		NetworkLobbyShutdown();
  1575 		NetworkLobbyShutdown();
  1576 	} else {
  1576 	} else {
  1577 		if (_networking_override) 
  1577 		if (_networking_override)
  1578 			NetworkLobbyShutdown();
  1578 			NetworkLobbyShutdown();
  1579 		
  1579 
  1580 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOCONNECTION,0,0);
  1580 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOCONNECTION,0,0);
  1581 		_switch_mode_errorstr = STR_NETWORK_ERR_NOCONNECTION;
  1581 		_switch_mode_errorstr = STR_NETWORK_ERR_NOCONNECTION;
  1582 	}
  1582 	}
  1583 	return _networking;
  1583 	return _networking;
  1584 }
  1584 }
  1605 {
  1605 {
  1606 	/* terminate server */
  1606 	/* terminate server */
  1607 	if (_networking_server) {
  1607 	if (_networking_server) {
  1608 		NetworkUDPClose(false);
  1608 		NetworkUDPClose(false);
  1609 		NetworkClose(false);
  1609 		NetworkClose(false);
  1610 		} 
  1610 		}
  1611 
  1611 
  1612 	/* terminate client connection */
  1612 	/* terminate client connection */
  1613 	else if (_networking) {
  1613 	else if (_networking) {
  1614 		NetworkClose(true);
  1614 		NetworkClose(true);
  1615 		}
  1615 		}
  1616 	
  1616 
  1617 	NetworkShutdown();
  1617 	NetworkShutdown();
  1618 }
  1618 }
  1619 
  1619 
  1620 /* *************************************************** */
  1620 /* *************************************************** */
  1621 
  1621 
  1668 // * Network Game List Extensions * //
  1668 // * Network Game List Extensions * //
  1669 // ******************************** //
  1669 // ******************************** //
  1670 
  1670 
  1671 void NetworkGameListClear() {
  1671 void NetworkGameListClear() {
  1672 NetworkGameList * item;
  1672 NetworkGameList * item;
  1673 NetworkGameList * next; 
  1673 NetworkGameList * next;
  1674 
  1674 
  1675 DEBUG(net, 4) ("[NET][G-List] cleared server list");
  1675 DEBUG(net, 4) ("[NET][G-List] cleared server list");
  1676 
  1676 
  1677 item = _network_game_list;
  1677 item = _network_game_list;
  1678 while (item != NULL) {
  1678 while (item != NULL) {
  1684 _network_game_count=0;
  1684 _network_game_count=0;
  1685 }
  1685 }
  1686 
  1686 
  1687 char * NetworkGameListAdd() {
  1687 char * NetworkGameListAdd() {
  1688 NetworkGameList * item;
  1688 NetworkGameList * item;
  1689 NetworkGameList * before; 
  1689 NetworkGameList * before;
  1690 
  1690 
  1691 DEBUG(net, 4) ("[NET][G-List] added server to list");
  1691 DEBUG(net, 4) ("[NET][G-List] added server to list");
  1692 
  1692 
  1693 item = _network_game_list;
  1693 item = _network_game_list;
  1694 before = item;
  1694 before = item;
  1724 
  1724 
  1725 }
  1725 }
  1726 
  1726 
  1727 char * NetworkGameListItem(uint16 index) {
  1727 char * NetworkGameListItem(uint16 index) {
  1728 NetworkGameList * item;
  1728 NetworkGameList * item;
  1729 NetworkGameList * next; 
  1729 NetworkGameList * next;
  1730 uint16 cnt = 0;
  1730 uint16 cnt = 0;
  1731 
  1731 
  1732 item = _network_game_list;
  1732 item = _network_game_list;
  1733 
  1733 
  1734 while ((item != NULL) && (cnt != index)) {
  1734 while ((item != NULL) && (cnt != index)) {
  1747 void NetworkGameFillDefaults() {
  1747 void NetworkGameFillDefaults() {
  1748 	NetworkGameInfo * game = &_network_game;
  1748 	NetworkGameInfo * game = &_network_game;
  1749 #if defined(WITH_REV)
  1749 #if defined(WITH_REV)
  1750 	extern char _openttd_revision[];
  1750 	extern char _openttd_revision[];
  1751 #endif
  1751 #endif
  1752 	
  1752 
  1753 	DEBUG(net, 4) ("[NET][G-Info] setting defaults");
  1753 	DEBUG(net, 4) ("[NET][G-Info] setting defaults");
  1754 
  1754 
  1755 	ttd_strlcpy(game->server_name,"OpenTTD Game",13);
  1755 	ttd_strlcpy(game->server_name,"OpenTTD Game",13);
  1756 	game->game_password[0]='\0';
  1756 	game->game_password[0]='\0';
  1757 	game->map_name[0]='\0';
  1757 	game->map_name[0]='\0';
  1766 	game->map_width=0;
  1766 	game->map_width=0;
  1767 	game->map_set=0;
  1767 	game->map_set=0;
  1768 
  1768 
  1769 	game->players_max=8;
  1769 	game->players_max=8;
  1770 	game->players_on=0;
  1770 	game->players_on=0;
  1771 	
  1771 
  1772 	game->server_lang=_dynlang.curr;
  1772 	game->server_lang=_dynlang.curr;
  1773 }
  1773 }
  1774 
  1774 
  1775 void NetworkGameChangeDate(uint16 newdate) {
  1775 void NetworkGameChangeDate(uint16 newdate) {
  1776 	if (_networking_server) {
  1776 	if (_networking_server) {