Changeset - r105:9609297bc621
[Not reviewed]
master
0 9 0
dominik - 20 years ago 2004-08-22 10:23:37
dominik@openttd.org
(svn r106) New network core (by sign_de)

Features:
* network core is dynamicly loaded when needed (-n isn't needed anymore)
for easy switching between single and multiplayer. But commandline
shortcuts are still enabled:
-n = autodetect network server
-n [ip] = connect to the server
* udp now uses 2 different ports
- you can run 1 server and serveral clients on one pc
- the clients udp-socket gets unloaded when the
network game starts
- the servers udp-sockets remains online to allow the
network gui to detect itself
* new gameinfo structure
this struct is available for every online/lan game
* dynamic NetworkGameList
9 files changed with 692 insertions and 279 deletions:
0 comments (0 inline, 0 general)
functions.h
Show inline comments
 
@@ -121,19 +121,36 @@ int CalcBridgeLenCostFactor(int x);
 
typedef void CommandCallback(bool success, uint tile, uint32 p1, uint32 p2);
 
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd);
 

	
 
void NetworkConnect(const char *hostname, int port);
 
void NetworkReceive();
 
void NetworkSend();
 
void NetworkProcessCommands();
 
void NetworkListen(int port);
 
void NetworkInitialize(const char *hostname);
 
void NetworkListen();
 
void NetworkInitialize();
 
void NetworkShutdown();
 
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback);
 
void NetworkStartSync();
 
void NetworkUDPListen(int port);
 
void NetworkUDPReceive();
 
void NetworkStartSync(bool fcreset);
 
void NetworkClose(bool client);
 

	
 
void NetworkIPListInit();
 
bool NetworkUDPSearchServer();
 

	
 
void NetworkCoreInit();
 
void NetworkCoreShutdown();
 
void NetworkCoreDisconnect();
 
void NetworkCoreLoop(bool incomming);
 
bool NetworkCoreConnectGame(byte* b, unsigned short port);
 
bool NetworkCoreStartGame();
 

	
 
void NetworkLobbyShutdown();
 
void NetworkLobbyInit();
 

	
 
void NetworkGameListClear();
 
char * NetworkGameListAdd();
 
void NetworkGameListFromLAN();
 
void NetworkGameListFromInternet();
 
char * NetworkGameListItem(uint16 index);
 

	
 
void NetworkGameFillDefaults();
 
void NetworkGameChangeDate(uint16 newdate);
 

	
 
/* misc_cmd.c */
 
void PlaceTreesRandomly();
intro_gui.c
Show inline comments
 
@@ -58,7 +58,9 @@ static void SelectGameWndProc(Window *w,
 
				DoCommandP(0, 0, 0, NULL, CMD_SET_SINGLE_PLAYER);
 
			break;
 
		case 7:
 
			ShowNetworkGameWindow();
 
			if (!_network_available) {
 
				ShowErrorMessage(-1,STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
 
				} else ShowNetworkGameWindow();
 
			break;
 
		case 8: ShowGameOptions(); break;
 
		case 9: ShowGameDifficulty(); break;
 
@@ -118,7 +120,7 @@ int32 CmdGenRandomNewGame(int x, int y, 
 
	_random_seed_1 = p1;
 
	_random_seed_2 = p2;
 

	
 
	if (_networking) { NetworkStartSync(); }
 
	if (_networking) { NetworkStartSync(true); }
 

	
 
	MakeNewGame();
 
	return 0;
 
@@ -159,7 +161,7 @@ int32 CmdStartScenario(int x, int y, uin
 
	_random_seed_1 = p1;
 
	_random_seed_2 = p2;
 

	
 
	if (_networking) { NetworkStartSync(); }
 
	if (_networking) { NetworkStartSync(true); }
 

	
 
	StartScenario();
 
	return 0;
lang/english.txt
Show inline comments
 
@@ -1213,6 +1213,9 @@ STR_NETWORK_NEW_COMPANY						:{BLACK}New
 
STR_NETWORK_NEW_COMPANY_TIP				:{BLACK}Open a new company
 
STR_NETWORK_READY									:{BLACK}Ready
 

	
 
STR_NETWORK_ERR_NOTAVAILABLE			:{WHITE} No network devices found or compiled without ENABLE_NETWORK
 
STR_NETWORK_ERR_NOSERVER			:{WHITE} Could not find any network game
 
STR_NETWORK_ERR_NOCONNECTION			:{WHITE} The server didn't answer the request
 

	
 
############ end network gui strings
 

	
misc.c
Show inline comments
 
@@ -542,6 +542,8 @@ void IncreaseDate()
 
	/* yeah, increse day counter and call various daily loops */
 
	_date++;
 

	
 
	NetworkGameChangeDate(_date);
 

	
 
	_vehicle_id_ctr_day = 0;
 

	
 
	DisasterDailyLoop();
network.c
Show inline comments
 
#include "stdafx.h"
 
#include "ttd.h"
 
#include "gui.h"
 
#include "command.h"
 
#include "player.h"
 

	
 
@@ -180,9 +181,10 @@ typedef struct FutureSeeds {
 
static FutureSeeds _future_seed[8];
 
static int _num_future_seed;
 

	
 
static SOCKET _listensocket;
 
static SOCKET _udpsocket;
 
static SOCKET _listensocket; // tcp socket
 

	
 
static SOCKET _udp_client_socket; // udp server socket
 
static SOCKET _udp_server_socket; // udp client socket
 

	
 
typedef struct UDPPacket {
 
	byte command_code;
 
@@ -194,15 +196,13 @@ typedef struct UDPPacket {
 
enum {
 
	NET_UDPCMD_SERVERSEARCH = 1,
 
	NET_UDPCMD_SERVERACTIVE,
 
	NET_UDPCMD_GETSERVERINFO,
 
	NET_UDPCMD_SERVERINFO,
 
};
 

	
 
uint32 _network_ip_list[10]; // Network ips
 
char * _network_detected_serverip = "255.255.255.255"; // UDP Broadcast detected server-ip
 
uint32 _network_detected_serverport = 0; // UDP Broadcast detected server-port
 
void NetworkUDPSend(bool client, struct sockaddr_in recv,struct UDPPacket packet);
 

	
 
void NetworkUDPSend(struct sockaddr_in recv,struct UDPPacket packet);
 

	
 
static bool _network_synced;
 
uint32 _network_ip_list[10]; // network ip list
 

	
 
// this is set to point to the savegame
 
static byte *_transmit_file;
 
@@ -210,8 +210,51 @@ static size_t _transmit_file_size;
 

	
 
static FILE *_recv_file;
 

	
 
typedef struct NetworkGameInfo {	
 
	char server_name[40]; // name of the game
 
	char server_revision[8]; // server game version
 
	byte server_lang; // langid
 
	byte players_max; // max players allowed on server
 
	byte players_on; // current count of players on server
 
	uint16 game_date; // current date
 
	char game_password[10]; // should fit ... 14 chars
 
	char map_name[40]; // map which is played ["random" for a randomized map]
 
	uint map_width; // map width / 8
 
	uint map_height; // map height / 8
 
	byte map_set; // graphical set
 
} NetworkGameInfo;
 

	
 
typedef struct NetworkGameList {
 
	NetworkGameInfo item;
 
	uint32 ip;
 
	uint16 port;
 
	char * _next;
 
} NetworkGameList;
 

	
 
static NetworkGameInfo _network_game;
 
static NetworkGameList * _network_game_list = NULL;
 

	
 
/* multi os compatible sleep function */
 
void CSleep(int milliseconds) {
 
#if defined(WIN32)
 
Sleep(milliseconds);
 
#endif
 
#if defined(UNIX)
 
#ifndef __BEOS__ 
 
usleep(milliseconds*1000);
 
#endif
 
#ifdef __BEOS__
 
snooze(milliseconds*1000);
 
#endif
 
#endif
 
}
 

	
 
//////////////////////////////////////////////////////////////////////
 

	
 
// ****************************** //
 
// * TCP Packets and Handlers   * //
 
// ****************************** //
 

	
 
static QueuedCommand *AllocQueuedCommand(CommandQueue *nq)
 
{
 
	QueuedCommand *qp = (QueuedCommand*)calloc(sizeof(QueuedCommand), 1);
 
@@ -471,12 +514,13 @@ static void HandleFilePacket(FilePacketH
 

	
 
		// sync to server.
 
		_networking_queuing = false;
 

	
 
		NetworkStartSync(false);
 
/*		
 
		_networking_sync = true;
 
		_frame_counter = 0; // start executing at frame 0.
 
		_sync_seed_1 = _sync_seed_2 = 0;
 
		_num_future_seed = 0;
 
		memset(_my_seed_list, 0, sizeof(_my_seed_list));
 
		memset(_my_seed_list, 0, sizeof(_my_seed_list)); */
 

	
 
		if (_network_playas == 0) {
 
			// send a command to make a new player
 
@@ -504,7 +548,7 @@ static void CloseClient(ClientState *cs)
 
{
 
	Packet *p, *next;
 

	
 
	printf("CloseClient\n");
 
	DEBUG(misc,1) ("[NET][TCP] closed client connection");
 

	
 
	assert(cs->socket != INVALID_SOCKET);
 

	
 
@@ -523,6 +567,8 @@ static void CloseClient(ClientState *cs)
 
	}
 
	cs->socket = INVALID_SOCKET;
 

	
 
	if (_networking_server) _network_game.players_on--;
 

	
 
	_num_clients--;
 
}
 

	
 
@@ -683,6 +729,8 @@ static ClientState *AllocClient(SOCKET s
 
	if (_num_clients == MAX_CLIENTS)
 
		return NULL;
 

	
 
	if (_networking_server) _network_game.players_on++;
 

	
 
	cs = &_clients[_num_clients++];
 
	memset(cs, 0, sizeof(*cs));
 
	cs->last = &cs->head;
 
@@ -779,14 +827,89 @@ static void SendQueuedCommandsToNewClien
 

	
 
}
 

	
 
// ************************** //
 
// * TCP Networking         * //
 
// ************************** //
 

	
 
bool NetworkConnect(const char *hostname, int port)
 
{
 
	SOCKET s;
 
	struct sockaddr_in sin;
 
	int b;
 

	
 
	DEBUG(misc, 1) ("[NET][TCP] Connecting to %s %d", hostname, port);
 

	
 
	s = socket(AF_INET, SOCK_STREAM, 0);
 
	if (s == INVALID_SOCKET) error("socket() failed");
 

	
 
	b = 1;
 
	setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));
 
	
 
	sin.sin_family = AF_INET;
 
	sin.sin_addr.s_addr = inet_addr(hostname);
 
	sin.sin_port = htons(port);
 

	
 
	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) {
 
		NetworkClose(true);
 
		return false;
 
		}
 

	
 
	// set nonblocking mode for socket..
 
	{ unsigned long blocking = 1; ioctlsocket(s, FIONBIO, &blocking); }
 

	
 
	// in client mode, only the first client field is used. it's pointing to the server.
 
	AllocClient(s);
 

	
 
	// queue packets.. because we're waiting for the savegame.
 
	_networking_queuing = true;
 
	_frame_counter_max = 0;
 

	
 
	return true;
 
}
 

	
 
void NetworkListen()
 
{
 
		
 
	SOCKET ls;
 
	struct sockaddr_in sin;
 
	int port;
 

	
 
	port = _network_server_port;
 

	
 
	DEBUG(misc, 1) ("[NET][TCP] listening on port %d", port);
 

	
 
	ls = socket(AF_INET, SOCK_STREAM, 0);
 
	if (ls == INVALID_SOCKET)
 
		error("socket() on listen socket failed");
 
	
 
	// reuse the socket
 
	{
 
		int reuse = 1; if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1)
 
			error("setsockopt() on listen socket failed");
 
	}
 

	
 
	// set nonblocking mode for socket
 
	{ unsigned long blocking = 1; ioctlsocket(ls, FIONBIO, &blocking); }
 

	
 
	sin.sin_family = AF_INET;
 
	sin.sin_addr.s_addr = 0;
 
	sin.sin_port = htons(port);
 

	
 
	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0)
 
		error("bind() failed");
 

	
 
	if (listen(ls, 1) != 0)
 
		error("listen() failed");
 

	
 
	_listensocket = ls;
 
}
 

	
 
void NetworkReceive()
 
{
 
	ClientState *cs;
 
	int n;
 
	fd_set read_fd, write_fd;
 
	struct timeval tv;
 

	
 
	NetworkUDPReceive(); // udp handling
 
	
 
	FD_ZERO(&read_fd);
 
	FD_ZERO(&write_fd);
 
@@ -897,165 +1020,76 @@ void NetworkSend()
 
	}
 
}
 

	
 
void NetworkConnect(const char *hostname, int port)
 
{
 
	SOCKET s;
 
	struct sockaddr_in sin;
 
	int b;
 

	
 

	
 
	s = socket(AF_INET, SOCK_STREAM, 0);
 
	if (s == INVALID_SOCKET) error("socket() failed");
 

	
 
	b = 1;
 
	setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));
 

	
 
	if (strcmp(hostname,"auto")==0) {
 
		// autodetect server over udp broadcast [works 4 lan]
 
		if (NetworkUDPSearchServer()) {
 
			hostname=_network_detected_serverip;
 
			port=_network_detected_serverport;
 
		} else {
 
			error("udp: server not found");
 
		}
 
	}
 
	
 
	sin.sin_family = AF_INET;
 
	sin.sin_addr.s_addr = inet_addr(hostname);
 
	sin.sin_port = htons(port);
 

	
 
	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0)
 
		error("connect() failed");
 

	
 
	// set nonblocking mode for socket..
 
	{ unsigned long blocking = 1; ioctlsocket(s, FIONBIO, &blocking); }
 

	
 
	// in client mode, only the first client field is used. it's pointing to the server.
 
	AllocClient(s);
 

	
 
	// queue packets.. because we're waiting for the savegame.
 
	_networking_queuing = true;
 
	_frame_counter_max = 0;
 

	
 
}
 

	
 
void NetworkListen(int port)
 
{
 
		
 
	SOCKET ls;
 
	struct sockaddr_in sin;
 

	
 
	ls = socket(AF_INET, SOCK_STREAM, 0);
 
	if (ls == INVALID_SOCKET)
 
		error("socket() on listen socket failed");
 
	
 
	// reuse the socket
 
	{
 
		int reuse = 1; if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1)
 
			error("setsockopt() on listen socket failed");
 
	}
 

	
 
	// set nonblocking mode for socket
 
	{ unsigned long blocking = 1; ioctlsocket(ls, FIONBIO, &blocking); }
 

	
 
	sin.sin_family = AF_INET;
 
	sin.sin_addr.s_addr = 0;
 
	sin.sin_port = htons(port);
 

	
 
	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0)
 
		error("bind() failed");
 

	
 
	if (listen(ls, 1) != 0)
 
		error("listen() failed");
 

	
 
	_listensocket = ls;
 
}
 

	
 
void NetworkInitialize(const char *hostname)
 
void NetworkInitialize()
 
{
 
	ClientState *cs;
 

	
 
#if defined(WIN32)
 
	WSADATA wsa;
 
	if (WSAStartup(MAKEWORD(2,0), &wsa) != 0)
 
		error("WSAStartup failed");
 
#endif
 

	
 
#if defined(__MORPHOS__) || defined(__AMIGA__)
 
	if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) {
 
		error("Couldn't open bsdsocket.library version 4.");
 
	}
 
#endif
 

	
 
	_command_queue.last = &_command_queue.head;
 
	_ack_queue.last = &_ack_queue.head;
 

	
 
	// invalidate all clients
 
	for(cs=_clients; cs != &_clients[MAX_CLIENTS]; cs++)
 
		cs->socket = INVALID_SOCKET;
 
	
 
	/*	startup udp listener
 
	 *	- only if this instance is a server, so clients can find it
 
	 *	OR
 
	 *  - a client, wanting to find a server to connect to
 
	 */
 
	if (hostname == NULL  || strcmp(hostname,"auto") == 0) {
 
		printf("Trying to open UDP port...\n");		
 
		NetworkUDPListen(_network_port);
 
	}
 

	
 
}
 

	
 
void NetworkClose(bool client) {
 

	
 
	ClientState *cs;
 
	// invalidate all clients
 

	
 
	for(cs=_clients; cs != &_clients[MAX_CLIENTS]; cs++) if (cs->socket != INVALID_SOCKET) {
 
		CloseClient(cs);
 
		}
 

	
 
	if (!client) {
 
		// if in servermode --> close listener
 
		closesocket(_listensocket);
 
		_listensocket= INVALID_SOCKET;
 
		DEBUG(misc,1) ("[NET][TCP] closed listener on port %i", _network_server_port);
 
		}
 
}
 

	
 
void NetworkShutdown()
 
{
 
#if defined(__MORPHOS__) || defined(__AMIGA__)
 
	if (SocketBase) {
 
		CloseLibrary(SocketBase);
 
	}
 
#endif
 

	
 
}
 

	
 
// switch to synced mode.
 
void NetworkStartSync()
 
void NetworkStartSync(bool fcreset)
 
{
 
	DEBUG(misc,3) ("[NET][SYNC] switching to synced game mode");
 
	_networking_sync = true;
 
	_frame_counter = 0;
 
	_frame_counter_max = 0;
 
	_frame_counter_srv = 0;
 
	if (fcreset) {
 
		_frame_counter_max = 0;
 
		_frame_counter_srv = 0;
 
		}
 
	_num_future_seed = 0;
 
	_sync_seed_1 = _sync_seed_2 = 0;
 
	memset(_my_seed_list, 0, sizeof(_my_seed_list));
 

	
 
}
 

	
 
// ************************** //
 
// * UDP Network Extensions * //
 
// ************************** //
 

	
 
/* multi os compatible sleep function */
 
void CSleep(int milliseconds) {
 
#if defined(WIN32)
 
Sleep(milliseconds);
 
#endif
 
#if defined(UNIX)
 
#ifndef __BEOS__ 
 
usleep(milliseconds*1000);
 
#endif
 
#ifdef __BEOS__
 
snooze(milliseconds*1000);
 
#endif
 
#endif
 
}
 

	
 
void NetworkUDPListen(int port)
 
void NetworkUDPListen(bool client)
 
{
 
	SOCKET udp;
 
	struct sockaddr_in sin;
 
	int port;
 

	
 
	DEBUG(misc,0) ("udp: listener initiated on port %i", port);
 
	NetworkIPListInit();
 
	if (client) { port = _network_client_port; } else { port = _network_server_port; };
 

	
 
	DEBUG(misc,1) ("[NET][UDP] listening on port %i", port);
 

	
 
	udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 
	if (udp == INVALID_SOCKET)
 
		error("udp: socket() on listen socket failed");
 
	
 
	// this disables network
 
	_network_available = !(udp == INVALID_SOCKET);
 
	
 
	// set nonblocking mode for socket
 
	{ unsigned long blocking = 1; ioctlsocket(udp, FIONBIO, &blocking); }
 
@@ -1065,137 +1099,502 @@ void NetworkUDPListen(int port)
 
	sin.sin_port = htons(port);
 

	
 
	if (bind(udp, (struct sockaddr*)&sin, sizeof(sin)) != 0)
 
		error("udp: bind() failed");
 
		DEBUG(misc,1) ("[NET][UDP] error: bind failed on port %i", port);
 
		
 

	
 
	// enable broadcasting
 
	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); }
 
	
 
	_udpsocket = udp;
 
	// allow reusing
 
	{ unsigned long val=1; setsockopt(udp, SOL_SOCKET, SO_REUSEADDR, (char *) &val , sizeof(val)); }
 

	
 
	if (client) { _udp_client_socket = udp; } else { _udp_server_socket = udp; } ;
 

	
 
}
 

	
 
void NetworkUDPReceive() {
 
void NetworkUDPClose(bool client) {
 
	if (client) { 
 
		DEBUG(misc,1) ("[NET][UDP] closed listener on port %i", _network_client_port);
 
		closesocket(_udp_client_socket);
 
		_udp_client_socket = INVALID_SOCKET;
 
		} else {
 
		DEBUG(misc,1) ("[NET][UDP] closed listener on port %i", _network_server_port);
 
		closesocket(_udp_server_socket);
 
		_udp_server_socket = INVALID_SOCKET;
 
		};
 
	}
 

	
 
void NetworkUDPReceive(bool client) {
 
	struct sockaddr_in client_addr;
 
	int client_len;
 
	int nbytes;
 
	struct UDPPacket packet;
 
	int packet_len;
 
	
 
	SOCKET udp;
 
	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
 

	
 
	packet_len = sizeof(packet);
 
	client_len = sizeof(client_addr);	
 
	
 
	nbytes = recvfrom(_udpsocket, (char *) &packet, packet_len , 0, (struct sockaddr *) &client_addr, &client_len);
 
	nbytes = recvfrom(udp, (char *) &packet, packet_len , 0, (struct sockaddr *) &client_addr, &client_len);
 
	if (nbytes>0) {
 
		if (packet.command_code==packet.command_check) switch (packet.command_code) {
 
		
 
		case NET_UDPCMD_SERVERSEARCH:
 
			if (_networking_server) {
 
				packet.command_check=packet.command_code=NET_UDPCMD_SERVERACTIVE;
 
				NetworkUDPSend(client_addr, packet);
 
 		case NET_UDPCMD_SERVERSEARCH:
 
 			if (!client) {
 
				packet.command_check=packet.command_code=NET_UDPCMD_SERVERINFO;
 
				memcpy(&packet.data,&_network_game,sizeof(_network_game));
 
				packet.data_len=sizeof(_network_game);
 
 				NetworkUDPSend(client,client_addr, packet);
 
 			}
 
 			break;
 
		case NET_UDPCMD_GETSERVERINFO:
 
			if (!client) {
 
				packet.command_check=packet.command_code=NET_UDPCMD_SERVERINFO;
 
				memcpy(&packet.data,&_network_game,sizeof(_network_game));
 
				packet.data_len=sizeof(_network_game);
 
				NetworkUDPSend(client,client_addr, packet);
 
			}
 
			break;
 
		case NET_UDPCMD_SERVERACTIVE:
 
			if (!_networking_server) {
 
				_network_detected_serverip=inet_ntoa(*(struct in_addr *) &client_addr.sin_addr);
 
				_network_detected_serverport=ntohs(client_addr.sin_port);
 
			}
 
			break;
 
		case NET_UDPCMD_SERVERINFO:
 
 			if (client) {
 
				NetworkGameList * item;
 

	
 
				item = (NetworkGameList *) NetworkGameListAdd();
 
				item -> ip = inet_addr(inet_ntoa(client_addr.sin_addr));
 
				item -> port = ntohs(client_addr.sin_port);
 
				
 
				memcpy(item,&packet.data,packet.data_len);
 
 			}
 
 			break;
 
		}
 
	}
 
}
 

	
 
void NetworkIPListInit() {
 
	struct hostent* he;
 
	char hostname[250];
 
	uint32 bcaddr;
 
	int i=0;
 
	
 
	_network_detected_serverip="";
 
	
 
	gethostname(hostname,250);
 
	DEBUG(misc,0) ("iplist: init for host %s", hostname);
 
	he=gethostbyname((char *) hostname);
 
	
 
	if (he == NULL) {
 
		DEBUG(misc, 0) ("iplist: gethostbyname failed for host %s...trying with IP address", hostname);
 
		bcaddr = inet_addr(hostname);
 
		he = gethostbyaddr(inet_ntoa(*(struct in_addr *)bcaddr), sizeof(bcaddr), AF_INET);
 
	}
 

	
 

	
 
	if (he == NULL) {
 
		DEBUG(misc, 0) ("iplist: cannot resolve %s", hostname);
 
	} else {
 
		while(he->h_addr_list[i]) { 
 
			bcaddr = inet_addr(inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
 
			_network_ip_list[i]=bcaddr;
 
			DEBUG(misc,0) ("iplist: add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
 
			i++;
 
		}
 
	}
 
	_network_ip_list[i]=0;
 
	
 
}
 

	
 
void NetworkUDPBroadCast(struct UDPPacket packet) {
 
void NetworkUDPBroadCast(bool client, struct UDPPacket packet) {
 
	int i=0, res;
 
	struct sockaddr_in out_addr;
 
	uint32 bcaddr;
 
	byte * bcptr;
 

	
 
	SOCKET udp;
 
	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
 

	
 
	while (_network_ip_list[i]!=0) {
 
		bcaddr=_network_ip_list[i];
 
		out_addr.sin_family = AF_INET;
 
		out_addr.sin_port = htons(_network_port);
 
		if (client) { out_addr.sin_port = htons(_network_server_port); } else { out_addr.sin_port = htons(_network_client_port); };
 
		bcptr = (byte *) &bcaddr;
 
		bcptr[3]=255;
 
		out_addr.sin_addr.s_addr = bcaddr;
 
		res=sendto(_udpsocket,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
 
		res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
 
		if (res==-1) error("udp: broadcast error: %i",GET_LAST_ERROR());
 
		i++;
 
	}
 
	
 
}
 

	
 
void NetworkUDPSend(struct sockaddr_in recv,struct UDPPacket packet) {
 
	sendto(_udpsocket,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &recv,sizeof(recv));
 
void NetworkUDPSend(bool client, struct sockaddr_in recv,struct UDPPacket packet) {
 

	
 
	SOCKET udp;
 
	if (client) udp=_udp_client_socket; else udp=_udp_server_socket;
 
	
 
	sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &recv,sizeof(recv));
 
}
 

	
 
bool NetworkUDPSearchServer() {
 

	
 
bool NetworkUDPSearchGame(byte ** _network_detected_serverip, unsigned short * _network_detected_serverport) {
 
	struct UDPPacket packet;
 
	int timeout=3000;
 
	DEBUG(misc,0) ("udp: searching server");
 
	_network_detected_serverip = "255.255.255.255";
 
	_network_detected_serverport = 0;
 
	
 
	NetworkGameListClear();
 

	
 
	DEBUG(misc,0) ("[NET][UDP] searching server");
 
	*_network_detected_serverip = "255.255.255.255";
 
	*_network_detected_serverport = 0;
 
	
 
	packet.command_check=packet.command_code=NET_UDPCMD_SERVERSEARCH;
 
	packet.data_len=0;
 
	NetworkUDPBroadCast(packet);
 
	NetworkUDPBroadCast(true, packet);
 
	while (timeout>=0) {
 
		CSleep(100);
 
		timeout-=100;
 
		NetworkUDPReceive();
 
		if (_network_detected_serverport>0) {
 
			timeout=-1;
 
			DEBUG(misc,0) ("udp: server found on %s", _network_detected_serverip);
 
			}
 
	    NetworkUDPReceive(true);
 

	
 
		if (_network_game_count>0) {
 
			NetworkGameList * item;
 
			item = (NetworkGameList *) NetworkGameListItem(0);
 
			*_network_detected_serverip=inet_ntoa(*(struct in_addr *) &item->ip);
 
			*_network_detected_serverport=item->port;
 
 			timeout=-1;
 
 			DEBUG(misc,0) ("[NET][UDP] server found on %s", *_network_detected_serverip);
 
 			}
 
	
 
		}
 

	
 
	return (_network_detected_serverport>0);
 
		
 
}
 

	
 

	
 
// *************************** //
 
// * New Network Core System * //
 
// *************************** //
 

	
 
void NetworkIPListInit() {
 
	struct hostent* he = NULL;
 
	char hostname[250];
 
	uint32 bcaddr;
 
	int i=0;
 
		
 
	gethostname(hostname,250);
 
	DEBUG(misc,2) ("[NET][IP] init for host %s", hostname);
 
	he=gethostbyname((char *) hostname);
 
 
	if (he == NULL) {
 
		he = gethostbyname("localhost");
 
		}
 
	
 
	if (he == NULL) {
 
		bcaddr = inet_addr("127.0.0.1");
 
		he = gethostbyaddr(inet_ntoa(*(struct in_addr *) &bcaddr), sizeof(bcaddr), AF_INET);
 
		}
 

	
 
	if (he == NULL) {
 
		DEBUG(misc, 2) ("[NET][IP] cannot resolve %s", hostname);
 
	} else {
 
		while(he->h_addr_list[i]) { 
 
			bcaddr = inet_addr(inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
 
			_network_ip_list[i]=bcaddr;
 
			DEBUG(misc,2) ("[NET][IP] add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i]));
 
			i++;
 
		}
 

	
 
	}
 
	_network_ip_list[i]=0;
 
	
 
}
 

	
 
/* *************************************************** */
 

	
 
void NetworkCoreInit() {
 

	
 
DEBUG(misc,3) ("[NET][Core] init()");
 
_network_available=true;
 

	
 
// [win32] winsock startup
 

	
 
#if defined(WIN32)
 
{
 
	WSADATA wsa;
 
	DEBUG(misc,3) ("[NET][Core] using windows socket library");
 
	if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
 
		DEBUG(misc,3) ("[NET][Core] error: WSAStartup failed");
 
		_network_available=false;
 
		}
 
}
 
#else 
 

	
 
// [morphos/amigaos] bsd-socket startup
 

	
 
#if defined(__MORPHOS__) || defined(__AMIGA__)
 
{
 
	DEBUG(misc,3) ("[NET][Core] using bsd socket library");
 
	if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) {
 
		DEBUG(misc,3) ("[NET][Core] Couldn't open bsdsocket.library version 4.");
 
		_network_available=false;
 
		}
 
}
 
#else
 

	
 
// [linux/macos] unix-socket startup
 

	
 
	DEBUG(misc,3) ("[NET][Core] using unix socket library");
 

	
 
#endif
 

	
 
#endif
 

	
 

	
 
if (_network_available) {
 
	DEBUG(misc,3) ("[NET][Core] OK: multiplayer available");
 
	// initiate network ip list
 
	NetworkIPListInit();
 
	} else {
 
	DEBUG(misc,3) ("[NET][Core] FAILED: multiplayer not available");
 
	}
 
}
 

	
 
/* *************************************************** */
 

	
 
void NetworkCoreShutdown() {
 

	
 
DEBUG(misc,3) ("[NET][Core] shutdown()");
 

	
 
#if defined(__MORPHOS__) || defined(__AMIGA__)
 
{	
 
	if (SocketBase) {
 
		CloseLibrary(SocketBase);
 
	}
 
}
 
#endif
 

	
 

	
 
#if defined(WIN32)
 
{
 
	WSACleanup();
 
}
 
#endif
 

	
 
}
 

	
 
/* *************************************************** */
 

	
 
bool NetworkCoreConnectGame(byte* b, unsigned short port)
 
{
 
	if (!_network_available) return false;
 

	
 
	if (strcmp((char *) b,"auto")==0) {
 
		// do autodetect
 
		NetworkUDPSearchGame(&b, &port);
 
		}
 

	
 
	if (port==0) {
 
		// autodetection failed
 
		if (_networking_override) NetworkLobbyShutdown();
 
		ShowErrorMessage(-1, STR_NETWORK_ERR_NOSERVER, 0, 0);
 
		return false;
 
		}
 
	NetworkInitialize();
 
	_networking = NetworkConnect(b, port);
 
	if (_networking) {
 
		NetworkLobbyShutdown();
 
		} else {
 
		if (_networking_override) NetworkLobbyShutdown();
 
		ShowErrorMessage(-1, STR_NETWORK_ERR_NOCONNECTION,0,0);
 
		}
 
	return _networking;
 
}
 

	
 
/* *************************************************** */
 

	
 
bool NetworkCoreStartGame()
 
{
 
	if (!_network_available) return false;
 
	NetworkLobbyShutdown();
 
	NetworkInitialize();
 
	NetworkListen();
 
	NetworkUDPListen(false);
 
	_networking_server = true;
 
	_networking = true;
 
	NetworkGameFillDefaults(); // clears the network game info
 
	_network_game.players_on++; // the serverplayer is online
 
	return true;
 
}
 

	
 
/* *************************************************** */
 

	
 
void NetworkCoreDisconnect()
 
{
 
	/* terminate server */
 
	if (_networking_server) {
 
		NetworkUDPClose(false);
 
		NetworkClose(false);
 
		} 
 

	
 
	/* terminate client connection */
 
	else if (_networking) {
 
		NetworkClose(true);
 
		}
 
	
 
	_networking_server = false;	
 
	_networking = false;
 
	NetworkShutdown();
 
}
 

	
 
/* *************************************************** */
 

	
 
void NetworkCoreLoop(bool incomming) {
 

	
 

	
 
if (incomming) {
 

	
 
	// incomming
 

	
 
	if ( _udp_client_socket != INVALID_SOCKET ) NetworkUDPReceive(true);
 
	if ( _udp_server_socket != INVALID_SOCKET ) NetworkUDPReceive(false);
 

	
 
	if (_networking) {
 
		NetworkReceive();
 
		NetworkProcessCommands(); // to check if we got any new commands belonging to the current frame before we increase it.
 
		}
 

	
 
	} else {
 

	
 
	// outgoing
 

	
 
	if (_networking) {
 
		NetworkSend();
 
		}
 

	
 
	}
 

	
 
}
 

	
 
void NetworkLobbyInit() {
 
	DEBUG(misc,3) ("[NET][Lobby] init()");
 
	NetworkUDPListen(true);
 
}
 

	
 
void NetworkLobbyShutdown() {
 
	DEBUG(misc,3) ("[NET][Lobby] shutdown()");
 
	NetworkUDPClose(true);
 
}
 

	
 

	
 
// ******************************** //
 
// * Network Game List Extensions * //
 
// ******************************** //
 

	
 
void NetworkGameListClear() {
 
NetworkGameList * item;
 
NetworkGameList * next; 
 

	
 
DEBUG(misc,4) ("[NET][G-List] cleared server list");
 

	
 
item = _network_game_list;
 
while (item != NULL) {
 
	next = (NetworkGameList *) item -> _next;
 
	free (item);
 
	item = next;
 
	}
 
_network_game_list=NULL;
 
_network_game_count=0;
 
}
 

	
 
char * NetworkGameListAdd() {
 
NetworkGameList * item;
 
NetworkGameList * before; 
 

	
 
DEBUG(misc,4) ("[NET][G-List] added server to list");
 

	
 
item = _network_game_list;
 
before = item;
 
while (item != NULL) {
 
	before = item;
 
	item = (NetworkGameList *) item -> _next;
 
	}
 
item = malloc(sizeof(NetworkGameList));
 
item -> _next = NULL;
 
if (before == NULL) {
 
	_network_game_list = item;
 
	} else {
 
	before -> _next = (char *) item;
 
	}
 
_network_game_count++;
 
return (char *) item;
 
}
 

	
 
void NetworkGameListFromLAN() {
 
	struct UDPPacket packet;
 
	DEBUG(misc,2) ("[NET][G-List] searching server over lan");
 
	NetworkGameListClear();
 
	packet.command_check=packet.command_code=NET_UDPCMD_SERVERSEARCH;
 
	packet.data_len=0;
 
	NetworkUDPBroadCast(true,packet);
 
}
 

	
 
void NetworkGameListFromInternet() {
 
	DEBUG(misc,2) ("[NET][G-List] searching servers over internet");
 
	NetworkGameListClear();
 

	
 
	// **TODO** masterserver communication [internet protocol list]
 

	
 
}
 

	
 
char * NetworkGameListItem(uint16 index) {
 
NetworkGameList * item;
 
NetworkGameList * next; 
 
uint16 cnt = 0;
 

	
 
item = _network_game_list;
 

	
 
while ((item != NULL) && (cnt != index)) {
 
	next = (NetworkGameList *) item -> _next;
 
	item = next;
 
	cnt++;
 
	}
 

	
 
return (char *) item;
 
}
 

	
 
// *************************** //
 
// * Network Game Extensions * //
 
// *************************** //
 

	
 
void NetworkGameFillDefaults() {
 
	NetworkGameInfo * game = &_network_game;
 
#if defined(WITH_REV)
 
	extern char _openttd_revision[];
 
#endif
 
	
 
	DEBUG(misc,4) ("[NET][G-Info] setting defaults");
 

	
 
	ttd_strlcpy(game->server_name,"OpenTTD Game",13);
 
	game->game_password[0]='\0';
 
	game->map_name[0]='\0';
 
#if defined(WITH_REV)
 
	ttd_strlcpy(game->server_revision,_openttd_revision,strlen(_openttd_revision));
 
#else
 
	ttd_strlcpy(game->server_revision,"norev000",strlen("norev000"));
 
#endif
 
	game->game_date=0;
 

	
 
	game->map_height=0;
 
	game->map_width=0;
 
	game->map_set=0;
 

	
 
	game->players_max=8;
 
	game->players_on=0;
 
	
 
	game->server_lang=_dynlang.curr;
 
}
 

	
 
void NetworkGameChangeDate(uint16 newdate) {
 
	if (_networking_server) {
 
		_network_game.game_date = newdate;
 
		}
 
}
 

	
 
#else // not ENABLE_NETWORK
 

	
 
// stubs
 
void NetworkInitialize(const char *hostname) {}
 
void NetworkInitialize() {}
 
void NetworkShutdown() {}
 
void NetworkListen(int port) {}
 
void NetworkListen() {}
 
void NetworkConnect(const char *hostname, int port) {}
 
void NetworkReceive() {}
 
void NetworkSend() {}
 
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback) {}
 
void NetworkProcessCommands() {}
 
void NetworkStartSync() {}
 
void NetworkUDPListen(int port) {}
 
void NetworkUDPReceive() {}
 
bool NetworkUDPSearchServer() { return false; }
 
#endif // ENABLE_NETWORK
 
void NetworkCoreInit() { _network_available=false; };
 
void NetworkCoreShutdown() {};
 
void NetworkCoreDisconnect() {};
 
void NetworkCoreLoop(bool incomming) {};
 
bool NetworkCoreConnectGame(byte* b, unsigned short port) {};
 
bool NetworkCoreStartGame() {};
 
void NetworkLobbyShutdown() {};
 
void NetworkLobbyInit() {};
 
void NetworkGameListClear() {};
 
char * NetworkGameListAdd() {return NULL;};
 
void NetworkGameListFromLAN() {};
 
void NetworkGameListFromInternet() {};
 
void NetworkGameFillDefaults() {};
 
char * NetworkGameListItem(uint16 index) {return NULL;};
 
void NetworkGameChangeDate(uint16 newdate) {};
 
}
 

	
 
#endif
network_gui.c
Show inline comments
 
@@ -21,16 +21,6 @@ void ShowQueryString(StringID str, Strin
 
static byte _selected_field;
 
char *direct_ip = NULL;
 

	
 

	
 
void ConnectToServer(byte* b)
 
{
 
	_networking = true;
 
	
 
	NetworkInitialize(b);
 
	DEBUG(misc, 1) ("Connecting to %s %d\n", b, _network_port);
 
	NetworkConnect(b, _network_port);
 
}
 

	
 
static const StringID _connection_types_dropdown[] = {
 
	STR_NETWORK_LAN,
 
	STR_NETWORK_INTERNET,
 
@@ -65,7 +55,15 @@ static void NetworkGameWindowWndProc(Win
 
		case 0:  // close X
 
		case 15: // cancel button
 
			DeleteWindowById(WC_NETWORK_WINDOW, 0);
 
			NetworkLobbyShutdown();
 
			break;
 
		case 3: // find server automaticaly
 
			{
 
			byte *b = "auto";
 
			NetworkCoreConnectGame(b,_network_server_port);
 
			}
 
			break;
 

	
 
		case 4: // connect via direct ip
 
			{
 
				StringID str;
 
@@ -111,7 +109,7 @@ static void NetworkGameWindowWndProc(Win
 
		byte *b = e->edittext.str;
 
		if (*b == 0)
 
			return;
 
		ConnectToServer(b);
 
		NetworkCoreConnectGame(b,_network_server_port);
 
	} break;
 

	
 
	}
 
@@ -159,6 +157,8 @@ void ShowNetworkGameWindow()
 
{
 
	Window *w;
 
	DeleteWindowById(WC_NETWORK_WINDOW, 0);
 

	
 
	NetworkLobbyInit();
 
	
 
	w = AllocateWindowDesc(&_network_game_window_desc);
 
	strcpy(_edit_str_buf, "Your name");
 
@@ -168,24 +168,9 @@ void ShowNetworkGameWindow()
 
	WP(w,querystr_d).maxlen = MAX_QUERYSTR_LEN;
 
	WP(w,querystr_d).maxwidth = 240;
 
	WP(w,querystr_d).buf = _edit_str_buf;
 
	
 
	
 
	ShowErrorMessage(-1, TEMP_STRING_NO_NETWORK, 0, 0);
 
	// ShowErrorMessage(-1, TEMP_STRING_NO_NETWORK, 0, 0);
 
}
 

	
 

	
 
void StartServer()
 
{
 
	_networking = true;
 
	NetworkInitialize(NULL);
 
	DEBUG(misc, 1) ("Listening on port %d\n", _network_port);
 
	NetworkListen(_network_port);
 
	_networking_server = true;
 
	DoCommandP(0, 0, 0, NULL, CMD_START_NEW_GAME);
 
}
 

	
 

	
 

	
 
static const StringID _players_dropdown[] = {
 
	STR_NETWORK_2_PLAYERS,
 
	STR_NETWORK_3_PLAYERS,
 
@@ -232,8 +217,9 @@ static void NetworkStartServerWindowWndP
 
			ShowDropDownMenu(w, _players_dropdown, _opt_mod_ptr->currency, e->click.widget, 0);
 
			return;
 
		case 9: // start game
 
			StartServer();
 
			NetworkCoreStartGame();
 
			ShowNetworkLobbyWindow();
 
			DoCommandP(0, 0, 0, NULL, CMD_START_NEW_GAME);
 
			break;
 
		}
 

	
 
@@ -308,10 +294,6 @@ static void ShowNetworkStartServerWindow
 
	WP(w,querystr_d).buf = _edit_str_buf;
 
}
 

	
 

	
 

	
 

	
 

	
 
static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
 
{
 
	switch(e->event) {
settings.c
Show inline comments
 
@@ -760,7 +760,8 @@ static const SettingDesc misc_settings[]
 
};
 

	
 
static const SettingDesc network_settings[] = {
 
	{"port", SDT_UINT | SDT_NOSAVE, (void*)3979, &_network_port},
 
	{"port", SDT_UINT | SDT_NOSAVE, (void*)3978, &_network_client_port},
 
	{"server_port", SDT_UINT | SDT_NOSAVE, (void*)3979, &_network_server_port},
 
	{"sync_freq", SDT_UINT | SDT_NOSAVE, (void*)4, &_network_sync_freq},
 
	{"ahead_frames", SDT_UINT | SDT_NOSAVE, (void*)5, &_network_ahead_frames},
 
	{NULL}
ttd.c
Show inline comments
 
@@ -484,6 +484,7 @@ int ttd_main(int argc, char* argv[])
 
	uint startdate = -1;
 
	_ignore_wrong_grf = false;
 
	musicdriver[0] = sounddriver[0] = videodriver[0] = 0;
 
	_networking_override=false;
 

	
 
	_game_mode = GM_MENU;
 
	_switch_mode = SM_MENU;
 
@@ -496,6 +497,7 @@ int ttd_main(int argc, char* argv[])
 
		case 'v': ttd_strlcpy(videodriver, mgo.opt, sizeof(videodriver)); break;
 
		case 'n': {
 
				network = 1; 
 
				_networking_override=true;
 
				if (mgo.opt) {
 
					network_conn = mgo.opt; 
 
					network++;
 
@@ -551,14 +553,17 @@ int ttd_main(int argc, char* argv[])
 
	if (resolution[0]) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; }
 
	if (startdate != -1) _patches.starting_date = startdate;
 

	
 
	// initialize network-core
 
	NetworkCoreInit();
 

	
 
	// enumerate language files
 
	InitializeLanguagePacks();
 

	
 
	// initialize screenshot formats
 
	InitializeScreenshotFormats();
 

	
 
  // initialize airport state machines
 
  InitializeAirports();
 
	// initialize airport state machines
 
	InitializeAirports();
 
	
 
	// Sample catalogue
 
	DEBUG(misc, 1) ("Loading sound effects...");
 
@@ -583,25 +588,21 @@ int ttd_main(int argc, char* argv[])
 
	if (_opt_mod_ptr->diff_level == 9)
 
		SetDifficultyLevel(0, _opt_mod_ptr);
 

	
 
	if (network) {
 
		_networking = true;
 
		
 
		NetworkInitialize(network_conn);
 
		if (network==1) {
 
			DEBUG(misc, 1) ("Listening on port %d\n", _network_port);
 
			NetworkListen(_network_port);
 
			_networking_server = true;
 
		} else {
 
			DEBUG(misc, 1) ("Connecting to %s %d\n", network_conn, _network_port);
 
			NetworkConnect(network_conn, _network_port);
 
	if ((network) && (_network_available)) {
 
		NetworkLobbyInit();
 
		if (network_conn!=NULL) {
 
			NetworkCoreConnectGame(network_conn,_network_server_port);
 
			} else {
 
			NetworkCoreConnectGame("auto",_network_server_port);
 
			}
 
		}
 
	}
 

	
 
	while (_video_driver->main_loop() == ML_SWITCHDRIVER) {}
 

	
 
	if (network) {
 
		NetworkShutdown();
 
	}
 
	if (_network_available) {
 
		// shutdown network-core
 
		NetworkCoreShutdown();
 
		}
 

	
 
	_video_driver->stop();
 
	_music_driver->stop();
 
@@ -609,8 +610,8 @@ int ttd_main(int argc, char* argv[])
 

	
 
	SaveToConfig();
 

	
 
  // uninitialize airport state machines
 
  UnInitializeAirports();
 
	// uninitialize airport state machines
 
	UnInitializeAirports();
 

	
 
	return 0;
 
}
 
@@ -774,14 +775,14 @@ static void SwitchMode(int new_mode)
 
		break;
 

	
 
	case SM_NEWGAME:
 
		if (_networking) { NetworkStartSync(); } // UGLY HACK HACK HACK
 
		if (_networking) { NetworkStartSync(true); } // UGLY HACK HACK HACK
 
		MakeNewGame();
 
		break;
 

	
 
normal_load:
 
	case SM_LOAD: { // Load game
 

	
 
		if (_networking) { NetworkStartSync(); } // UGLY HACK HACK HACK
 
		if (_networking) { NetworkStartSync(true); } // UGLY HACK HACK HACK
 

	
 
		_error_message = INVALID_STRING_ID;
 
		if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) {
 
@@ -820,6 +821,10 @@ normal_load:
 

	
 

	
 
	case SM_MENU: // Switch to game menu
 
		
 
		if ((_networking) && (!_networking_override)) NetworkCoreDisconnect();
 
		_networking_override=false;
 

	
 
		LoadIntroGame();
 
		break;
 

	
 
@@ -951,10 +956,8 @@ void GameLoop()
 
	_timer_counter+=8;
 
	CursorTick();
 

	
 
	if (_networking) {
 
		NetworkReceive();
 
		NetworkProcessCommands(); // to check if we got any new commands belonging to the current frame before we increase it.
 
	}
 
	// incomming packets
 
	NetworkCoreLoop(true);
 

	
 
	if (_networking_sync) {
 
		// make sure client's time is synched to the server by running frames quickly up to where the server is.
 
@@ -983,8 +986,8 @@ void GameLoop()
 
	MouseLoop();
 

	
 
	// send outgoing packets.
 
	if (_networking)
 
		NetworkSend();
 
	NetworkCoreLoop(false);
 

	
 

	
 
	if (_game_mode != GM_MENU)
 
		MusicLoop();
variables.h
Show inline comments
 
@@ -218,14 +218,16 @@ VARDEF int32 _frame_counter_max; // for 
 
VARDEF int32 _frame_counter_srv; // for networking, this is the last known framecounter of the server. it is always less than frame_counter_max.
 

	
 
// networking settings
 
VARDEF uint _network_port;
 
VARDEF bool _network_available;  // is network mode available?
 
VARDEF uint32 _network_ip_list[10]; // Network IPs
 
VARDEF uint16 _network_game_count;
 

	
 
VARDEF uint _network_client_port;
 
VARDEF uint _network_server_port;
 

	
 
VARDEF uint _network_sync_freq;
 
VARDEF uint _network_ahead_frames;
 

	
 
VARDEF uint32 _network_ip_list[10]; // Network IPs
 
VARDEF char * _network_detected_serverip; // UDP Broadcast detected Server
 
VARDEF uint32 _network_detected_serverport; // UDP Broadcast detected server-port
 

	
 
VARDEF uint32 _sync_seed_1, _sync_seed_2;
 

	
 
VARDEF bool _is_ai_player; // current player is an AI player? - Can be removed if new AI is done
 
@@ -283,6 +285,8 @@ VARDEF SmallFiosItem _file_to_saveload;
 
VARDEF byte _make_screenshot;
 

	
 
VARDEF bool _networking;
 
VARDEF bool _networking_override; // dont shutdown network core when the GameMenu appears.
 

	
 
VARDEF bool _networking_sync; // if we use network mode and the games must stay in sync.
 
VARDEF bool _networking_server;
 
VARDEF bool _networking_queuing; // queueing only?
0 comments (0 inline, 0 general)