(svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
authorrubidium
Tue, 02 Jan 2007 17:34:03 +0000
changeset 5720 cc0ceeafaa55
parent 5719 76441d929243
child 5721 25220a9b7c27
(svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
Makefile
ai/ai.c
ai/ai.h
command.c
console.c
console_cmds.c
date.c
date.h
economy.c
genworld.c
genworld_gui.c
intro_gui.c
main_gui.c
misc.c
misc_cmd.c
misc_gui.c
network.c
network.h
network/core/config.h
network/core/game.h
network/core/os_abstraction.h
network/core/packet.c
network/core/packet.h
network/core/tcp.c
network/core/tcp.h
network/core/udp.c
network/core/udp.h
network/network.c
network/network.h
network/network_client.c
network/network_client.h
network/network_data.c
network/network_data.h
network/network_gamelist.c
network/network_gamelist.h
network/network_gui.c
network/network_gui.h
network/network_server.c
network/network_server.h
network/network_udp.c
network/network_udp.h
network_client.c
network_client.h
network_core.h
network_data.c
network_data.h
network_gamelist.c
network_gamelist.h
network_gui.c
network_gui.h
network_server.c
network_server.h
network_udp.c
network_udp.h
newgrf_config.c
npf.c
oldloader.c
openttd.c
openttd.vcproj
openttd_vs80.vcproj
player_gui.c
players.c
saveload.c
settings.c
settings_gui.c
town_gui.c
vehicle.c
video/cocoa_v.m
video/dedicated_v.c
video/sdl_v.c
video/win32_v.c
--- a/Makefile	Tue Jan 02 12:52:29 2007 +0000
+++ b/Makefile	Tue Jan 02 17:34:03 2007 +0000
@@ -732,13 +732,16 @@
 SRCS += music.c
 SRCS += music_gui.c
 SRCS += namegen.c
-SRCS += network.c
-SRCS += network_client.c
-SRCS += network_data.c
-SRCS += network_gamelist.c
-SRCS += network_gui.c
-SRCS += network_server.c
-SRCS += network_udp.c
+SRCS += network/core/packet.c
+SRCS += network/core/tcp.c
+SRCS += network/core/udp.c
+SRCS += network/network.c
+SRCS += network/network_client.c
+SRCS += network/network_data.c
+SRCS += network/network_gamelist.c
+SRCS += network/network_gui.c
+SRCS += network/network_server.c
+SRCS += network/network_udp.c
 SRCS += newgrf.c
 SRCS += newgrf_cargo.c
 SRCS += newgrf_config.c
--- a/ai/ai.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/ai/ai.c	Tue Jan 02 17:34:03 2007 +0000
@@ -4,7 +4,7 @@
 #include "../openttd.h"
 #include "../variables.h"
 #include "../command.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "ai.h"
 #include "default/default.h"
 
--- a/ai/ai.h	Tue Jan 02 12:52:29 2007 +0000
+++ b/ai/ai.h	Tue Jan 02 17:34:03 2007 +0000
@@ -2,7 +2,7 @@
 #define AI_H
 
 #include "../functions.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../player.h"
 #include "../command.h"
 
--- a/command.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/command.c	Tue Jan 02 17:34:03 2007 +0000
@@ -8,7 +8,7 @@
 #include "gui.h"
 #include "command.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "genworld.h"
 
--- a/console.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/console.c	Tue Jan 02 17:34:03 2007 +0000
@@ -13,9 +13,9 @@
 #include <stdarg.h>
 #include <string.h>
 #include "console.h"
-#include "network.h"
-#include "network_data.h"
-#include "network_server.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
 
 #define ICON_BUFFER 79
 #define ICON_HISTORY_SIZE 20
--- a/console_cmds.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/console_cmds.c	Tue Jan 02 17:34:03 2007 +0000
@@ -9,10 +9,10 @@
 #include "saveload.h"
 #include "string.h"
 #include "variables.h"
-#include "network_data.h"
-#include "network_client.h"
-#include "network_server.h"
-#include "network_udp.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_udp.h"
 #include "command.h"
 #include "settings.h"
 #include "fios.h"
@@ -22,7 +22,7 @@
 #include "screenshot.h"
 #include "genworld.h"
 #include "date.h"
-#include "network.h"
+#include "network/network.h"
 
 // ** scriptfile handling ** //
 static FILE *_script_file;
--- a/date.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/date.c	Tue Jan 02 17:34:03 2007 +0000
@@ -6,9 +6,9 @@
 #include "variables.h"
 #include "macros.h"
 #include "vehicle.h"
-#include "network.h"
-#include "network_data.h"
-#include "network_server.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
 #include "functions.h"
 #include "currency.h"
 
--- a/date.h	Tue Jan 02 12:52:29 2007 +0000
+++ b/date.h	Tue Jan 02 17:34:03 2007 +0000
@@ -3,6 +3,8 @@
 #ifndef DATE_H
 #define DATE_H
 
+#include "openttd.h"
+
 /**
  * 1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885. On
  *                    an overflow the new day begun and 65535 / 885 = 74.
--- a/economy.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/economy.c	Tue Jan 02 17:34:03 2007 +0000
@@ -19,10 +19,10 @@
 #include "economy.h"
 #include "industry.h"
 #include "town.h"
-#include "network.h"
+#include "network/network.h"
 #include "sound.h"
 #include "engine.h"
-#include "network_data.h"
+#include "network/network_data.h"
 #include "variables.h"
 #include "vehicle_gui.h"
 #include "ai/ai.h"
--- a/genworld.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/genworld.c	Tue Jan 02 17:34:03 2007 +0000
@@ -11,7 +11,7 @@
 #include "gfx.h"
 #include "gfxinit.h"
 #include "gui.h"
-#include "network.h"
+#include "network/network.h"
 #include "debug.h"
 #include "settings.h"
 #include "heightmap.h"
--- a/genworld_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/genworld_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -19,7 +19,7 @@
 #include "settings.h"
 #include "debug.h"
 #include "genworld.h"
-#include "network.h"
+#include "network/network.h"
 #include "thread.h"
 #include "date.h"
 #include "newgrf_config.h"
--- a/intro_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/intro_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -9,12 +9,12 @@
 #include "gui.h"
 #include "gfx.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "settings.h"
 #include "heightmap.h"
 #include "genworld.h"
-#include "network_gui.h"
+#include "network/network_gui.h"
 #include "newgrf.h"
 
 static const Widget _select_game_widgets[] = {
--- a/main_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/main_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -23,7 +23,7 @@
 #include "vehicle.h"
 #include "console.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "signs.h"
 #include "waypoint.h"
 #include "variables.h"
@@ -37,10 +37,10 @@
 #include "vehicle_gui.h"
 #include "newgrf_config.h"
 
-#include "network_data.h"
-#include "network_client.h"
-#include "network_server.h"
-#include "network_gui.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_gui.h"
 #include "industry.h"
 
 static int _rename_id = 1;
--- a/misc.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/misc.c	Tue Jan 02 17:34:03 2007 +0000
@@ -24,7 +24,7 @@
 #ifndef MERSENNE_TWISTER
 
 #ifdef RANDOM_DEBUG
-#include "network_data.h"
+#include "network/network_data.h"
 uint32 DoRandom(int line, const char *file)
 #else // RANDOM_DEBUG
 uint32 Random(void)
--- a/misc_cmd.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/misc_cmd.c	Tue Jan 02 17:34:03 2007 +0000
@@ -11,7 +11,7 @@
 #include "window.h"
 #include "gui.h"
 #include "economy.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "livery.h"
 
--- a/misc_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/misc_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -22,7 +22,7 @@
 #include "player.h"
 #include "town.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "string.h"
 #include "variables.h"
 #include "vehicle.h"
--- a/network.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1448 +0,0 @@
-/* $Id$ */
-
-#include "stdafx.h"
-#include "network_data.h"
-
-#if defined(WITH_REV)
-	extern const char _openttd_revision[];
-#elif defined(WITH_REV_HACK)
-	#define WITH_REV
-	const char _openttd_revision[] = WITH_REV_HACK;
-#else
-	const char _openttd_revision[] = NOREV_STRING;
-#endif
-
-
-#ifdef ENABLE_NETWORK
-
-#include "openttd.h"
-#include "debug.h"
-#include "functions.h"
-#include "string.h"
-#include "strings.h"
-#include "map.h"
-#include "command.h"
-#include "variables.h"
-#include "date.h"
-#include "table/strings.h"
-#include "network_client.h"
-#include "network_server.h"
-#include "network_udp.h"
-#include "network_gamelist.h"
-#include "network_gui.h"
-#include "console.h" /* IConsoleCmdExec */
-#include <stdarg.h> /* va_list */
-#include "md5.h"
-
-#ifdef __MORPHOS__
-// the library base is required here
-struct Library *SocketBase = NULL;
-#endif
-
-// The listen socket for the server
-static SOCKET _listensocket;
-
-// The amount of clients connected
-static byte _network_clients_connected = 0;
-// The index counter for new clients (is never decreased)
-static uint16 _network_client_index = NETWORK_SERVER_INDEX + 1;
-
-/* Some externs / forwards */
-extern void StateGameLoop(void);
-
-// Function that looks up the CI for a given client-index
-NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index)
-{
-	NetworkClientInfo *ci;
-
-	for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
-		if (ci->client_index == client_index) return ci;
-	}
-
-	return NULL;
-}
-
-/** Return the CI for a given IP
- * @param ip IP of the client we are looking for. This must be in string-format
- * @return return a pointer to the corresponding NetworkClientInfo struct or NULL on failure */
-NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip)
-{
-	NetworkClientInfo *ci;
-	uint32 ip_number = inet_addr(ip);
-
-	for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
-		if (ci->client_ip == ip_number) return ci;
-	}
-
-	return NULL;
-}
-
-// Function that looks up the CS for a given client-index
-NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index)
-{
-	NetworkClientState *cs;
-
-	for (cs = _clients; cs != &_clients[MAX_CLIENT_INFO]; cs++) {
-		if (cs->index == client_index) return cs;
-	}
-
-	return NULL;
-}
-
-// NetworkGetClientName is a server-safe function to get the name of the client
-//  if the user did not send it yet, Client #<no> is used.
-void NetworkGetClientName(char *client_name, size_t size, const NetworkClientState *cs)
-{
-	const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
-
-	if (ci->client_name[0] == '\0') {
-		snprintf(client_name, size, "Client #%4d", cs->index);
-	} else {
-		ttd_strlcpy(client_name, ci->client_name, size);
-	}
-}
-
-byte NetworkSpectatorCount(void)
-{
-	const NetworkClientState *cs;
-	byte count = 0;
-
-	FOR_ALL_CLIENTS(cs) {
-		if (DEREF_CLIENT_INFO(cs)->client_playas == PLAYER_SPECTATOR) count++;
-	}
-
-	return count;
-}
-
-// This puts a text-message to the console, or in the future, the chat-box,
-//  (to keep it all a bit more general)
-// If 'self_send' is true, this is the client who is sending the message
-void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...)
-{
-	char buf[1024];
-	va_list va;
-	const int duration = 10; // Game days the messages stay visible
-	char message[1024];
-	char temp[1024];
-
-	va_start(va, str);
-	vsnprintf(buf, lengthof(buf), str, va);
-	va_end(va);
-
-	switch (action) {
-		case NETWORK_ACTION_SERVER_MESSAGE:
-			color = 1;
-			snprintf(message, sizeof(message), "*** %s", buf);
-			break;
-		case NETWORK_ACTION_JOIN:
-			color = 1;
-			GetString(temp, STR_NETWORK_CLIENT_JOINED, lastof(temp));
-			snprintf(message, sizeof(message), "*** %s %s", name, temp);
-			break;
-		case NETWORK_ACTION_LEAVE:
-			color = 1;
-			GetString(temp, STR_NETWORK_ERR_LEFT, lastof(temp));
-			snprintf(message, sizeof(message), "*** %s %s (%s)", name, temp, buf);
-			break;
-		case NETWORK_ACTION_GIVE_MONEY:
-			if (self_send) {
-				SetDParamStr(0, name);
-				SetDParam(1, atoi(buf));
-				GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY, lastof(temp));
-				snprintf(message, sizeof(message), "*** %s", temp);
-			} else {
-				SetDParam(0, atoi(buf));
-				GetString(temp, STR_NETWORK_GIVE_MONEY, lastof(temp));
-				snprintf(message, sizeof(message), "*** %s %s", name, temp);
-			}
-			break;
-		case NETWORK_ACTION_NAME_CHANGE:
-			GetString(temp, STR_NETWORK_NAME_CHANGE, lastof(temp));
-			snprintf(message, sizeof(message), "*** %s %s %s", name, temp, buf);
-			break;
-		case NETWORK_ACTION_CHAT_COMPANY:
-			SetDParamStr(0, name);
-			SetDParamStr(1, buf);
-			GetString(temp, self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY, lastof(temp));
-			ttd_strlcpy(message, temp, sizeof(message));
-			break;
-		case NETWORK_ACTION_CHAT_CLIENT:
-			SetDParamStr(0, name);
-			SetDParamStr(1, buf);
-			GetString(temp, self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT, lastof(temp));
-			ttd_strlcpy(message, temp, sizeof(message));
-			break;
-		default:
-			SetDParamStr(0, name);
-			SetDParamStr(1, buf);
-			GetString(temp, STR_NETWORK_CHAT_ALL, lastof(temp));
-			ttd_strlcpy(message, temp, sizeof(message));
-			break;
-	}
-
-	IConsolePrintF(color, "%s", message);
-	AddTextMessage(color, duration, "%s", message);
-}
-
-// Calculate the frame-lag of a client
-uint NetworkCalculateLag(const NetworkClientState *cs)
-{
-	int lag = cs->last_frame_server - cs->last_frame;
-	// This client has missed his ACK packet after 1 DAY_TICKS..
-	//  so we increase his lag for every frame that passes!
-	// The packet can be out by a max of _net_frame_freq
-	if (cs->last_frame_server + DAY_TICKS + _network_frame_freq < _frame_counter)
-		lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _network_frame_freq);
-
-	return lag;
-}
-
-
-// There was a non-recoverable error, drop back to the main menu with a nice
-//  error
-static void NetworkError(StringID error_string)
-{
-	_switch_mode = SM_MENU;
-	_switch_mode_errorstr = error_string;
-}
-
-static void ClientStartError(const char *error)
-{
-	DEBUG(net, 0, "[client] could not start network: %s",error);
-	NetworkError(STR_NETWORK_ERR_CLIENT_START);
-}
-
-static void ServerStartError(const char *error)
-{
-	DEBUG(net, 0, "[server] could not start network: %s",error);
-	NetworkError(STR_NETWORK_ERR_SERVER_START);
-}
-
-static void NetworkClientError(NetworkRecvStatus res, NetworkClientState* cs)
-{
-	// First, send a CLIENT_ERROR to the server, so he knows we are
-	//  disconnection (and why!)
-	NetworkErrorCode errorno;
-
-	// We just want to close the connection..
-	if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
-		cs->has_quit = true;
-		NetworkCloseClient(cs);
-		_networking = false;
-
-		DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-		return;
-	}
-
-	switch (res) {
-		case NETWORK_RECV_STATUS_DESYNC:   errorno = NETWORK_ERROR_DESYNC; break;
-		case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
-		default:                           errorno = NETWORK_ERROR_GENERAL; break;
-	}
-	// This means we fucked up and the server closed the connection
-	if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
-			res != NETWORK_RECV_STATUS_SERVER_BANNED) {
-		SEND_COMMAND(PACKET_CLIENT_ERROR)(errorno);
-
-		// Dequeue all commands before closing the socket
-		NetworkSend_Packets(DEREF_CLIENT(0));
-	}
-
-	_switch_mode = SM_MENU;
-	NetworkCloseClient(cs);
-	_networking = false;
-}
-
-/** Retrieve a string representation of an internal error number
- * @param buf buffer where the error message will be stored
- * @param err NetworkErrorCode
- * @return returns a pointer to the error message (buf) */
-char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last)
-{
-	/* List of possible network errors, used by
-	 * PACKET_SERVER_ERROR and PACKET_CLIENT_ERROR */
-	static const StringID network_error_strings[] = {
-		STR_NETWORK_ERR_CLIENT_GENERAL,
-		STR_NETWORK_ERR_CLIENT_DESYNC,
-		STR_NETWORK_ERR_CLIENT_SAVEGAME,
-		STR_NETWORK_ERR_CLIENT_CONNECTION_LOST,
-		STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR,
-		STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED,
-		STR_NETWORK_ERR_CLIENT_NOT_EXPECTED,
-		STR_NETWORK_ERR_CLIENT_WRONG_REVISION,
-		STR_NETWORK_ERR_CLIENT_NAME_IN_USE,
-		STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD,
-		STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH,
-		STR_NETWORK_ERR_CLIENT_KICKED,
-		STR_NETWORK_ERR_CLIENT_CHEATER,
-		STR_NETWORK_ERR_CLIENT_SERVER_FULL
-	};
-
-	if (err >= lengthof(network_error_strings)) err = 0;
-
-	return GetString(buf, network_error_strings[err], last);
-}
-
-/* Count the number of active clients connected */
-static uint NetworkCountPlayers(void)
-{
-	const NetworkClientState *cs;
-	uint count = 0;
-
-	FOR_ALL_CLIENTS(cs) {
-		const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
-		if (IsValidPlayer(ci->client_playas)) count++;
-	}
-
-	return count;
-}
-
-static bool _min_players_paused = false;
-
-/* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
-void CheckMinPlayers(void)
-{
-	if (!_network_dedicated) return;
-
-	if (NetworkCountPlayers() < _network_min_players) {
-		if (_min_players_paused) return;
-
-		_min_players_paused = true;
-		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
-		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX);
-	} else {
-		if (!_min_players_paused) return;
-
-		_min_players_paused = false;
-		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
-		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX);
-	}
-}
-
-// Find all IP-aliases for this host
-static void NetworkFindIPs(void)
-{
-	int i;
-
-#if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
-	/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
-	int _netstat(int fd, char **output, int verbose);
-
-	int seek_past_header(char **pos, const char *header) {
-		char *new_pos = strstr(*pos, header);
-		if (new_pos == 0) {
-			return B_ERROR;
-		}
-		*pos += strlen(header) + new_pos - *pos + 1;
-		return B_OK;
-	}
-
-	int output_length;
-	char *output_pointer = NULL;
-	char **output;
-	int sock = socket(AF_INET, SOCK_DGRAM, 0);
-	i = 0;
-
-	// If something fails, make sure the list is empty
-	_broadcast_list[0] = 0;
-
-	if (sock < 0) {
-		DEBUG(net, 0, "[core] error creating socket");
-		return;
-	}
-
-	output_length = _netstat(sock, &output_pointer, 1);
-	if (output_length < 0) {
-		DEBUG(net, 0, "[core] error running _netstat");
-		return;
-	}
-
-	output = &output_pointer;
-	if (seek_past_header(output, "IP Interfaces:") == B_OK) {
-		for (;;) {
-			uint32 n, fields, read;
-			uint8 i1, i2, i3, i4, j1, j2, j3, j4;
-			struct in_addr inaddr;
-			uint32 ip;
-			uint32 netmask;
-
-			fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
-												&n, &i1,&i2,&i3,&i4, &j1,&j2,&j3,&j4, &read);
-			read += 1;
-			if (fields != 9) {
-				break;
-			}
-
-			ip      = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
-			netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
-
-			if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
-				inaddr.s_addr = htonl(ip | ~netmask);
-				_broadcast_list[i] = inaddr.s_addr;
-				i++;
-			}
-			if (read < 0) {
-				break;
-			}
-			*output += read;
-		}
-		/* XXX - Using either one of these crashes openttd heavily? - wber */
-		/*free(output_pointer);*/
-		/*free(output);*/
-		closesocket(sock);
-	}
-#elif defined(HAVE_GETIFADDRS)
-	struct ifaddrs *ifap, *ifa;
-
-	// If something fails, make sure the list is empty
-	_broadcast_list[0] = 0;
-
-	if (getifaddrs(&ifap) != 0)
-		return;
-
-	i = 0;
-	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-		if (!(ifa->ifa_flags & IFF_BROADCAST)) continue;
-		if (ifa->ifa_broadaddr == NULL) continue;
-		if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
-		_broadcast_list[i] = ((struct sockaddr_in*)ifa->ifa_broadaddr)->sin_addr.s_addr;
-		i++;
-	}
-	freeifaddrs(ifap);
-
-#else /* not HAVE_GETIFADDRS */
-	SOCKET sock;
-#ifdef WIN32
-	DWORD len = 0;
-	INTERFACE_INFO ifo[MAX_INTERFACES];
-	uint j;
-#else
-	char buf[4 * 1024]; // Arbitrary buffer size
-	struct ifconf ifconf;
-	const char* buf_end;
-	const char* p;
-#endif
-
-	// If something fails, make sure the list is empty
-	_broadcast_list[0] = 0;
-
-	sock = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sock == INVALID_SOCKET) return;
-
-#ifdef WIN32
-	memset(&ifo[0], 0, sizeof(ifo));
-	if ((WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &ifo[0], sizeof(ifo), &len, NULL, NULL)) != 0) {
-		closesocket(sock);
-		return;
-	}
-
-	i = 0;
-	for (j = 0; j < len / sizeof(*ifo); j++) {
-		if (ifo[j].iiFlags & IFF_LOOPBACK) continue;
-		if (!(ifo[j].iiFlags & IFF_BROADCAST)) continue;
-		/* iiBroadcast is unusable, because it always seems to be set to
-		 * 255.255.255.255.
-		 */
-		_broadcast_list[i++] =
-			 ifo[j].iiAddress.AddressIn.sin_addr.s_addr |
-			~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
-	}
-#else
-	ifconf.ifc_len = sizeof(buf);
-	ifconf.ifc_buf = buf;
-	if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) {
-		closesocket(sock);
-		return;
-	}
-
-	i = 0;
-	buf_end = buf + ifconf.ifc_len;
-	for (p = buf; p < buf_end;) {
-		const struct ifreq* req = (const struct ifreq*)p;
-
-		if (req->ifr_addr.sa_family == AF_INET) {
-			struct ifreq r;
-
-			strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name));
-			if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 &&
-					r.ifr_flags & IFF_BROADCAST &&
-					ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
-				_broadcast_list[i++] =
-					((struct sockaddr_in*)&r.ifr_broadaddr)->sin_addr.s_addr;
-			}
-		}
-
-		p += sizeof(struct ifreq);
-#ifdef AF_LINK
-		p += req->ifr_addr.sa_len - sizeof(struct sockaddr);
-#endif
-	}
-#endif
-
-	closesocket(sock);
-#endif /* not HAVE_GETIFADDRS */
-
-	_broadcast_list[i] = 0;
-
-	DEBUG(net, 3, "Detected broadcast addresses:");
-	// Now display to the debug all the detected ips
-	for (i = 0; _broadcast_list[i] != 0; i++) {
-		DEBUG(net, 3, "%d) %s", i, inet_ntoa(*(struct in_addr *)&_broadcast_list[i]));//inet_ntoa(inaddr));
-	}
-}
-
-// Resolve a hostname to a inet_addr
-unsigned long NetworkResolveHost(const char *hostname)
-{
-	in_addr_t ip;
-
-	// First try: is it an ip address?
-	ip = inet_addr(hostname);
-
-	// If not try to resolve the name
-	if (ip == INADDR_NONE) {
-		struct hostent *he = gethostbyname(hostname);
-		if (he == NULL) {
-			DEBUG(net, 0, "Cannot resolve '%s'", hostname);
-		} else {
-			struct in_addr addr = *(struct in_addr *)he->h_addr_list[0];
-			DEBUG(net, 1, "Resolved '%s' to %s", hostname, inet_ntoa(addr));
-			ip = addr.s_addr;
-		}
-	}
-	return ip;
-}
-
-// Converts a string to ip/port/player
-//  Format: IP#player:port
-//
-// connection_string will be re-terminated to seperate out the hostname, and player and port will
-// be set to the player and port strings given by the user, inside the memory area originally
-// occupied by connection_string.
-void ParseConnectionString(const char **player, const char **port, char *connection_string)
-{
-	char *p;
-	for (p = connection_string; *p != '\0'; p++) {
-		if (*p == '#') {
-			*p = '\0';
-			*player = ++p;
-			while (IsValidChar(*p, CS_NUMERAL)) p++;
-			if (*p == '\0') break;
-		} else if (*p == ':') {
-			*port = p + 1;
-			*p = '\0';
-		}
-	}
-}
-
-// Creates a new client from a socket
-//   Used both by the server and the client
-static NetworkClientState *NetworkAllocClient(SOCKET s)
-{
-	NetworkClientState *cs;
-	byte client_no = 0;
-
-	if (_network_server) {
-		// Can we handle a new client?
-		if (_network_clients_connected >= MAX_CLIENTS) return NULL;
-		if (_network_game_info.clients_on >= _network_game_info.clients_max) return NULL;
-
-		// Register the login
-		client_no = _network_clients_connected++;
-	}
-
-	cs = DEREF_CLIENT(client_no);
-	memset(cs, 0, sizeof(*cs));
-	cs->socket = s;
-	cs->last_frame = 0;
-	cs->has_quit = false;
-
-	cs->last_frame = _frame_counter;
-	cs->last_frame_server = _frame_counter;
-
-	if (_network_server) {
-		NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
-		memset(ci, 0, sizeof(*ci));
-
-		cs->index = _network_client_index++;
-		ci->client_index = cs->index;
-		ci->client_playas = PLAYER_INACTIVE_CLIENT;
-		ci->join_date = _date;
-
-		InvalidateWindow(WC_CLIENT_LIST, 0);
-	}
-
-	return cs;
-}
-
-// Close a connection
-void NetworkCloseClient(NetworkClientState *cs)
-{
-	NetworkClientInfo *ci;
-	// Socket is already dead
-	if (cs->socket == INVALID_SOCKET) {
-		cs->has_quit = true;
-		return;
-	}
-
-	DEBUG(net, 1, "Closed client connection %d", cs->index);
-
-	if (!cs->has_quit && _network_server && cs->status > STATUS_INACTIVE) {
-		// We did not receive a leave message from this client...
-		NetworkErrorCode errorno = NETWORK_ERROR_CONNECTION_LOST;
-		char str[100];
-		char client_name[NETWORK_CLIENT_NAME_LENGTH];
-		NetworkClientState *new_cs;
-
-		NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-		GetNetworkErrorMsg(str, errorno, lastof(str));
-
-		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
-
-		// Inform other clients of this... strange leaving ;)
-		FOR_ALL_CLIENTS(new_cs) {
-			if (new_cs->status > STATUS_AUTH && cs != new_cs) {
-				SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
-			}
-		}
-	}
-
-	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
-	if (cs->status == STATUS_PRE_ACTIVE && _network_pause_on_join) {
-		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
-		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX);
-	}
-
-	closesocket(cs->socket);
-	cs->writable = false;
-	cs->has_quit = true;
-
-	// Free all pending and partially received packets
-	while (cs->packet_queue != NULL) {
-		Packet *p = cs->packet_queue->next;
-		free(cs->packet_queue);
-		cs->packet_queue = p;
-	}
-	free(cs->packet_recv);
-	cs->packet_recv = NULL;
-
-	while (cs->command_queue != NULL) {
-		CommandPacket *p = cs->command_queue->next;
-		free(cs->command_queue);
-		cs->command_queue = p;
-	}
-
-	// Close the gap in the client-list
-	ci = DEREF_CLIENT_INFO(cs);
-
-	if (_network_server) {
-		// We just lost one client :(
-		if (cs->status > STATUS_INACTIVE) _network_game_info.clients_on--;
-		_network_clients_connected--;
-
-		while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->socket != INVALID_SOCKET) {
-			*cs = *(cs + 1);
-			*ci = *(ci + 1);
-			cs++;
-			ci++;
-		}
-
-		InvalidateWindow(WC_CLIENT_LIST, 0);
-	}
-
-	// Reset the status of the last socket
-	cs->socket = INVALID_SOCKET;
-	cs->status = STATUS_INACTIVE;
-	cs->index = NETWORK_EMPTY_INDEX;
-	ci->client_index = NETWORK_EMPTY_INDEX;
-
-	CheckMinPlayers();
-}
-
-// A client wants to connect to a server
-static bool NetworkConnect(const char *hostname, int port)
-{
-	SOCKET s;
-	struct sockaddr_in sin;
-
-	DEBUG(net, 1, "Connecting to %s %d", hostname, port);
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s == INVALID_SOCKET) {
-		ClientStartError("socket() failed");
-		return false;
-	}
-
-	if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
-
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = NetworkResolveHost(hostname);
-	sin.sin_port = htons(port);
-	_network_last_host_ip = sin.sin_addr.s_addr;
-
-	/* We failed to connect for which reason what so ever */
-	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) return false;
-
-	if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
-
-	// in client mode, only the first client field is used. it's pointing to the server.
-	NetworkAllocClient(s);
-
-	_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
-	ShowJoinStatusWindow();
-
-	return true;
-}
-
-// For the server, to accept new clients
-static void NetworkAcceptClients(void)
-{
-	struct sockaddr_in sin;
-	NetworkClientState *cs;
-	uint i;
-	bool banned;
-
-	// Should never ever happen.. is it possible??
-	assert(_listensocket != INVALID_SOCKET);
-
-	for (;;) {
-		socklen_t sin_len = sizeof(sin);
-		SOCKET s = accept(_listensocket, (struct sockaddr*)&sin, &sin_len);
-		if (s == INVALID_SOCKET) return;
-
-		SetNonBlocking(s); // XXX error handling?
-
-		DEBUG(net, 1, "Client connected from %s on frame %d", inet_ntoa(sin.sin_addr), _frame_counter);
-
-		SetNoDelay(s); // XXX error handling?
-
-		/* Check if the client is banned */
-		banned = false;
-		for (i = 0; i < lengthof(_network_ban_list); i++) {
-			if (_network_ban_list[i] == NULL) continue;
-
-			if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) {
-				Packet *p = NetworkSend_Init(PACKET_SERVER_BANNED);
-
-				DEBUG(net, 1, "Banned ip tried to join (%s), refused", _network_ban_list[i]);
-
-				p->buffer[0] = p->size & 0xFF;
-				p->buffer[1] = p->size >> 8;
-
-				send(s, p->buffer, p->size, 0);
-				closesocket(s);
-
-				free(p);
-
-				banned = true;
-				break;
-			}
-		}
-		/* If this client is banned, continue with next client */
-		if (banned) continue;
-
-		cs = NetworkAllocClient(s);
-		if (cs == NULL) {
-			// no more clients allowed?
-			// Send to the client that we are full!
-			Packet *p = NetworkSend_Init(PACKET_SERVER_FULL);
-
-			p->buffer[0] = p->size & 0xFF;
-			p->buffer[1] = p->size >> 8;
-
-			send(s, p->buffer, p->size, 0);
-			closesocket(s);
-
-			free(p);
-
-			continue;
-		}
-
-		// a new client has connected. We set him at inactive for now
-		//  maybe he is only requesting server-info. Till he has sent a PACKET_CLIENT_MAP_OK
-		//  the client stays inactive
-		cs->status = STATUS_INACTIVE;
-
-		DEREF_CLIENT_INFO(cs)->client_ip = sin.sin_addr.s_addr; // Save the IP of the client
-	}
-}
-
-// Set up the listen socket for the server
-static bool NetworkListen(void)
-{
-	SOCKET ls;
-	struct sockaddr_in sin;
-
-	DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
-
-	ls = socket(AF_INET, SOCK_STREAM, 0);
-	if (ls == INVALID_SOCKET) {
-		ServerStartError("socket() on listen socket failed");
-		return false;
-	}
-
-	{ // reuse the socket
-		int reuse = 1;
-		// The (const char*) cast is needed for windows!!
-		if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1) {
-			ServerStartError("setsockopt() on listen socket failed");
-			return false;
-		}
-	}
-
-	if (!SetNonBlocking(ls)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
-
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = _network_server_bind_ip;
-	sin.sin_port = htons(_network_server_port);
-
-	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
-		ServerStartError("bind() failed");
-		return false;
-	}
-
-	if (listen(ls, 1) != 0) {
-		ServerStartError("listen() failed");
-		return false;
-	}
-
-	_listensocket = ls;
-
-	return true;
-}
-
-// Close all current connections
-static void NetworkClose(void)
-{
-	NetworkClientState *cs;
-
-	FOR_ALL_CLIENTS(cs) {
-		if (!_network_server) {
-			SEND_COMMAND(PACKET_CLIENT_QUIT)("leaving");
-			NetworkSend_Packets(cs);
-		}
-		NetworkCloseClient(cs);
-	}
-
-	if (_network_server) {
-		// We are a server, also close the listensocket
-		closesocket(_listensocket);
-		_listensocket = INVALID_SOCKET;
-		DEBUG(net, 1, "Closed listener");
-		NetworkUDPClose();
-	}
-}
-
-// Inits the network (cleans sockets and stuff)
-static void NetworkInitialize(void)
-{
-	NetworkClientState *cs;
-
-	_local_command_queue = NULL;
-
-	// Clean all client-sockets
-	memset(_clients, 0, sizeof(_clients));
-	for (cs = _clients; cs != &_clients[MAX_CLIENTS]; cs++) {
-		cs->socket = INVALID_SOCKET;
-		cs->status = STATUS_INACTIVE;
-		cs->command_queue = NULL;
-	}
-
-	// Clean the client_info memory
-	memset(&_network_client_info, 0, sizeof(_network_client_info));
-	memset(&_network_player_info, 0, sizeof(_network_player_info));
-
-	_sync_frame = 0;
-	_network_first_time = true;
-
-	_network_reconnect = 0;
-
-	NetworkUDPInitialize();
-}
-
-// Query a server to fetch his game-info
-//  If game_info is true, only the gameinfo is fetched,
-//   else only the client_info is fetched
-NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info)
-{
-	if (!_network_available) return NULL;
-
-	NetworkDisconnect();
-
-	if (game_info) return NetworkUDPQueryServer(host, port);
-
-	NetworkInitialize();
-
-	_network_server = false;
-
-	// Try to connect
-	_networking = NetworkConnect(host, port);
-
-	// We are connected
-	if (_networking) {
-		SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)();
-	} else { // No networking, close everything down again
-		NetworkDisconnect();
-	}
-
-	return NULL;
-}
-
-/* Validates an address entered as a string and adds the server to
- * the list. If you use this function, the games will be marked
- * as manually added. */
-void NetworkAddServer(const char *b)
-{
-	if (*b != '\0') {
-		NetworkGameList *item;
-		const char *port = NULL;
-		const char *player = NULL;
-		char host[NETWORK_HOSTNAME_LENGTH];
-		uint16 rport;
-
-		ttd_strlcpy(host, b, lengthof(host));
-
-		ttd_strlcpy(_network_default_ip, b, lengthof(_network_default_ip));
-		rport = NETWORK_DEFAULT_PORT;
-
-		ParseConnectionString(&player, &port, host);
-		if (port != NULL) rport = atoi(port);
-
-		item = NetworkQueryServer(host, rport, true);
-		item->manually = true;
-	}
-}
-
-/* Generates the list of manually added hosts from NetworkGameList and
- * dumps them into the array _network_host_list. This array is needed
- * by the function that generates the config file. */
-void NetworkRebuildHostList(void)
-{
-	uint i = 0;
-	const NetworkGameList *item = _network_game_list;
-	while (item != NULL && i != lengthof(_network_host_list)) {
-		if (item->manually) {
-			free(_network_host_list[i]);
-			_network_host_list[i++] = str_fmt("%s:%i", item->info.hostname, item->port);
-		}
-		item = item->next;
-	}
-
-	for (; i < lengthof(_network_host_list); i++) {
-		free(_network_host_list[i]);
-		_network_host_list[i] = NULL;
-	}
-}
-
-// Used by clients, to connect to a server
-bool NetworkClientConnectGame(const char *host, uint16 port)
-{
-	if (!_network_available) return false;
-
-	if (port == 0) return false;
-
-	ttd_strlcpy(_network_last_host, host, sizeof(_network_last_host));
-	_network_last_port = port;
-
-	NetworkDisconnect();
-	NetworkUDPClose();
-	NetworkInitialize();
-
-	// Try to connect
-	_networking = NetworkConnect(host, port);
-
-	// We are connected
-	if (_networking) {
-		IConsoleCmdExec("exec scripts/on_client.scr 0");
-		NetworkClient_Connected();
-	} else {
-		// Connecting failed
-		NetworkError(STR_NETWORK_ERR_NOCONNECTION);
-	}
-
-	return _networking;
-}
-
-static void NetworkInitGameInfo(void)
-{
-	NetworkClientInfo *ci;
-
-	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
-	ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
-	ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
-	if (_network_game_info.server_name[0] == '\0')
-		snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
-
-	ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision));
-
-	// The server is a client too ;)
-	if (_network_dedicated) {
-		_network_game_info.clients_on = 0;
-		_network_game_info.companies_on = 0;
-		_network_game_info.dedicated = true;
-	} else {
-		_network_game_info.clients_on = 1;
-		_network_game_info.companies_on = 1;
-		_network_game_info.dedicated = false;
-	}
-
-	_network_game_info.spectators_on = 0;
-
-	_network_game_info.game_date = _date;
-	_network_game_info.start_date = ConvertYMDToDate(_patches.starting_year, 0, 1);
-	_network_game_info.map_width = MapSizeX();
-	_network_game_info.map_height = MapSizeY();
-	_network_game_info.map_set = _opt.landscape;
-
-	_network_game_info.use_password = (_network_server_password[0] != '\0');
-
-	// We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it
-	//  The index is NETWORK_SERVER_INDEX ( = 1)
-	ci = &_network_client_info[MAX_CLIENT_INFO - 1];
-	memset(ci, 0, sizeof(*ci));
-
-	ci->client_index = NETWORK_SERVER_INDEX;
-	ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
-
-	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
-	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
-}
-
-bool NetworkServerStart(void)
-{
-	if (!_network_available) return false;
-
-	/* Call the pre-scripts */
-	IConsoleCmdExec("exec scripts/pre_server.scr 0");
-	if (_network_dedicated) IConsoleCmdExec("exec scripts/pre_dedicated.scr 0");
-
-	NetworkInitialize();
-	if (!NetworkListen()) return false;
-
-	// Try to start UDP-server
-	_network_udp_server = true;
-	_network_udp_server = NetworkUDPListen(&_udp_server_socket, _network_server_bind_ip, _network_server_port, false);
-
-	_network_server = true;
-	_networking = true;
-	_frame_counter = 0;
-	_frame_counter_server = 0;
-	_frame_counter_max = 0;
-	_last_sync_frame = 0;
-	_network_own_client_index = NETWORK_SERVER_INDEX;
-
-	/* Non-dedicated server will always be player #1 */
-	if (!_network_dedicated) _network_playas = 0;
-
-	_network_clients_connected = 0;
-
-	NetworkInitGameInfo();
-
-	// execute server initialization script
-	IConsoleCmdExec("exec scripts/on_server.scr 0");
-	// if the server is dedicated ... add some other script
-	if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
-
-	_min_players_paused = false;
-	CheckMinPlayers();
-
-	/* Try to register us to the master server */
-	_network_last_advertise_frame = 0;
-	_network_need_advertise = true;
-	NetworkUDPAdvertise();
-	return true;
-}
-
-// The server is rebooting...
-// The only difference with NetworkDisconnect, is the packets that is sent
-void NetworkReboot(void)
-{
-	if (_network_server) {
-		NetworkClientState *cs;
-		FOR_ALL_CLIENTS(cs) {
-			SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
-			NetworkSend_Packets(cs);
-		}
-	}
-
-	NetworkClose();
-
-	// Free all queued commands
-	while (_local_command_queue != NULL) {
-		CommandPacket *p = _local_command_queue;
-		_local_command_queue = _local_command_queue->next;
-		free(p);
-	}
-
-	_networking = false;
-	_network_server = false;
-}
-
-// We want to disconnect from the host/clients
-void NetworkDisconnect(void)
-{
-	if (_network_server) {
-		NetworkClientState *cs;
-		FOR_ALL_CLIENTS(cs) {
-			SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
-			NetworkSend_Packets(cs);
-		}
-	}
-
-	if (_network_advertise) NetworkUDPRemoveAdvertise();
-
-	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-
-	NetworkClose();
-
-	// Free all queued commands
-	while (_local_command_queue != NULL) {
-		CommandPacket *p = _local_command_queue;
-		_local_command_queue = _local_command_queue->next;
-		free(p);
-	}
-
-	_networking = false;
-	_network_server = false;
-}
-
-// Receives something from the network
-static bool NetworkReceive(void)
-{
-	NetworkClientState *cs;
-	int n;
-	fd_set read_fd, write_fd;
-	struct timeval tv;
-
-	FD_ZERO(&read_fd);
-	FD_ZERO(&write_fd);
-
-	FOR_ALL_CLIENTS(cs) {
-		FD_SET(cs->socket, &read_fd);
-		FD_SET(cs->socket, &write_fd);
-	}
-
-	// take care of listener port
-	if (_network_server) FD_SET(_listensocket, &read_fd);
-
-	tv.tv_sec = tv.tv_usec = 0; // don't block at all.
-#if !defined(__MORPHOS__) && !defined(__AMIGA__)
-	n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
-#else
-	n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
-#endif
-	if (n == -1 && !_network_server) NetworkError(STR_NETWORK_ERR_LOSTCONNECTION);
-
-	// accept clients..
-	if (_network_server && FD_ISSET(_listensocket, &read_fd)) NetworkAcceptClients();
-
-	// read stuff from clients
-	FOR_ALL_CLIENTS(cs) {
-		cs->writable = !!FD_ISSET(cs->socket, &write_fd);
-		if (FD_ISSET(cs->socket, &read_fd)) {
-			if (_network_server) {
-				NetworkServer_ReadPackets(cs);
-			} else {
-				NetworkRecvStatus res;
-
-				// The client already was quiting!
-				if (cs->has_quit) return false;
-
-				res = NetworkClient_ReadPackets(cs);
-				if (res != NETWORK_RECV_STATUS_OKAY) {
-					// The client made an error of which we can not recover
-					//   close the client and drop back to main menu
-					NetworkClientError(res, cs);
-					return false;
-				}
-			}
-		}
-	}
-	return true;
-}
-
-// This sends all buffered commands (if possible)
-static void NetworkSend(void)
-{
-	NetworkClientState *cs;
-	FOR_ALL_CLIENTS(cs) {
-		if (cs->writable) {
-			NetworkSend_Packets(cs);
-
-			if (cs->status == STATUS_MAP) {
-				// This client is in the middle of a map-send, call the function for that
-				SEND_COMMAND(PACKET_SERVER_MAP)(cs);
-			}
-		}
-	}
-}
-
-// Handle the local-command-queue
-static void NetworkHandleLocalQueue(void)
-{
-	CommandPacket *cp, **cp_prev;
-
-	cp_prev = &_local_command_queue;
-
-	while ( (cp = *cp_prev) != NULL) {
-
-		// The queue is always in order, which means
-		// that the first element will be executed first.
-		if (_frame_counter < cp->frame) break;
-
-		if (_frame_counter > cp->frame) {
-			// If we reach here, it means for whatever reason, we've already executed
-			// past the command we need to execute.
-			DEBUG(net, 0, "Trying to execute a packet in the past!");
-			assert(0);
-		}
-
-		// We can execute this command
-		NetworkExecuteCommand(cp);
-
-		*cp_prev = cp->next;
-		free(cp);
-	}
-
-	// Just a safety check, to be removed in the future.
-	// Make sure that no older command appears towards the end of the queue
-	// In that case we missed executing it. This will never happen.
-	for (cp = _local_command_queue; cp; cp = cp->next) {
-		assert(_frame_counter < cp->frame);
-	}
-
-}
-
-static bool NetworkDoClientLoop(void)
-{
-	_frame_counter++;
-
-	NetworkHandleLocalQueue();
-
-	StateGameLoop();
-
-	// Check if we are in sync!
-	if (_sync_frame != 0) {
-		if (_sync_frame == _frame_counter) {
-#ifdef NETWORK_SEND_DOUBLE_SEED
-			if (_sync_seed_1 != _random_seeds[0][0] || _sync_seed_2 != _random_seeds[0][1]) {
-#else
-			if (_sync_seed_1 != _random_seeds[0][0]) {
-#endif
-				NetworkError(STR_NETWORK_ERR_DESYNC);
-				DEBUG(net, 0, "Sync error detected!");
-				NetworkClientError(NETWORK_RECV_STATUS_DESYNC, DEREF_CLIENT(0));
-				return false;
-			}
-
-			// If this is the first time we have a sync-frame, we
-			//   need to let the server know that we are ready and at the same
-			//   frame as he is.. so we can start playing!
-			if (_network_first_time) {
-				_network_first_time = false;
-				SEND_COMMAND(PACKET_CLIENT_ACK)();
-			}
-
-			_sync_frame = 0;
-		} else if (_sync_frame < _frame_counter) {
-			DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
-			_sync_frame = 0;
-		}
-	}
-
-	return true;
-}
-
-// We have to do some UDP checking
-void NetworkUDPGameLoop(void)
-{
-	if (_network_udp_server) {
-		NetworkUDPReceive(_udp_server_socket);
-		if (_udp_master_socket != INVALID_SOCKET) {
-			NetworkUDPReceive(_udp_master_socket);
-		}
-	} else if (_udp_client_socket != INVALID_SOCKET) {
-		NetworkUDPReceive(_udp_client_socket);
-		if (_network_udp_broadcast > 0) _network_udp_broadcast--;
-	}
-}
-
-// The main loop called from ttd.c
-//  Here we also have to do StateGameLoop if needed!
-void NetworkGameLoop(void)
-{
-	if (!_networking) return;
-
-	if (!NetworkReceive()) return;
-
-	if (_network_server) {
-		bool send_frame = false;
-
-		// We first increase the _frame_counter
-		_frame_counter++;
-		// Update max-frame-counter
-		if (_frame_counter > _frame_counter_max) {
-			_frame_counter_max = _frame_counter + _network_frame_freq;
-			send_frame = true;
-		}
-
-		NetworkHandleLocalQueue();
-
-		// Then we make the frame
-		StateGameLoop();
-
-		_sync_seed_1 = _random_seeds[0][0];
-#ifdef NETWORK_SEND_DOUBLE_SEED
-		_sync_seed_2 = _random_seeds[0][1];
-#endif
-
-		NetworkServer_Tick(send_frame);
-	} else {
-		// Client
-
-		// Make sure we are at the frame were the server is (quick-frames)
-		if (_frame_counter_server > _frame_counter) {
-			while (_frame_counter_server > _frame_counter) {
-				if (!NetworkDoClientLoop()) break;
-			}
-		} else {
-			// Else, keep on going till _frame_counter_max
-			if (_frame_counter_max > _frame_counter) NetworkDoClientLoop();
-		}
-	}
-
-	NetworkSend();
-}
-
-static void NetworkGenerateUniqueId(void)
-{
-	md5_state_t state;
-	md5_byte_t digest[16];
-	char hex_output[16*2 + 1];
-	char coding_string[NETWORK_NAME_LENGTH];
-	int di;
-
-	snprintf(coding_string, sizeof(coding_string), "%d%s", (uint)Random(), "OpenTTD Unique ID");
-
-	/* Generate the MD5 hash */
-	md5_init(&state);
-	md5_append(&state, (const md5_byte_t*)coding_string, strlen(coding_string));
-	md5_finish(&state, digest);
-
-	for (di = 0; di < 16; ++di)
-		sprintf(hex_output + di * 2, "%02x", digest[di]);
-
-	/* _network_unique_id is our id */
-	snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
-}
-
-// This tries to launch the network for a given OS
-void NetworkStartUp(void)
-{
-	DEBUG(net, 3, "[core] starting network...");
-
-#if defined(__MORPHOS__) || defined(__AMIGA__)
-	/*
-	 *  IMPORTANT NOTE: SocketBase needs to be initialized before we use _any_
-	 *  network related function, else: crash.
-	 */
-	DEBUG(net, 3, "[core] loading bsd socket library");
-	SocketBase = OpenLibrary("bsdsocket.library", 4);
-	if (SocketBase == NULL) {
-		DEBUG(net, 0, "[core] can't open bsdsocket.library version 4, network unavailable");
-		_network_available = false;
-		return;
-	}
-
-#if defined(__AMIGA__)
-	// for usleep() implementation (only required for legacy AmigaOS builds)
-	TimerPort = CreateMsgPort();
-	if (TimerPort != NULL) {
-		TimerRequest = (struct timerequest*)CreateIORequest(TimerPort, sizeof(struct timerequest);
-		if (TimerRequest != NULL) {
-			if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest*)TimerRequest, 0) == 0) {
-				TimerBase = TimerRequest->tr_node.io_Device;
-				if (TimerBase == NULL) {
-					// free ressources...
-					DEBUG(net, 0, "[core] can't initialize timer, network unavailable");
-					_network_available = false;
-					return;
-				}
-			}
-		}
-	}
-#endif // __AMIGA__
-#endif // __MORPHOS__ / __AMIGA__
-
-	// Network is available
-	_network_available = true;
-	_network_dedicated = false;
-	_network_last_advertise_frame = 0;
-	_network_need_advertise = true;
-	_network_advertise_retries = 0;
-
-	/* Load the ip from the openttd.cfg */
-	_network_server_bind_ip = inet_addr(_network_server_bind_ip_host);
-	/* And put the data back in it in case it was an invalid ip */
-	snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
-
-	/* Generate an unique id when there is none yet */
-	if (_network_unique_id[0] == '\0') NetworkGenerateUniqueId();
-
-	{
-		byte cl_max = _network_game_info.clients_max;
-		byte cp_max = _network_game_info.companies_max;
-		byte sp_max = _network_game_info.spectators_max;
-
-		memset(&_network_game_info, 0, sizeof(_network_game_info));
-		_network_game_info.clients_max = cl_max;
-		_network_game_info.companies_max = cp_max;
-		_network_game_info.spectators_max = sp_max;
-	}
-
-	// Let's load the network in windows
-	#if defined(WIN32)
-	{
-		WSADATA wsa;
-		DEBUG(net, 3, "[core] loading windows socket library");
-		if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
-			DEBUG(net, 0, "[core] WSAStartup failed, network unavailable");
-			_network_available = false;
-			return;
-		}
-	}
-	#endif // WIN32
-
-	NetworkInitialize();
-	DEBUG(net, 3, "[core] network online, multiplayer available");
-	NetworkFindIPs();
-}
-
-// This shuts the network down
-void NetworkShutDown(void)
-{
-	NetworkDisconnect();
-	NetworkUDPClose();
-
-	DEBUG(net, 3, "[core] shutting down network");
-
-	_network_available = false;
-
-#if defined(__MORPHOS__) || defined(__AMIGA__)
-	// free allocated ressources
-#if defined(__AMIGA__)
-	if (TimerBase    != NULL) CloseDevice((struct IORequest*)TimerRequest); // XXX This smells wrong
-	if (TimerRequest != NULL) DeleteIORequest(TimerRequest);
-	if (TimerPort    != NULL) DeleteMsgPort(TimerPort);
-#endif
-
-	if (SocketBase != NULL) CloseLibrary(SocketBase);
-#endif
-
-#if defined(WIN32)
-	WSACleanup();
-#endif
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_H
-#define NETWORK_H
-
-#define NOREV_STRING "norev000"
-
-#ifdef ENABLE_NETWORK
-
-#include "player.h"
-
-// If this line is enable, every frame will have a sync test
-//  this is not needed in normal games. Normal is like 1 sync in 100
-//  frames. You can enable this if you have a lot of desyncs on a certain
-//  game.
-// Remember: both client and server have to be compiled with this
-//  option enabled to make it to work. If one of the two has it disabled
-//  nothing will happen.
-//#define ENABLE_NETWORK_SYNC_EVERY_FRAME
-
-// In theory sending 1 of the 2 seeds is enough to check for desyncs
-//   so in theory, this next define can be left off.
-//#define NETWORK_SEND_DOUBLE_SEED
-
-// How many clients can we have? Like.. MAX_PLAYERS - 1 is the amount of
-//  players that can really play.. so.. a max of 4 spectators.. gives us..
-//  MAX_PLAYERS + 3
-#define MAX_CLIENTS (MAX_PLAYERS + 3)
-
-
-// Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1
-#define MAX_CLIENT_INFO (MAX_CLIENTS + 1)
-
-/* Stuff for the master-server */
-#define NETWORK_MASTER_SERVER_PORT 3978
-#define NETWORK_MASTER_SERVER_HOST "master.openttd.org"
-#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister"
-
-#define NETWORK_DEFAULT_PORT 3979
-
-#define MAX_INTERFACES 9
-
-
-// How many vehicle/station types we put over the network
-#define NETWORK_VEHICLE_TYPES 5
-#define NETWORK_STATION_TYPES 5
-
-enum {
-	NETWORK_NAME_LENGTH        =  80,
-	NETWORK_HOSTNAME_LENGTH    =  80,
-	NETWORK_REVISION_LENGTH    =  15,
-	NETWORK_PASSWORD_LENGTH    =  20,
-	NETWORK_PLAYERS_LENGTH     = 200,
-	NETWORK_CLIENT_NAME_LENGTH =  25,
-	NETWORK_RCONCOMMAND_LENGTH = 500,
-
-	NETWORK_GRF_NAME_LENGTH    =  80, ///< Maximum length of the name of a GRF
-	/* Maximum number of GRFs that can be sent.
-	 * This value is related to number of handles (files) OpenTTD can open.
-	 * This is currently 64 and about 10 are currently used when OpenTTD loads
-	 * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so
-	 * this is not a limit, but rather a way to easily check whether the limit
-	 * imposed by the handle count is reached. Secondly it isn't possible to
-	 * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due
-	 * to the limited size of UDP packets. */
-	NETWORK_MAX_GRF_COUNT      =  55,
-
-	NETWORK_NUM_LANGUAGES      =   4,
-};
-
-// This is the struct used by both client and server
-//  some fields will be empty on the client (like game_password) by default
-//  and only filled with data a player enters.
-typedef struct NetworkGameInfo {
-	char server_name[NETWORK_NAME_LENGTH];          // Server name
-	char hostname[NETWORK_HOSTNAME_LENGTH];         // Hostname of the server (if any)
-	char server_revision[NETWORK_REVISION_LENGTH];  // The SVN version number the server is using (e.g.: 'r304')
-	                                                //  It even shows a SVN version in release-version, so
-	                                                //  it is easy to compare if a server is of the correct version
-	bool version_compatible;                        // Can we connect to this server or not? (based on server_revision)
-	bool compatible;                                // Can we connect to this server or not? (based on server_revision _and_ grf_match
-	byte server_lang;                               // Language of the server (we should make a nice table for this)
-	byte use_password;                              // Is set to != 0 if it uses a password
-	char server_password[NETWORK_PASSWORD_LENGTH];  // On the server: the game password, on the client: != "" if server has password
-	byte clients_max;                               // Max clients allowed on server
-	byte clients_on;                                // Current count of clients on server
-	byte companies_max;                             // Max companies allowed on server
-	byte companies_on;                              // How many started companies do we have (XXX - disabled for server atm, use ActivePlayerCount())
-	byte spectators_max;                            // Max spectators allowed on server
-	byte spectators_on;                             // How many spectators do we have? (XXX - disabled for server atm, use NetworkSpectatorCount())
-	Date game_date;                                 // Current date
-	Date start_date;                                // When the game started
-	char map_name[NETWORK_NAME_LENGTH];             // Map which is played ["random" for a randomized map]
-	uint16 map_width;                               // Map width
-	uint16 map_height;                              // Map height
-	byte map_set;                                   // Graphical set
-	bool dedicated;                                 // Is this a dedicated server?
-	char rcon_password[NETWORK_PASSWORD_LENGTH];    // RCon password for the server. "" if rcon is disabled
-	struct GRFConfig *grfconfig;                    // List of NewGRF files required
-} NetworkGameInfo;
-
-typedef struct NetworkPlayerInfo {
-	char company_name[NETWORK_NAME_LENGTH];         // Company name
-	char password[NETWORK_PASSWORD_LENGTH];         // The password for the player
-	Year inaugurated_year;                          // What year the company started in
-	int64 company_value;                            // The company value
-	int64 money;                                    // The amount of money the company has
-	int64 income;                                   // How much did the company earned last year
-	uint16 performance;                             // What was his performance last month?
-	byte use_password;                              // 0: No password 1: There is a password
-	uint16 num_vehicle[NETWORK_VEHICLE_TYPES];      // How many vehicles are there of this type?
-	uint16 num_station[NETWORK_STATION_TYPES];      // How many stations are there of this type?
-	char players[NETWORK_PLAYERS_LENGTH];           // The players that control this company (Name1, name2, ..)
-	uint16 months_empty;                            // How many months the company is empty
-} NetworkPlayerInfo;
-
-typedef struct NetworkClientInfo {
-	uint16 client_index;                            // Index of the client (same as ClientState->index)
-	char client_name[NETWORK_CLIENT_NAME_LENGTH];   // Name of the client
-	byte client_lang;                               // The language of the client
-	byte client_playas;                             // As which player is this client playing (PlayerID)
-	uint32 client_ip;                               // IP-address of the client (so he can be banned)
-	Date join_date;                                 // Gamedate the player has joined
-	char unique_id[NETWORK_NAME_LENGTH];            // Every play sends an unique id so we can indentify him
-} NetworkClientInfo;
-
-typedef struct NetworkGameList {
-	NetworkGameInfo info;
-	uint32 ip;
-	uint16 port;
-	bool online;                                    // False if the server did not respond (default status)
-	bool manually;                                  // True if the server was added manually
-	struct NetworkGameList *next;
-} NetworkGameList;
-
-typedef enum {
-	NETWORK_JOIN_STATUS_CONNECTING,
-	NETWORK_JOIN_STATUS_AUTHORIZING,
-	NETWORK_JOIN_STATUS_WAITING,
-	NETWORK_JOIN_STATUS_DOWNLOADING,
-	NETWORK_JOIN_STATUS_PROCESSING,
-	NETWORK_JOIN_STATUS_REGISTERING,
-
-	NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO,
-} NetworkJoinStatus;
-
-// language ids for server_lang and client_lang
-typedef enum {
-	NETLANG_ANY     = 0,
-	NETLANG_ENGLISH = 1,
-	NETLANG_GERMAN  = 2,
-	NETLANG_FRENCH  = 3,
-} NetworkLanguage;
-
-VARDEF NetworkGameList *_network_game_list;
-
-VARDEF NetworkGameInfo _network_game_info;
-VARDEF NetworkPlayerInfo _network_player_info[MAX_PLAYERS];
-VARDEF NetworkClientInfo _network_client_info[MAX_CLIENT_INFO];
-
-VARDEF char _network_player_name[NETWORK_CLIENT_NAME_LENGTH];
-VARDEF char _network_default_ip[NETWORK_HOSTNAME_LENGTH];
-
-VARDEF uint16 _network_own_client_index;
-VARDEF char _network_unique_id[NETWORK_NAME_LENGTH]; // Our own unique ID
-
-VARDEF uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode
-VARDEF uint32 _frame_counter_max; // To where we may go with our clients
-
-VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients.
-
-// networking settings
-VARDEF uint32 _broadcast_list[MAX_INTERFACES + 1];
-
-VARDEF uint16 _network_server_port;
-/* We use bind_ip and bind_ip_host, where bind_ip_host is the readable form of
-    bind_ip_host, and bind_ip the numeric value, because we want a nice number
-    in the openttd.cfg, but we wants to use the uint32 internally.. */
-VARDEF uint32 _network_server_bind_ip;
-VARDEF char _network_server_bind_ip_host[NETWORK_HOSTNAME_LENGTH];
-VARDEF bool _is_network_server; // Does this client wants to be a network-server?
-VARDEF char _network_server_name[NETWORK_NAME_LENGTH];
-VARDEF char _network_server_password[NETWORK_PASSWORD_LENGTH];
-VARDEF char _network_rcon_password[NETWORK_PASSWORD_LENGTH];
-
-VARDEF uint16 _network_max_join_time;             ///< Time a client can max take to join
-VARDEF bool _network_pause_on_join;               ///< Pause the game when a client tries to join (more chance of succeeding join)
-
-VARDEF uint16 _redirect_console_to_client;
-
-VARDEF uint16 _network_sync_freq;
-VARDEF uint8 _network_frame_freq;
-
-VARDEF uint32 _sync_seed_1, _sync_seed_2;
-VARDEF uint32 _sync_frame;
-VARDEF bool _network_first_time;
-// Vars needed for the join-GUI
-VARDEF NetworkJoinStatus _network_join_status;
-VARDEF uint8 _network_join_waiting;
-VARDEF uint16 _network_join_kbytes;
-VARDEF uint16 _network_join_kbytes_total;
-
-VARDEF char _network_last_host[NETWORK_HOSTNAME_LENGTH];
-VARDEF short _network_last_port;
-VARDEF uint32 _network_last_host_ip;
-VARDEF uint8 _network_reconnect;
-
-VARDEF bool _network_udp_server;
-VARDEF uint16 _network_udp_broadcast;
-
-VARDEF byte _network_lan_internet;
-
-VARDEF bool _network_need_advertise;
-VARDEF uint32 _network_last_advertise_frame;
-VARDEF uint8 _network_advertise_retries;
-
-VARDEF bool _network_autoclean_companies;
-VARDEF uint8 _network_autoclean_unprotected; // Remove a company after X months
-VARDEF uint8 _network_autoclean_protected;   // Unprotect a company after X months
-
-VARDEF Year _network_restart_game_year;      // If this year is reached, the server automaticly restarts
-VARDEF uint8 _network_min_players;           // Minimum number of players for game to unpause
-
-NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info);
-
-byte NetworkSpectatorCount(void);
-
-VARDEF char *_network_host_list[10];
-VARDEF char *_network_ban_list[25];
-
-void ParseConnectionString(const char **player, const char **port, char *connection_string);
-void NetworkUpdateClientInfo(uint16 client_index);
-void NetworkAddServer(const char *b);
-void NetworkRebuildHostList(void);
-bool NetworkChangeCompanyPassword(byte argc, char *argv[]);
-void NetworkPopulateCompanyInfo(void);
-void UpdateNetworkGameWindow(bool unselect);
-void CheckMinPlayers(void);
-
-void NetworkStartUp(void);
-void NetworkUDPClose(void);
-void NetworkShutDown(void);
-void NetworkGameLoop(void);
-void NetworkUDPGameLoop(void);
-bool NetworkServerStart(void);
-bool NetworkClientConnectGame(const char *host, uint16 port);
-void NetworkReboot(void);
-void NetworkDisconnect(void);
-
-VARDEF bool _networking;         ///< are we in networking mode?
-VARDEF bool _network_server;     ///< network-server is active
-VARDEF bool _network_available;  ///< is network mode available?
-
-#else /* ENABLE_NETWORK */
-/* Network function stubs when networking is disabled */
-
-static inline void NetworkStartUp(void) {}
-static inline void NetworkShutDown(void) {}
-
-#define _networking 0
-#define _network_server 0
-#define _network_available 0
-
-#endif /* ENABLE_NETWORK */
-
-/* These variables must always be registered! */
-VARDEF bool _network_dedicated;  ///< are we a dedicated server?
-VARDEF bool _network_advertise;  ///< is the server advertising to the master server?
-VARDEF PlayerID _network_playas; ///< an id to play as.. (see players.h:Players)
-
-#endif /* NETWORK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/config.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_CONFIG_H
+#define NETWORK_CORE_CONFIG_H
+
+#ifdef ENABLE_NETWORK
+
+/** DNS hostname of the masterserver */
+#define NETWORK_MASTER_SERVER_HOST "master.openttd.org"
+/** Message sent to the masterserver to 'identify' this client as OpenTTD */
+#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister"
+
+enum {
+	NETWORK_MASTER_SERVER_PORT    = 3978, ///< The default port of the master server (UDP)
+	NETWORK_DEFAULT_PORT          = 3979, ///< The default port of the game server (TCP & UDP)
+
+	SEND_MTU                      = 1460, ///< Number of bytes we can pack in a single packet
+
+	NETWORK_GAME_INFO_VERSION     =    4, ///< What version of game-info do we use?
+	NETWORK_COMPANY_INFO_VERSION  =    4, ///< What version of company info is this?
+	NETWORK_MASTER_SERVER_VERSION =    1, ///< What version of master-server-protocol do we use?
+
+	NETWORK_NAME_LENGTH           =   80, ///< The maximum length of the server name and map name, in bytes including '\0'
+	NETWORK_HOSTNAME_LENGTH       =   80, ///< The maximum length of the host name, in bytes including '\0'
+	NETWORK_REVISION_LENGTH       =   15, ///< The maximum length of the revision, in bytes including '\0'
+	NETWORK_PASSWORD_LENGTH       =   20, ///< The maximum length of the password, in bytes including '\0'
+	NETWORK_PLAYERS_LENGTH        =  200, ///< The maximum length for the list of players that controls a company, in bytes including '\0'
+	NETWORK_CLIENT_NAME_LENGTH    =   25, ///< The maximum length of a player, in bytes including '\0'
+	NETWORK_RCONCOMMAND_LENGTH    =  500, ///< The maximum length of a rconsole command, in bytes including '\0'
+
+	NETWORK_GRF_NAME_LENGTH       =   80, ///< Maximum length of the name of a GRF
+	/**
+	 * Maximum number of GRFs that can be sent.
+	 * This value is related to number of handles (files) OpenTTD can open.
+	 * This is currently 64 and about 10 are currently used when OpenTTD loads
+	 * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so
+	 * this is not a limit, but rather a way to easily check whether the limit
+	 * imposed by the handle count is reached. Secondly it isn't possible to
+	 * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due
+	 * to the limited size of UDP packets.
+	 */
+	NETWORK_MAX_GRF_COUNT         =   55,
+
+	NETWORK_NUM_LANGUAGES         =    4, ///< Number of known languages (to the network protocol) + 1 for 'any'.
+};
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_CONFIG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/game.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_GAME_H
+#define NETWORK_CORE_GAME_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file game.h Information about a game that is sent between a
+ *              game server, game client and masterserver.
+ */
+
+/**
+ * This is the struct used by both client and server
+ * some fields will be empty on the client (like game_password) by default
+ * and only filled with data a player enters.
+ */
+typedef struct NetworkGameInfo {
+	byte game_info_version;                         ///< Version of the game info
+	char server_name[NETWORK_NAME_LENGTH];          ///< Server name
+	char hostname[NETWORK_HOSTNAME_LENGTH];         ///< Hostname of the server (if any)
+	char server_revision[NETWORK_REVISION_LENGTH];  ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
+	bool version_compatible;                        ///< Can we connect to this server or not? (based on server_revision)
+	bool compatible;                                ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
+	byte server_lang;                               ///< Language of the server (we should make a nice table for this)
+	byte use_password;                              ///< Is set to != 0 if it uses a password
+	char server_password[NETWORK_PASSWORD_LENGTH];  ///< On the server: the game password, on the client: != "" if server has password
+	byte clients_max;                               ///< Max clients allowed on server
+	byte clients_on;                                ///< Current count of clients on server
+	byte companies_max;                             ///< Max companies allowed on server
+	byte companies_on;                              ///< How many started companies do we have
+	byte spectators_max;                            ///< Max spectators allowed on server
+	byte spectators_on;                             ///< How many spectators do we have?
+	Date game_date;                                 ///< Current date
+	Date start_date;                                ///< When the game started
+	char map_name[NETWORK_NAME_LENGTH];             ///< Map which is played ["random" for a randomized map]
+	uint16 map_width;                               ///< Map width
+	uint16 map_height;                              ///< Map height
+	byte map_set;                                   ///< Graphical set
+	bool dedicated;                                 ///< Is this a dedicated server?
+	char rcon_password[NETWORK_PASSWORD_LENGTH];    ///< RCon password for the server. "" if rcon is disabled
+	struct GRFConfig *grfconfig;                    ///< List of NewGRF files used
+} NetworkGameInfo;
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_GAME_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/os_abstraction.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,181 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_OS_ABSTRACTION_H
+#define NETWORK_CORE_OS_ABSTRACTION_H
+
+/**
+ * @file os_abstraction.h Network stuff has many things that needs to be
+ *                        included and/or implemented by default.
+ *                        All those things are in this file.
+ */
+
+/* Include standard stuff per OS */
+
+#ifdef ENABLE_NETWORK
+
+/* Windows stuff */
+#if defined(WIN32) || defined(WIN64)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#if !(defined(__MINGW32__) || defined(__CYGWIN__))
+	/* Windows has some different names for some types */
+	typedef SSIZE_T ssize_t;
+	typedef int socklen_t;
+#endif
+
+#define GET_LAST_ERROR() WSAGetLastError()
+#define EWOULDBLOCK WSAEWOULDBLOCK
+/* Windows has some different names for some types */
+typedef unsigned long in_addr_t;
+#endif /* WIN32 */
+
+/* UNIX stuff */
+#if defined(UNIX)
+#	define SOCKET int
+#	define INVALID_SOCKET -1
+#	if !defined(__MORPHOS__) && !defined(__AMIGA__)
+#		define ioctlsocket ioctl
+#	if !defined(BEOS_NET_SERVER)
+#		define closesocket close
+#	endif
+#		define GET_LAST_ERROR() (errno)
+#	endif
+/* Need this for FIONREAD on solaris */
+#	define BSD_COMP
+
+/* Includes needed for UNIX-like systems */
+#	include <unistd.h>
+#	include <sys/ioctl.h>
+#	if defined(__BEOS__) && defined(BEOS_NET_SERVER)
+#		include <be/net/socket.h>
+#		include <be/kernel/OS.h> // snooze()
+#		include <be/net/netdb.h>
+		typedef unsigned long in_addr_t;
+#		define INADDR_NONE INADDR_BROADCAST
+#	else
+#		include <sys/socket.h>
+#		include <netinet/in.h>
+#		include <netinet/tcp.h>
+#		include <arpa/inet.h>
+#		include <net/if.h>
+/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
+#		if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__INNOTEK_LIBC__) \
+		   && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__)
+/* If for any reason ifaddrs.h does not exist on your system, comment out
+ *   the following two lines and an alternative way will be used to fetch
+ *   the list of IPs from the system. */
+#			include <ifaddrs.h>
+#			define HAVE_GETIFADDRS
+#		endif
+#		if defined(SUNOS) || defined(__MORPHOS__) || defined(__BEOS__)
+#			define INADDR_NONE 0xffffffff
+#		endif
+#		if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
+			/* needed on Zeta */
+#			include <sys/sockio.h>
+#		endif
+#	endif /* BEOS_NET_SERVER */
+
+#	if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
+		typedef uint32_t in_addr_t;
+#	endif
+
+#	include <errno.h>
+#	include <sys/time.h>
+#	include <netdb.h>
+#endif // UNIX
+
+#ifdef __BEOS__
+	typedef int socklen_t;
+#endif
+
+/* OS/2 stuff */
+#if defined(__OS2__)
+#	define SOCKET int
+#	define INVALID_SOCKET -1
+#	define ioctlsocket ioctl
+#	define closesocket close
+#	define GET_LAST_ERROR() (sock_errno())
+
+/* Includes needed for OS/2 systems */
+#	include <types.h>
+#	include <unistd.h>
+#	include <sys/ioctl.h>
+#	include <sys/socket.h>
+#	include <netinet/in.h>
+#	include <netinet/tcp.h>
+#	include <arpa/inet.h>
+#	include <net/if.h>
+#	include <errno.h>
+#	include <sys/time.h>
+#	include <netdb.h>
+#	include <nerrno.h>
+#	define INADDR_NONE 0xffffffff
+
+typedef int socklen_t;
+#if !defined(__INNOTEK_LIBC__)
+typedef unsigned long in_addr_t;
+#endif /* __INNOTEK_LIBC__ */
+#endif /* OS/2 */
+
+/* MorphOS and Amiga stuff */
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+#	include <exec/types.h>
+#	include <proto/exec.h>   // required for Open/CloseLibrary()
+#	if defined(__MORPHOS__)
+#		include <sys/filio.h>  // FIO* defines
+#		include <sys/sockio.h> // SIO* defines
+#		include <netinet/in.h>
+#	else /* __AMIGA__ */
+#		include	<proto/socket.h>
+#	endif
+
+/* Make the names compatible */
+#	define closesocket(s) CloseSocket(s)
+#	define GET_LAST_ERROR() Errno()
+#	define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status)
+#	define ioctl ioctlsocket
+
+	typedef unsigned int in_addr_t;
+	typedef long         socklen_t;
+	extern struct Library *SocketBase;
+
+#	ifdef __AMIGA__
+	/* for usleep() implementation */
+	extern struct Device      *TimerBase;
+	extern struct MsgPort     *TimerPort;
+	extern struct timerequest *TimerRequest;
+#	endif
+#endif // __MORPHOS__ || __AMIGA__
+
+static inline bool SetNonBlocking(int d)
+{
+#ifdef WIN32
+	u_long nonblocking = 1;
+#else
+	int nonblocking = 1;
+#endif
+#if defined(__BEOS__) && defined(BEOS_NET_SERVER)
+	return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
+#else
+	return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
+#endif
+}
+
+static inline bool SetNoDelay(int d)
+{
+	/* XXX should this be done at all? */
+#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server
+	int b = 1;
+	/* The (const char*) cast is needed for windows */
+	return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
+#else
+	return true;
+#endif
+}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/packet.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,216 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../macros.h"
+#include "../../string.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+
+/* Do not want to include functions.h and all required headers */
+extern void NORETURN CDECL error(const char *str, ...);
+
+
+/**
+ * Create a packet for sending
+ * @param type the of packet
+ * @return the newly created packet
+ */
+Packet *NetworkSend_Init(PacketType type)
+{
+	Packet *packet = malloc(sizeof(Packet));
+	/* An error is inplace here, because it simply means we ran out of memory. */
+	if (packet == NULL) error("Failed to allocate Packet");
+
+	/* Skip the size so we can write that in before sending the packet */
+	packet->size = sizeof(packet->size);
+	packet->buffer[packet->size++] = type;
+	packet->pos = 0;
+
+	return packet;
+}
+
+/**
+ * Writes the packet size from the raw packet from packet->size
+ * @param packet the packet to write the size of
+ */
+void NetworkSend_FillPacketSize(Packet *packet)
+{
+	packet->buffer[0] = GB(packet->size, 0, 8);
+	packet->buffer[1] = GB(packet->size, 8, 8);
+}
+
+/**
+ * The next couple of functions make sure we can send
+ *  uint8, uint16, uint32 and uint64 endian-safe
+ *  over the network. The least significant bytes are
+ *  sent first.
+ *
+ *  So 0x01234567 would be sent as 67 45 23 01.
+ */
+
+void NetworkSend_uint8(Packet *packet, uint8 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = data;
+}
+
+void NetworkSend_uint16(Packet *packet, uint16 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data, 0, 8);
+	packet->buffer[packet->size++] = GB(data, 8, 8);
+}
+
+void NetworkSend_uint32(Packet *packet, uint32 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data,  0, 8);
+	packet->buffer[packet->size++] = GB(data,  8, 8);
+	packet->buffer[packet->size++] = GB(data, 16, 8);
+	packet->buffer[packet->size++] = GB(data, 24, 8);
+}
+
+void NetworkSend_uint64(Packet *packet, uint64 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data,  0, 8);
+	packet->buffer[packet->size++] = GB(data,  8, 8);
+	packet->buffer[packet->size++] = GB(data, 16, 8);
+	packet->buffer[packet->size++] = GB(data, 24, 8);
+	packet->buffer[packet->size++] = GB(data, 32, 8);
+	packet->buffer[packet->size++] = GB(data, 40, 8);
+	packet->buffer[packet->size++] = GB(data, 48, 8);
+	packet->buffer[packet->size++] = GB(data, 56, 8);
+}
+
+/**
+ *  Sends a string over the network. It sends out
+ *  the string + '\0'. No size-byte or something.
+ */
+void NetworkSend_string(Packet *packet, const char* data)
+{
+	assert(data != NULL);
+	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
+	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
+}
+
+
+/**
+ * Receiving commands
+ * Again, the next couple of functions are endian-safe
+ *  see the comment before NetworkSend_uint8 for more info.
+ */
+
+
+extern uint CloseConnection(NetworkClientState *cs);
+
+/** Is it safe to read from the packet, i.e. didn't we run over the buffer ? */
+static inline bool CanReadFromPacket(NetworkClientState *cs, Packet *packet, uint bytes_to_read)
+{
+	/* Don't allow reading from a closed socket */
+	if (HasClientQuit(cs)) return false;
+
+	/* Check if variable is within packet-size */
+	if (packet->pos + bytes_to_read > packet->size) {
+		CloseConnection(cs);
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * Reads the packet size from the raw packet and stores it in the packet->size
+ * @param packet the packet to read the size of
+ */
+void NetworkRecv_ReadPacketSize(Packet *packet)
+{
+	packet->size  = (uint16)packet->buffer[0];
+	packet->size += (uint16)packet->buffer[1] << 8;
+}
+
+uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
+{
+	uint8 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n = packet->buffer[packet->pos++];
+	return n;
+}
+
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
+{
+	uint16 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint16)packet->buffer[packet->pos++];
+	n += (uint16)packet->buffer[packet->pos++] << 8;
+	return n;
+}
+
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
+{
+	uint32 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint32)packet->buffer[packet->pos++];
+	n += (uint32)packet->buffer[packet->pos++] << 8;
+	n += (uint32)packet->buffer[packet->pos++] << 16;
+	n += (uint32)packet->buffer[packet->pos++] << 24;
+	return n;
+}
+
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
+{
+	uint64 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint64)packet->buffer[packet->pos++];
+	n += (uint64)packet->buffer[packet->pos++] << 8;
+	n += (uint64)packet->buffer[packet->pos++] << 16;
+	n += (uint64)packet->buffer[packet->pos++] << 24;
+	n += (uint64)packet->buffer[packet->pos++] << 32;
+	n += (uint64)packet->buffer[packet->pos++] << 40;
+	n += (uint64)packet->buffer[packet->pos++] << 48;
+	n += (uint64)packet->buffer[packet->pos++] << 56;
+	return n;
+}
+
+/** Reads a string till it finds a '\0' in the stream */
+void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
+{
+	PacketSize pos;
+	char *bufp = buffer;
+
+	/* Don't allow reading from a closed socket */
+	if (HasClientQuit(cs)) return;
+
+	pos = p->pos;
+	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
+
+	if (size == 0 || pos == p->size) {
+		*buffer = '\0';
+		/* If size was sooner to zero then the string in the stream
+		 *  skip till the \0, so than packet can be read out correctly for the rest */
+		while (pos < p->size && p->buffer[pos] != '\0') pos++;
+		pos++;
+	}
+	p->pos = pos;
+
+	str_validate(bufp);
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/packet.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,67 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_PACKET_H
+#define NETWORK_CORE_PACKET_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+typedef struct NetworkClientState NetworkClientState;
+
+/**
+ * Queries the network client state struct to determine whether
+ * the client has quit. It indirectly also queries whether the
+ * packet is corrupt as the connection will be closed if it is
+ * reading beyond the boundary of the received packet.
+ * @param cs the state to query
+ * @param true if the connection should be considered dropped
+ */
+bool HasClientQuit(NetworkClientState *cs);
+
+typedef uint16 PacketSize; ///< Size of the whole packet.
+typedef uint8  PacketType; ///< Identifier for the packet
+
+/**
+ * Internal entity of a packet. As everything is sent as a packet,
+ * all network communication will need to call the functions that
+ * populate the packet.
+ * Every packet can be at most SEND_MTU bytes. Overflowing this
+ * limit will give an assertion when sending (i.e. writing) the
+ * packet. Reading past the size of the packet when receiving
+ * will return all 0 values and "" in case of the string.
+ */
+typedef struct Packet {
+	/** The next packet. Used for queueing packets before sending. */
+	struct Packet *next;
+	/** The size of the whole packet for received packets. For packets
+	 * that will be sent, the value is filled in just before the
+	 * actual transmission. */
+	PacketSize size;
+	/** The current read/write position in the packet */
+	PacketSize pos;
+	/** The buffer of this packet */
+	byte buffer[SEND_MTU];
+} Packet;
+
+
+Packet *NetworkSend_Init(PacketType type);
+void NetworkSend_FillPacketSize(Packet *packet);
+void NetworkSend_uint8 (Packet *packet, uint8 data);
+void NetworkSend_uint16(Packet *packet, uint16 data);
+void NetworkSend_uint32(Packet *packet, uint32 data);
+void NetworkSend_uint64(Packet *packet, uint64 data);
+void NetworkSend_string(Packet *packet, const char* data);
+
+void NetworkRecv_ReadPacketSize(Packet *packet);
+uint8  NetworkRecv_uint8 (NetworkClientState *cs, Packet *packet);
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet);
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet);
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet);
+void   NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_PACKET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/tcp.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../debug.h"
+#include "../../openttd.h"
+#include "../../variables.h"
+#include "../../table/strings.h"
+#include "../../functions.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+#include "../network_data.h"
+#include "tcp.h"
+
+/**
+ * @file tcp.c Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
+ *  A socket can make errors. When that happens this handles what to do.
+ * For clients: close connection and drop back to main-menu
+ * For servers: close connection and that is it
+ * @param cs the client to close the connection of
+ * @return the new status
+ */
+NetworkRecvStatus CloseConnection(NetworkClientState *cs)
+{
+	NetworkCloseClient(cs);
+
+	/* Clients drop back to the main menu */
+	if (!_network_server && _networking) {
+		_switch_mode = SM_MENU;
+		_networking = false;
+		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
+
+		return NETWORK_RECV_STATUS_CONN_LOST;
+	}
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+/**
+ * Whether the client has quit or not (used in packet.c)
+ * @param cs the client to check
+ * @return true if the client has quit
+ */
+bool HasClientQuit(NetworkClientState *cs)
+{
+	return cs->has_quit;
+}
+
+/**
+ * This function puts the packet in the send-queue and it is send as
+ * soon as possible. This is the next tick, or maybe one tick later
+ * if the OS-network-buffer is full)
+ * @param packet the packet to send
+ * @param cs     the client to send to
+ */
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
+{
+	Packet *p;
+	assert(packet != NULL);
+
+	packet->pos = 0;
+	packet->next = NULL;
+
+	NetworkSend_FillPacketSize(packet);
+
+	/* Locate last packet buffered for the client */
+	p = cs->packet_queue;
+	if (p == NULL) {
+		/* No packets yet */
+		cs->packet_queue = packet;
+	} else {
+		/* Skip to the last packet */
+		while (p->next != NULL) p = p->next;
+		p->next = packet;
+	}
+}
+
+/**
+ * Sends all the buffered packets out for this client. It stops when:
+ *   1) all packets are send (queue is empty)
+ *   2) the OS reports back that it can not send any more
+ *      data right now (full network-buffer, it happens ;))
+ *   3) sending took too long
+ * @param cs the client to send the packets for
+ */
+bool NetworkSend_Packets(NetworkClientState *cs)
+{
+	ssize_t res;
+	Packet *p;
+
+	/* We can not write to this socket!! */
+	if (!cs->writable) return false;
+	if (cs->socket == INVALID_SOCKET) return false;
+
+	p = cs->packet_queue;
+	while (p != NULL) {
+		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+		if (res == -1) {
+			int err = GET_LAST_ERROR();
+			if (err != EWOULDBLOCK) {
+				/* Something went wrong.. close client! */
+				DEBUG(net, 0, "send failed with error %d", err);
+				CloseConnection(cs);
+				return false;
+			}
+			return true;
+		}
+		if (res == 0) {
+			/* Client/server has left us :( */
+			CloseConnection(cs);
+			return false;
+		}
+
+		p->pos += res;
+
+		/* Is this packet sent? */
+		if (p->pos == p->size) {
+			/* Go to the next packet */
+			cs->packet_queue = p->next;
+			free(p);
+			p = cs->packet_queue;
+		} else {
+			return true;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * Receives a packet for the given client
+ * @param cs     the client to (try to) receive a packet for
+ * @param status the variable to store the status into
+ * @return the received packet (or NULL when it didn't receive one)
+ */
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
+{
+	ssize_t res;
+	Packet *p;
+
+	*status = NETWORK_RECV_STATUS_OKAY;
+
+	if (cs->socket == INVALID_SOCKET) return NULL;
+
+	if (cs->packet_recv == NULL) {
+		cs->packet_recv = malloc(sizeof(Packet));
+		if (cs->packet_recv == NULL) error("Failed to allocate packet");
+		/* Set pos to zero! */
+		cs->packet_recv->pos = 0;
+		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
+	}
+
+	p = cs->packet_recv;
+
+	/* Read packet size */
+	if (p->pos < sizeof(PacketSize)) {
+		while (p->pos < sizeof(PacketSize)) {
+			/* Read the size of the packet */
+			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
+			if (res == -1) {
+				int err = GET_LAST_ERROR();
+				if (err != EWOULDBLOCK) {
+					/* Something went wrong... (104 is connection reset by peer) */
+					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+					*status = CloseConnection(cs);
+					return NULL;
+				}
+				/* Connection would block, so stop for now */
+				return NULL;
+			}
+			if (res == 0) {
+				/* Client/server has left */
+				*status = CloseConnection(cs);
+				return NULL;
+			}
+			p->pos += res;
+		}
+
+		NetworkRecv_ReadPacketSize(p);
+
+		if (p->size > SEND_MTU) {
+			*status = CloseConnection(cs);
+			return NULL;
+		}
+	}
+
+	/* Read rest of packet */
+	while (p->pos < p->size) {
+		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+		if (res == -1) {
+			int err = GET_LAST_ERROR();
+			if (err != EWOULDBLOCK) {
+				/* Something went wrong... (104 is connection reset by peer) */
+				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+				*status = CloseConnection(cs);
+				return NULL;
+			}
+			/* Connection would block */
+			return NULL;
+		}
+		if (res == 0) {
+			/* Client/server has left */
+			*status = CloseConnection(cs);
+			return NULL;
+		}
+
+		p->pos += res;
+	}
+
+	/* We have a complete packet, return it! */
+	p->pos = 2;
+	p->next = NULL; // Should not be needed, but who knows...
+
+	/* Prepare for receiving a new packet */
+	cs->packet_recv = NULL;
+
+	return p;
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/tcp.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,60 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_TCP_H
+#define NETWORK_CORE_TCP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file tcp.h Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Enum with all types of UDP packets.
+ * The order of the first 4 packets MUST not be changed, as
+ * it protects old clients from joining newer servers
+ * (because SERVER_ERROR is the respond to a wrong revision)
+ */
+enum {
+	PACKET_SERVER_FULL,
+	PACKET_SERVER_BANNED,
+	PACKET_CLIENT_JOIN,
+	PACKET_SERVER_ERROR,
+	PACKET_CLIENT_COMPANY_INFO,
+	PACKET_SERVER_COMPANY_INFO,
+	PACKET_SERVER_CLIENT_INFO,
+	PACKET_SERVER_NEED_PASSWORD,
+	PACKET_CLIENT_PASSWORD,
+	PACKET_SERVER_WELCOME,
+	PACKET_CLIENT_GETMAP,
+	PACKET_SERVER_WAIT,
+	PACKET_SERVER_MAP,
+	PACKET_CLIENT_MAP_OK,
+	PACKET_SERVER_JOIN,
+	PACKET_SERVER_FRAME,
+	PACKET_SERVER_SYNC,
+	PACKET_CLIENT_ACK,
+	PACKET_CLIENT_COMMAND,
+	PACKET_SERVER_COMMAND,
+	PACKET_CLIENT_CHAT,
+	PACKET_SERVER_CHAT,
+	PACKET_CLIENT_SET_PASSWORD,
+	PACKET_CLIENT_SET_NAME,
+	PACKET_CLIENT_QUIT,
+	PACKET_CLIENT_ERROR,
+	PACKET_SERVER_QUIT,
+	PACKET_SERVER_ERROR_QUIT,
+	PACKET_SERVER_SHUTDOWN,
+	PACKET_SERVER_NEWGAME,
+	PACKET_SERVER_RCON,
+	PACKET_CLIENT_RCON,
+	PACKET_END                   ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs);
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status);
+bool NetworkSend_Packets(NetworkClientState *cs);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_TCP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/udp.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../date.h"
+#include "../../debug.h"
+#include "../../macros.h"
+#include "../../newgrf_config.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "game.h"
+#include "packet.h"
+#include "udp.h"
+
+/**
+ * @file udp.c Basic functions to receive and send UDP packets.
+ */
+
+/**
+ * Send a packet over UDP
+ * @param udp  the socket to send over
+ * @param p    the packet to send
+ * @param recv the receiver (target) of the packet
+ */
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
+{
+	int res;
+
+	NetworkSend_FillPacketSize(p);
+
+	/* Send the buffer */
+	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
+
+	/* Check for any errors, but ignore it otherwise */
+	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
+}
+
+/**
+ * Start listening on the given host and port.
+ * @param udp       the place where the (references to the) UDP are stored
+ * @param host      the host (ip) to listen on
+ * @param port      the port to listen on
+ * @param broadcast whether to allow broadcast sending/receiving
+ * @return true if the listening succeeded
+ */
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
+{
+	struct sockaddr_in sin;
+
+	/* Make sure socket is closed */
+	closesocket(*udp);
+
+	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (*udp == INVALID_SOCKET) {
+		DEBUG(net, 0, "[udp] failed to start UDP listener");
+		return false;
+	}
+
+	/* set nonblocking mode for socket */
+	{
+		unsigned long blocking = 1;
+#ifndef BEOS_NET_SERVER
+		ioctlsocket(*udp, FIONBIO, &blocking);
+#else
+		setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL);
+#endif
+	}
+
+	sin.sin_family = AF_INET;
+	/* Listen on all IPs */
+	sin.sin_addr.s_addr = host;
+	sin.sin_port = htons(port);
+
+	if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+		DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
+		return false;
+	}
+
+	if (broadcast) {
+		/* Enable broadcast */
+		unsigned long val = 1;
+#ifndef BEOS_NET_SERVER // will work around this, some day; maybe.
+		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
+#endif
+	}
+
+	DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
+
+	return true;
+}
+
+/**
+ * Receive a packet at UDP level
+ * @param udp the socket to receive the packet on
+ */
+void NetworkUDPReceive(SOCKET udp)
+{
+	struct sockaddr_in client_addr;
+	socklen_t client_len;
+	int nbytes;
+	Packet p;
+	int packet_len;
+
+	packet_len = sizeof(p.buffer);
+	client_len = sizeof(client_addr);
+
+	/* Try to receive anything */
+	nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
+
+	/* We got some bytes for the base header of the packet.
+	 * Assume we received the whole packet. */
+	if (nbytes > 2) {
+		NetworkRecv_ReadPacketSize(&p);
+
+		/* Put the position on the right place */
+		p.pos = 2;
+		p.next = NULL;
+
+		/* Handle the packet */
+		NetworkHandleUDPPacket(&p, &client_addr);
+	}
+}
+
+
+/**
+ * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
+ * @param p the packet to write the data to
+ * @param c the configuration to write the GRF ID and MD5 checksum from
+ */
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c)
+{
+	uint j;
+	NetworkSend_uint32(p, c->grfid);
+	for (j = 0; j < sizeof(c->md5sum); j++) {
+		NetworkSend_uint8 (p, c->md5sum[j]);
+	}
+}
+
+/**
+ * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
+ * @param cs the client state (for closing connect on out-of-bounds reading etc)
+ * @param p  the packet to read the data from
+ * @param c  the configuration to write the GRF ID and MD5 checksum to
+ */
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c)
+{
+	uint j;
+	c->grfid = NetworkRecv_uint32(cs, p);
+	for (j = 0; j < sizeof(c->md5sum); j++) {
+		c->md5sum[j] = NetworkRecv_uint8(cs, p);
+	}
+}
+
+
+/**
+ * Serializes the NetworkGameInfo struct to the packet
+ * @param p    the packet to write the data to
+ * @param info the NetworkGameInfo struct to serialize
+ */
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info)
+{
+	NetworkSend_uint8 (p, NETWORK_GAME_INFO_VERSION);
+
+	/*
+	 *              Please observe the order.
+	 * The parts must be read in the same order as they are sent!
+	 */
+
+
+	/* NETWORK_GAME_INFO_VERSION = 4 */
+	{
+		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
+		 * the GRFs that are needed, i.e. the ones that the server has
+		 * selected in the NewGRF GUI and not the ones that are used due
+		 * to the fact that they are in [newgrf-static] in openttd.cfg */
+		const GRFConfig *c;
+		uint count = 0;
+
+		/* Count number of GRFs to send information about */
+		for (c = info->grfconfig; c != NULL; c = c->next) {
+			if (!HASBIT(c->flags, GCF_STATIC)) count++;
+		}
+		NetworkSend_uint8 (p, count); // Send number of GRFs
+
+		/* Send actual GRF Identifications */
+		for (c = info->grfconfig; c != NULL; c = c->next) {
+			if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(p, c);
+		}
+	}
+
+	/* NETWORK_GAME_INFO_VERSION = 3 */
+	NetworkSend_uint32(p, info->game_date);
+	NetworkSend_uint32(p, info->start_date);
+
+	/* NETWORK_GAME_INFO_VERSION = 2 */
+	NetworkSend_uint8 (p, info->companies_max);
+	NetworkSend_uint8 (p, info->companies_on);
+	NetworkSend_uint8 (p, info->spectators_max);
+
+	/* NETWORK_GAME_INFO_VERSION = 1 */
+	NetworkSend_string(p, info->server_name);
+	NetworkSend_string(p, info->server_revision);
+	NetworkSend_uint8 (p, info->server_lang);
+	NetworkSend_uint8 (p, info->use_password);
+	NetworkSend_uint8 (p, info->clients_max);
+	NetworkSend_uint8 (p, info->clients_on);
+	NetworkSend_uint8 (p, info->spectators_on);
+	NetworkSend_string(p, info->map_name);
+	NetworkSend_uint16(p, info->map_width);
+	NetworkSend_uint16(p, info->map_height);
+	NetworkSend_uint8 (p, info->map_set);
+	NetworkSend_uint8 (p, info->dedicated);
+}
+
+/**
+ * Deserializes the NetworkGameInfo struct from the packet
+ * @param cs   the client state (for closing connect on out-of-bounds reading etc)
+ * @param p    the packet to read the data from
+ * @param info the NetworkGameInfo to deserialize into
+ */
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info)
+{
+	info->game_info_version = NetworkRecv_uint8(cs, p);
+
+	/*
+	 *              Please observe the order.
+	 * The parts must be read in the same order as they are sent!
+	 */
+
+	switch (info->game_info_version) {
+		case 4: {
+			GRFConfig *c, **dst = &info->grfconfig;
+			uint i;
+			uint num_grfs = NetworkRecv_uint8(cs, p);
+
+			for (i = 0; i < num_grfs; i++) {
+				c = calloc(1, sizeof(*c));
+				NetworkRecv_GRFIdentifier(cs, p, c);
+				HandleIncomingNetworkGameInfoGRFConfig(c);
+
+				/* Append GRFConfig to the list */
+				*dst = c;
+				dst = &c->next;
+			}
+		} /* Fallthrough */
+		case 3:
+			info->game_date      = NetworkRecv_uint32(cs, p);
+			info->start_date     = NetworkRecv_uint32(cs, p);
+			/* Fallthrough */
+		case 2:
+			info->companies_max  = NetworkRecv_uint8 (cs, p);
+			info->companies_on   = NetworkRecv_uint8 (cs, p);
+			info->spectators_max = NetworkRecv_uint8 (cs, p);
+			/* Fallthrough */
+		case 1:
+			NetworkRecv_string(cs, p, info->server_name,     sizeof(info->server_name));
+			NetworkRecv_string(cs, p, info->server_revision, sizeof(info->server_revision));
+			info->server_lang    = NetworkRecv_uint8 (cs, p);
+			info->use_password   = NetworkRecv_uint8 (cs, p);
+			info->clients_max    = NetworkRecv_uint8 (cs, p);
+			info->clients_on     = NetworkRecv_uint8 (cs, p);
+			info->spectators_on  = NetworkRecv_uint8 (cs, p);
+			if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
+				info->game_date    = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+				info->start_date   = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+			}
+			NetworkRecv_string(cs, p, info->map_name, sizeof(info->map_name));
+			info->map_width      = NetworkRecv_uint16(cs, p);
+			info->map_height     = NetworkRecv_uint16(cs, p);
+			info->map_set        = NetworkRecv_uint8 (cs, p);
+			info->dedicated      = NetworkRecv_uint8 (cs, p);
+	}
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/core/udp.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_UDP_H
+#define NETWORK_CORE_UDP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file udp.h Basic functions to receive and send UDP packets.
+ */
+
+///** Sending/receiving of UDP packets **////
+
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv);
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast);
+void NetworkUDPReceive(SOCKET udp);
+
+/**
+ * Function that is called for every received UDP packet.
+ * @param packet      the received packet
+ * @param client_addr the address of the sender of the packet
+ */
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+
+
+///** Sending/receiving of (large) chuncks of UDP packets **////
+
+
+/** Enum with all types of UDP packets. The order MUST not be changed **/
+enum {
+	PACKET_UDP_CLIENT_FIND_SERVER,   ///< Queries a game server for game information
+	PACKET_UDP_SERVER_RESPONSE,      ///< Reply of the game server with game information
+	PACKET_UDP_CLIENT_DETAIL_INFO,   ///< Queries a game server about details of the game, such as companies
+	PACKET_UDP_SERVER_DETAIL_INFO,   ///< Reply of the game server about details of the game, such as companies
+	PACKET_UDP_SERVER_REGISTER,      ///< Packet to register itself to the master server
+	PACKET_UDP_MASTER_ACK_REGISTER,  ///< Packet indicating registration has succedeed
+	PACKET_UDP_CLIENT_GET_LIST,      ///< Request for serverlist from master server
+	PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's
+	PACKET_UDP_SERVER_UNREGISTER,    ///< Request to be removed from the server-list
+	PACKET_UDP_CLIENT_GET_NEWGRFS,   ///< Requests the name for a list of GRFs (GRF_ID and MD5)
+	PACKET_UDP_SERVER_NEWGRFS,       ///< Sends the list of NewGRF's requested.
+	PACKET_UDP_END                   ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c);
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info);
+
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c);
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info);
+
+/**
+ * Function that is called for every GRFConfig that is read when receiving
+ * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
+ * function must set all appropriate fields. This GRF is later appended to
+ * the grfconfig list of the NetworkGameInfo.
+ * @param config the GRF to handle
+ */
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_UDP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,1451 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+#include "network_data.h"
+
+#if defined(WITH_REV)
+	extern const char _openttd_revision[];
+#elif defined(WITH_REV_HACK)
+	#define WITH_REV
+	const char _openttd_revision[] = WITH_REV_HACK;
+#else
+	const char _openttd_revision[] = NOREV_STRING;
+#endif
+
+
+#ifdef ENABLE_NETWORK
+
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../map.h"
+#include "../command.h"
+#include "../variables.h"
+#include "../date.h"
+#include "../newgrf_config.h"
+#include "../table/strings.h"
+#include "network_client.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "network_gamelist.h"
+#include "core/udp.h"
+#include "core/tcp.h"
+#include "network_gui.h"
+#include "../console.h" /* IConsoleCmdExec */
+#include <stdarg.h> /* va_list */
+#include "../md5.h"
+
+#ifdef __MORPHOS__
+// the library base is required here
+struct Library *SocketBase = NULL;
+#endif
+
+// The listen socket for the server
+static SOCKET _listensocket;
+
+// The amount of clients connected
+static byte _network_clients_connected = 0;
+// The index counter for new clients (is never decreased)
+static uint16 _network_client_index = NETWORK_SERVER_INDEX + 1;
+
+/* Some externs / forwards */
+extern void StateGameLoop(void);
+
+// Function that looks up the CI for a given client-index
+NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index)
+{
+	NetworkClientInfo *ci;
+
+	for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
+		if (ci->client_index == client_index) return ci;
+	}
+
+	return NULL;
+}
+
+/** Return the CI for a given IP
+ * @param ip IP of the client we are looking for. This must be in string-format
+ * @return return a pointer to the corresponding NetworkClientInfo struct or NULL on failure */
+NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip)
+{
+	NetworkClientInfo *ci;
+	uint32 ip_number = inet_addr(ip);
+
+	for (ci = _network_client_info; ci != endof(_network_client_info); ci++) {
+		if (ci->client_ip == ip_number) return ci;
+	}
+
+	return NULL;
+}
+
+// Function that looks up the CS for a given client-index
+NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index)
+{
+	NetworkClientState *cs;
+
+	for (cs = _clients; cs != &_clients[MAX_CLIENT_INFO]; cs++) {
+		if (cs->index == client_index) return cs;
+	}
+
+	return NULL;
+}
+
+// NetworkGetClientName is a server-safe function to get the name of the client
+//  if the user did not send it yet, Client #<no> is used.
+void NetworkGetClientName(char *client_name, size_t size, const NetworkClientState *cs)
+{
+	const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+
+	if (ci->client_name[0] == '\0') {
+		snprintf(client_name, size, "Client #%4d", cs->index);
+	} else {
+		ttd_strlcpy(client_name, ci->client_name, size);
+	}
+}
+
+byte NetworkSpectatorCount(void)
+{
+	const NetworkClientState *cs;
+	byte count = 0;
+
+	FOR_ALL_CLIENTS(cs) {
+		if (DEREF_CLIENT_INFO(cs)->client_playas == PLAYER_SPECTATOR) count++;
+	}
+
+	return count;
+}
+
+// This puts a text-message to the console, or in the future, the chat-box,
+//  (to keep it all a bit more general)
+// If 'self_send' is true, this is the client who is sending the message
+void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...)
+{
+	char buf[1024];
+	va_list va;
+	const int duration = 10; // Game days the messages stay visible
+	char message[1024];
+	char temp[1024];
+
+	va_start(va, str);
+	vsnprintf(buf, lengthof(buf), str, va);
+	va_end(va);
+
+	switch (action) {
+		case NETWORK_ACTION_SERVER_MESSAGE:
+			color = 1;
+			snprintf(message, sizeof(message), "*** %s", buf);
+			break;
+		case NETWORK_ACTION_JOIN:
+			color = 1;
+			GetString(temp, STR_NETWORK_CLIENT_JOINED, lastof(temp));
+			snprintf(message, sizeof(message), "*** %s %s", name, temp);
+			break;
+		case NETWORK_ACTION_LEAVE:
+			color = 1;
+			GetString(temp, STR_NETWORK_ERR_LEFT, lastof(temp));
+			snprintf(message, sizeof(message), "*** %s %s (%s)", name, temp, buf);
+			break;
+		case NETWORK_ACTION_GIVE_MONEY:
+			if (self_send) {
+				SetDParamStr(0, name);
+				SetDParam(1, atoi(buf));
+				GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY, lastof(temp));
+				snprintf(message, sizeof(message), "*** %s", temp);
+			} else {
+				SetDParam(0, atoi(buf));
+				GetString(temp, STR_NETWORK_GIVE_MONEY, lastof(temp));
+				snprintf(message, sizeof(message), "*** %s %s", name, temp);
+			}
+			break;
+		case NETWORK_ACTION_NAME_CHANGE:
+			GetString(temp, STR_NETWORK_NAME_CHANGE, lastof(temp));
+			snprintf(message, sizeof(message), "*** %s %s %s", name, temp, buf);
+			break;
+		case NETWORK_ACTION_CHAT_COMPANY:
+			SetDParamStr(0, name);
+			SetDParamStr(1, buf);
+			GetString(temp, self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY, lastof(temp));
+			ttd_strlcpy(message, temp, sizeof(message));
+			break;
+		case NETWORK_ACTION_CHAT_CLIENT:
+			SetDParamStr(0, name);
+			SetDParamStr(1, buf);
+			GetString(temp, self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT, lastof(temp));
+			ttd_strlcpy(message, temp, sizeof(message));
+			break;
+		default:
+			SetDParamStr(0, name);
+			SetDParamStr(1, buf);
+			GetString(temp, STR_NETWORK_CHAT_ALL, lastof(temp));
+			ttd_strlcpy(message, temp, sizeof(message));
+			break;
+	}
+
+	IConsolePrintF(color, "%s", message);
+	AddTextMessage(color, duration, "%s", message);
+}
+
+// Calculate the frame-lag of a client
+uint NetworkCalculateLag(const NetworkClientState *cs)
+{
+	int lag = cs->last_frame_server - cs->last_frame;
+	// This client has missed his ACK packet after 1 DAY_TICKS..
+	//  so we increase his lag for every frame that passes!
+	// The packet can be out by a max of _net_frame_freq
+	if (cs->last_frame_server + DAY_TICKS + _network_frame_freq < _frame_counter)
+		lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _network_frame_freq);
+
+	return lag;
+}
+
+
+// There was a non-recoverable error, drop back to the main menu with a nice
+//  error
+static void NetworkError(StringID error_string)
+{
+	_switch_mode = SM_MENU;
+	_switch_mode_errorstr = error_string;
+}
+
+static void ClientStartError(const char *error)
+{
+	DEBUG(net, 0, "[client] could not start network: %s",error);
+	NetworkError(STR_NETWORK_ERR_CLIENT_START);
+}
+
+static void ServerStartError(const char *error)
+{
+	DEBUG(net, 0, "[server] could not start network: %s",error);
+	NetworkError(STR_NETWORK_ERR_SERVER_START);
+}
+
+static void NetworkClientError(NetworkRecvStatus res, NetworkClientState* cs)
+{
+	// First, send a CLIENT_ERROR to the server, so he knows we are
+	//  disconnection (and why!)
+	NetworkErrorCode errorno;
+
+	// We just want to close the connection..
+	if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
+		cs->has_quit = true;
+		NetworkCloseClient(cs);
+		_networking = false;
+
+		DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+		return;
+	}
+
+	switch (res) {
+		case NETWORK_RECV_STATUS_DESYNC:   errorno = NETWORK_ERROR_DESYNC; break;
+		case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
+		default:                           errorno = NETWORK_ERROR_GENERAL; break;
+	}
+	// This means we fucked up and the server closed the connection
+	if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
+			res != NETWORK_RECV_STATUS_SERVER_BANNED) {
+		SEND_COMMAND(PACKET_CLIENT_ERROR)(errorno);
+
+		// Dequeue all commands before closing the socket
+		NetworkSend_Packets(DEREF_CLIENT(0));
+	}
+
+	_switch_mode = SM_MENU;
+	NetworkCloseClient(cs);
+	_networking = false;
+}
+
+/** Retrieve a string representation of an internal error number
+ * @param buf buffer where the error message will be stored
+ * @param err NetworkErrorCode
+ * @return returns a pointer to the error message (buf) */
+char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last)
+{
+	/* List of possible network errors, used by
+	 * PACKET_SERVER_ERROR and PACKET_CLIENT_ERROR */
+	static const StringID network_error_strings[] = {
+		STR_NETWORK_ERR_CLIENT_GENERAL,
+		STR_NETWORK_ERR_CLIENT_DESYNC,
+		STR_NETWORK_ERR_CLIENT_SAVEGAME,
+		STR_NETWORK_ERR_CLIENT_CONNECTION_LOST,
+		STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR,
+		STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED,
+		STR_NETWORK_ERR_CLIENT_NOT_EXPECTED,
+		STR_NETWORK_ERR_CLIENT_WRONG_REVISION,
+		STR_NETWORK_ERR_CLIENT_NAME_IN_USE,
+		STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD,
+		STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH,
+		STR_NETWORK_ERR_CLIENT_KICKED,
+		STR_NETWORK_ERR_CLIENT_CHEATER,
+		STR_NETWORK_ERR_CLIENT_SERVER_FULL
+	};
+
+	if (err >= lengthof(network_error_strings)) err = 0;
+
+	return GetString(buf, network_error_strings[err], last);
+}
+
+/* Count the number of active clients connected */
+static uint NetworkCountPlayers(void)
+{
+	const NetworkClientState *cs;
+	uint count = 0;
+
+	FOR_ALL_CLIENTS(cs) {
+		const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+		if (IsValidPlayer(ci->client_playas)) count++;
+	}
+
+	return count;
+}
+
+static bool _min_players_paused = false;
+
+/* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
+void CheckMinPlayers(void)
+{
+	if (!_network_dedicated) return;
+
+	if (NetworkCountPlayers() < _network_min_players) {
+		if (_min_players_paused) return;
+
+		_min_players_paused = true;
+		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX);
+	} else {
+		if (!_min_players_paused) return;
+
+		_min_players_paused = false;
+		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX);
+	}
+}
+
+// Find all IP-aliases for this host
+static void NetworkFindIPs(void)
+{
+	int i;
+
+#if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
+	/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
+	int _netstat(int fd, char **output, int verbose);
+
+	int seek_past_header(char **pos, const char *header) {
+		char *new_pos = strstr(*pos, header);
+		if (new_pos == 0) {
+			return B_ERROR;
+		}
+		*pos += strlen(header) + new_pos - *pos + 1;
+		return B_OK;
+	}
+
+	int output_length;
+	char *output_pointer = NULL;
+	char **output;
+	int sock = socket(AF_INET, SOCK_DGRAM, 0);
+	i = 0;
+
+	// If something fails, make sure the list is empty
+	_broadcast_list[0] = 0;
+
+	if (sock < 0) {
+		DEBUG(net, 0, "[core] error creating socket");
+		return;
+	}
+
+	output_length = _netstat(sock, &output_pointer, 1);
+	if (output_length < 0) {
+		DEBUG(net, 0, "[core] error running _netstat");
+		return;
+	}
+
+	output = &output_pointer;
+	if (seek_past_header(output, "IP Interfaces:") == B_OK) {
+		for (;;) {
+			uint32 n, fields, read;
+			uint8 i1, i2, i3, i4, j1, j2, j3, j4;
+			struct in_addr inaddr;
+			uint32 ip;
+			uint32 netmask;
+
+			fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
+												&n, &i1,&i2,&i3,&i4, &j1,&j2,&j3,&j4, &read);
+			read += 1;
+			if (fields != 9) {
+				break;
+			}
+
+			ip      = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
+			netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
+
+			if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
+				inaddr.s_addr = htonl(ip | ~netmask);
+				_broadcast_list[i] = inaddr.s_addr;
+				i++;
+			}
+			if (read < 0) {
+				break;
+			}
+			*output += read;
+		}
+		/* XXX - Using either one of these crashes openttd heavily? - wber */
+		/*free(output_pointer);*/
+		/*free(output);*/
+		closesocket(sock);
+	}
+#elif defined(HAVE_GETIFADDRS)
+	struct ifaddrs *ifap, *ifa;
+
+	// If something fails, make sure the list is empty
+	_broadcast_list[0] = 0;
+
+	if (getifaddrs(&ifap) != 0)
+		return;
+
+	i = 0;
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+		if (!(ifa->ifa_flags & IFF_BROADCAST)) continue;
+		if (ifa->ifa_broadaddr == NULL) continue;
+		if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
+		_broadcast_list[i] = ((struct sockaddr_in*)ifa->ifa_broadaddr)->sin_addr.s_addr;
+		i++;
+	}
+	freeifaddrs(ifap);
+
+#else /* not HAVE_GETIFADDRS */
+	SOCKET sock;
+#ifdef WIN32
+	DWORD len = 0;
+	INTERFACE_INFO ifo[MAX_INTERFACES];
+	uint j;
+#else
+	char buf[4 * 1024]; // Arbitrary buffer size
+	struct ifconf ifconf;
+	const char* buf_end;
+	const char* p;
+#endif
+
+	// If something fails, make sure the list is empty
+	_broadcast_list[0] = 0;
+
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock == INVALID_SOCKET) return;
+
+#ifdef WIN32
+	memset(&ifo[0], 0, sizeof(ifo));
+	if ((WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &ifo[0], sizeof(ifo), &len, NULL, NULL)) != 0) {
+		closesocket(sock);
+		return;
+	}
+
+	i = 0;
+	for (j = 0; j < len / sizeof(*ifo); j++) {
+		if (ifo[j].iiFlags & IFF_LOOPBACK) continue;
+		if (!(ifo[j].iiFlags & IFF_BROADCAST)) continue;
+		/* iiBroadcast is unusable, because it always seems to be set to
+		 * 255.255.255.255.
+		 */
+		_broadcast_list[i++] =
+			 ifo[j].iiAddress.AddressIn.sin_addr.s_addr |
+			~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
+	}
+#else
+	ifconf.ifc_len = sizeof(buf);
+	ifconf.ifc_buf = buf;
+	if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) {
+		closesocket(sock);
+		return;
+	}
+
+	i = 0;
+	buf_end = buf + ifconf.ifc_len;
+	for (p = buf; p < buf_end;) {
+		const struct ifreq* req = (const struct ifreq*)p;
+
+		if (req->ifr_addr.sa_family == AF_INET) {
+			struct ifreq r;
+
+			strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name));
+			if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 &&
+					r.ifr_flags & IFF_BROADCAST &&
+					ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
+				_broadcast_list[i++] =
+					((struct sockaddr_in*)&r.ifr_broadaddr)->sin_addr.s_addr;
+			}
+		}
+
+		p += sizeof(struct ifreq);
+#ifdef AF_LINK
+		p += req->ifr_addr.sa_len - sizeof(struct sockaddr);
+#endif
+	}
+#endif
+
+	closesocket(sock);
+#endif /* not HAVE_GETIFADDRS */
+
+	_broadcast_list[i] = 0;
+
+	DEBUG(net, 3, "Detected broadcast addresses:");
+	// Now display to the debug all the detected ips
+	for (i = 0; _broadcast_list[i] != 0; i++) {
+		DEBUG(net, 3, "%d) %s", i, inet_ntoa(*(struct in_addr *)&_broadcast_list[i]));//inet_ntoa(inaddr));
+	}
+}
+
+// Resolve a hostname to a inet_addr
+unsigned long NetworkResolveHost(const char *hostname)
+{
+	in_addr_t ip;
+
+	// First try: is it an ip address?
+	ip = inet_addr(hostname);
+
+	// If not try to resolve the name
+	if (ip == INADDR_NONE) {
+		struct hostent *he = gethostbyname(hostname);
+		if (he == NULL) {
+			DEBUG(net, 0, "Cannot resolve '%s'", hostname);
+		} else {
+			struct in_addr addr = *(struct in_addr *)he->h_addr_list[0];
+			DEBUG(net, 1, "Resolved '%s' to %s", hostname, inet_ntoa(addr));
+			ip = addr.s_addr;
+		}
+	}
+	return ip;
+}
+
+// Converts a string to ip/port/player
+//  Format: IP#player:port
+//
+// connection_string will be re-terminated to seperate out the hostname, and player and port will
+// be set to the player and port strings given by the user, inside the memory area originally
+// occupied by connection_string.
+void ParseConnectionString(const char **player, const char **port, char *connection_string)
+{
+	char *p;
+	for (p = connection_string; *p != '\0'; p++) {
+		if (*p == '#') {
+			*p = '\0';
+			*player = ++p;
+			while (IsValidChar(*p, CS_NUMERAL)) p++;
+			if (*p == '\0') break;
+		} else if (*p == ':') {
+			*port = p + 1;
+			*p = '\0';
+		}
+	}
+}
+
+// Creates a new client from a socket
+//   Used both by the server and the client
+static NetworkClientState *NetworkAllocClient(SOCKET s)
+{
+	NetworkClientState *cs;
+	byte client_no = 0;
+
+	if (_network_server) {
+		// Can we handle a new client?
+		if (_network_clients_connected >= MAX_CLIENTS) return NULL;
+		if (_network_game_info.clients_on >= _network_game_info.clients_max) return NULL;
+
+		// Register the login
+		client_no = _network_clients_connected++;
+	}
+
+	cs = DEREF_CLIENT(client_no);
+	memset(cs, 0, sizeof(*cs));
+	cs->socket = s;
+	cs->last_frame = 0;
+	cs->has_quit = false;
+
+	cs->last_frame = _frame_counter;
+	cs->last_frame_server = _frame_counter;
+
+	if (_network_server) {
+		NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
+		memset(ci, 0, sizeof(*ci));
+
+		cs->index = _network_client_index++;
+		ci->client_index = cs->index;
+		ci->client_playas = PLAYER_INACTIVE_CLIENT;
+		ci->join_date = _date;
+
+		InvalidateWindow(WC_CLIENT_LIST, 0);
+	}
+
+	return cs;
+}
+
+// Close a connection
+void NetworkCloseClient(NetworkClientState *cs)
+{
+	NetworkClientInfo *ci;
+	// Socket is already dead
+	if (cs->socket == INVALID_SOCKET) {
+		cs->has_quit = true;
+		return;
+	}
+
+	DEBUG(net, 1, "Closed client connection %d", cs->index);
+
+	if (!cs->has_quit && _network_server && cs->status > STATUS_INACTIVE) {
+		// We did not receive a leave message from this client...
+		NetworkErrorCode errorno = NETWORK_ERROR_CONNECTION_LOST;
+		char str[100];
+		char client_name[NETWORK_CLIENT_NAME_LENGTH];
+		NetworkClientState *new_cs;
+
+		NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+		GetNetworkErrorMsg(str, errorno, lastof(str));
+
+		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+		// Inform other clients of this... strange leaving ;)
+		FOR_ALL_CLIENTS(new_cs) {
+			if (new_cs->status > STATUS_AUTH && cs != new_cs) {
+				SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
+			}
+		}
+	}
+
+	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
+	if (cs->status == STATUS_PRE_ACTIVE && _network_pause_on_join) {
+		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX);
+	}
+
+	closesocket(cs->socket);
+	cs->writable = false;
+	cs->has_quit = true;
+
+	// Free all pending and partially received packets
+	while (cs->packet_queue != NULL) {
+		Packet *p = cs->packet_queue->next;
+		free(cs->packet_queue);
+		cs->packet_queue = p;
+	}
+	free(cs->packet_recv);
+	cs->packet_recv = NULL;
+
+	while (cs->command_queue != NULL) {
+		CommandPacket *p = cs->command_queue->next;
+		free(cs->command_queue);
+		cs->command_queue = p;
+	}
+
+	// Close the gap in the client-list
+	ci = DEREF_CLIENT_INFO(cs);
+
+	if (_network_server) {
+		// We just lost one client :(
+		if (cs->status > STATUS_INACTIVE) _network_game_info.clients_on--;
+		_network_clients_connected--;
+
+		while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->socket != INVALID_SOCKET) {
+			*cs = *(cs + 1);
+			*ci = *(ci + 1);
+			cs++;
+			ci++;
+		}
+
+		InvalidateWindow(WC_CLIENT_LIST, 0);
+	}
+
+	// Reset the status of the last socket
+	cs->socket = INVALID_SOCKET;
+	cs->status = STATUS_INACTIVE;
+	cs->index = NETWORK_EMPTY_INDEX;
+	ci->client_index = NETWORK_EMPTY_INDEX;
+
+	CheckMinPlayers();
+}
+
+// A client wants to connect to a server
+static bool NetworkConnect(const char *hostname, int port)
+{
+	SOCKET s;
+	struct sockaddr_in sin;
+
+	DEBUG(net, 1, "Connecting to %s %d", hostname, port);
+
+	s = socket(AF_INET, SOCK_STREAM, 0);
+	if (s == INVALID_SOCKET) {
+		ClientStartError("socket() failed");
+		return false;
+	}
+
+	if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
+
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = NetworkResolveHost(hostname);
+	sin.sin_port = htons(port);
+	_network_last_host_ip = sin.sin_addr.s_addr;
+
+	/* We failed to connect for which reason what so ever */
+	if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) return false;
+
+	if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
+
+	// in client mode, only the first client field is used. it's pointing to the server.
+	NetworkAllocClient(s);
+
+	_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
+	ShowJoinStatusWindow();
+
+	return true;
+}
+
+// For the server, to accept new clients
+static void NetworkAcceptClients(void)
+{
+	struct sockaddr_in sin;
+	NetworkClientState *cs;
+	uint i;
+	bool banned;
+
+	// Should never ever happen.. is it possible??
+	assert(_listensocket != INVALID_SOCKET);
+
+	for (;;) {
+		socklen_t sin_len = sizeof(sin);
+		SOCKET s = accept(_listensocket, (struct sockaddr*)&sin, &sin_len);
+		if (s == INVALID_SOCKET) return;
+
+		SetNonBlocking(s); // XXX error handling?
+
+		DEBUG(net, 1, "Client connected from %s on frame %d", inet_ntoa(sin.sin_addr), _frame_counter);
+
+		SetNoDelay(s); // XXX error handling?
+
+		/* Check if the client is banned */
+		banned = false;
+		for (i = 0; i < lengthof(_network_ban_list); i++) {
+			if (_network_ban_list[i] == NULL) continue;
+
+			if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) {
+				Packet *p = NetworkSend_Init(PACKET_SERVER_BANNED);
+
+				DEBUG(net, 1, "Banned ip tried to join (%s), refused", _network_ban_list[i]);
+
+				p->buffer[0] = p->size & 0xFF;
+				p->buffer[1] = p->size >> 8;
+
+				send(s, p->buffer, p->size, 0);
+				closesocket(s);
+
+				free(p);
+
+				banned = true;
+				break;
+			}
+		}
+		/* If this client is banned, continue with next client */
+		if (banned) continue;
+
+		cs = NetworkAllocClient(s);
+		if (cs == NULL) {
+			// no more clients allowed?
+			// Send to the client that we are full!
+			Packet *p = NetworkSend_Init(PACKET_SERVER_FULL);
+
+			p->buffer[0] = p->size & 0xFF;
+			p->buffer[1] = p->size >> 8;
+
+			send(s, p->buffer, p->size, 0);
+			closesocket(s);
+
+			free(p);
+
+			continue;
+		}
+
+		// a new client has connected. We set him at inactive for now
+		//  maybe he is only requesting server-info. Till he has sent a PACKET_CLIENT_MAP_OK
+		//  the client stays inactive
+		cs->status = STATUS_INACTIVE;
+
+		DEREF_CLIENT_INFO(cs)->client_ip = sin.sin_addr.s_addr; // Save the IP of the client
+	}
+}
+
+// Set up the listen socket for the server
+static bool NetworkListen(void)
+{
+	SOCKET ls;
+	struct sockaddr_in sin;
+
+	DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
+
+	ls = socket(AF_INET, SOCK_STREAM, 0);
+	if (ls == INVALID_SOCKET) {
+		ServerStartError("socket() on listen socket failed");
+		return false;
+	}
+
+	{ // reuse the socket
+		int reuse = 1;
+		// The (const char*) cast is needed for windows!!
+		if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1) {
+			ServerStartError("setsockopt() on listen socket failed");
+			return false;
+		}
+	}
+
+	if (!SetNonBlocking(ls)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
+
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = _network_server_bind_ip;
+	sin.sin_port = htons(_network_server_port);
+
+	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+		ServerStartError("bind() failed");
+		return false;
+	}
+
+	if (listen(ls, 1) != 0) {
+		ServerStartError("listen() failed");
+		return false;
+	}
+
+	_listensocket = ls;
+
+	return true;
+}
+
+// Close all current connections
+static void NetworkClose(void)
+{
+	NetworkClientState *cs;
+
+	FOR_ALL_CLIENTS(cs) {
+		if (!_network_server) {
+			SEND_COMMAND(PACKET_CLIENT_QUIT)("leaving");
+			NetworkSend_Packets(cs);
+		}
+		NetworkCloseClient(cs);
+	}
+
+	if (_network_server) {
+		// We are a server, also close the listensocket
+		closesocket(_listensocket);
+		_listensocket = INVALID_SOCKET;
+		DEBUG(net, 1, "Closed listener");
+		NetworkUDPClose();
+	}
+}
+
+// Inits the network (cleans sockets and stuff)
+static void NetworkInitialize(void)
+{
+	NetworkClientState *cs;
+
+	_local_command_queue = NULL;
+
+	// Clean all client-sockets
+	memset(_clients, 0, sizeof(_clients));
+	for (cs = _clients; cs != &_clients[MAX_CLIENTS]; cs++) {
+		cs->socket = INVALID_SOCKET;
+		cs->status = STATUS_INACTIVE;
+		cs->command_queue = NULL;
+	}
+
+	// Clean the client_info memory
+	memset(&_network_client_info, 0, sizeof(_network_client_info));
+	memset(&_network_player_info, 0, sizeof(_network_player_info));
+
+	_sync_frame = 0;
+	_network_first_time = true;
+
+	_network_reconnect = 0;
+
+	NetworkUDPInitialize();
+}
+
+// Query a server to fetch his game-info
+//  If game_info is true, only the gameinfo is fetched,
+//   else only the client_info is fetched
+NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info)
+{
+	if (!_network_available) return NULL;
+
+	NetworkDisconnect();
+
+	if (game_info) return NetworkUDPQueryServer(host, port);
+
+	NetworkInitialize();
+
+	_network_server = false;
+
+	// Try to connect
+	_networking = NetworkConnect(host, port);
+
+	// We are connected
+	if (_networking) {
+		SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)();
+	} else { // No networking, close everything down again
+		NetworkDisconnect();
+	}
+
+	return NULL;
+}
+
+/* Validates an address entered as a string and adds the server to
+ * the list. If you use this function, the games will be marked
+ * as manually added. */
+void NetworkAddServer(const char *b)
+{
+	if (*b != '\0') {
+		NetworkGameList *item;
+		const char *port = NULL;
+		const char *player = NULL;
+		char host[NETWORK_HOSTNAME_LENGTH];
+		uint16 rport;
+
+		ttd_strlcpy(host, b, lengthof(host));
+
+		ttd_strlcpy(_network_default_ip, b, lengthof(_network_default_ip));
+		rport = NETWORK_DEFAULT_PORT;
+
+		ParseConnectionString(&player, &port, host);
+		if (port != NULL) rport = atoi(port);
+
+		item = NetworkQueryServer(host, rport, true);
+		item->manually = true;
+	}
+}
+
+/* Generates the list of manually added hosts from NetworkGameList and
+ * dumps them into the array _network_host_list. This array is needed
+ * by the function that generates the config file. */
+void NetworkRebuildHostList(void)
+{
+	uint i = 0;
+	const NetworkGameList *item = _network_game_list;
+	while (item != NULL && i != lengthof(_network_host_list)) {
+		if (item->manually) {
+			free(_network_host_list[i]);
+			_network_host_list[i++] = str_fmt("%s:%i", item->info.hostname, item->port);
+		}
+		item = item->next;
+	}
+
+	for (; i < lengthof(_network_host_list); i++) {
+		free(_network_host_list[i]);
+		_network_host_list[i] = NULL;
+	}
+}
+
+// Used by clients, to connect to a server
+bool NetworkClientConnectGame(const char *host, uint16 port)
+{
+	if (!_network_available) return false;
+
+	if (port == 0) return false;
+
+	ttd_strlcpy(_network_last_host, host, sizeof(_network_last_host));
+	_network_last_port = port;
+
+	NetworkDisconnect();
+	NetworkUDPClose();
+	NetworkInitialize();
+
+	// Try to connect
+	_networking = NetworkConnect(host, port);
+
+	// We are connected
+	if (_networking) {
+		IConsoleCmdExec("exec scripts/on_client.scr 0");
+		NetworkClient_Connected();
+	} else {
+		// Connecting failed
+		NetworkError(STR_NETWORK_ERR_NOCONNECTION);
+	}
+
+	return _networking;
+}
+
+static void NetworkInitGameInfo(void)
+{
+	NetworkClientInfo *ci;
+
+	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
+	ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
+	ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
+	if (_network_game_info.server_name[0] == '\0')
+		snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
+
+	ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision));
+
+	// The server is a client too ;)
+	if (_network_dedicated) {
+		_network_game_info.clients_on = 0;
+		_network_game_info.companies_on = 0;
+		_network_game_info.dedicated = true;
+	} else {
+		_network_game_info.clients_on = 1;
+		_network_game_info.companies_on = 1;
+		_network_game_info.dedicated = false;
+	}
+
+	_network_game_info.spectators_on = 0;
+
+	_network_game_info.game_date = _date;
+	_network_game_info.start_date = ConvertYMDToDate(_patches.starting_year, 0, 1);
+	_network_game_info.map_width = MapSizeX();
+	_network_game_info.map_height = MapSizeY();
+	_network_game_info.map_set = _opt.landscape;
+
+	_network_game_info.use_password = (_network_server_password[0] != '\0');
+
+	// We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it
+	//  The index is NETWORK_SERVER_INDEX ( = 1)
+	ci = &_network_client_info[MAX_CLIENT_INFO - 1];
+	memset(ci, 0, sizeof(*ci));
+
+	ci->client_index = NETWORK_SERVER_INDEX;
+	ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
+
+	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
+	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
+}
+
+bool NetworkServerStart(void)
+{
+	if (!_network_available) return false;
+
+	/* Call the pre-scripts */
+	IConsoleCmdExec("exec scripts/pre_server.scr 0");
+	if (_network_dedicated) IConsoleCmdExec("exec scripts/pre_dedicated.scr 0");
+
+	NetworkInitialize();
+	if (!NetworkListen()) return false;
+
+	// Try to start UDP-server
+	_network_udp_server = true;
+	_network_udp_server = NetworkUDPListen(&_udp_server_socket, _network_server_bind_ip, _network_server_port, false);
+
+	_network_server = true;
+	_networking = true;
+	_frame_counter = 0;
+	_frame_counter_server = 0;
+	_frame_counter_max = 0;
+	_last_sync_frame = 0;
+	_network_own_client_index = NETWORK_SERVER_INDEX;
+
+	/* Non-dedicated server will always be player #1 */
+	if (!_network_dedicated) _network_playas = 0;
+
+	_network_clients_connected = 0;
+
+	NetworkInitGameInfo();
+
+	// execute server initialization script
+	IConsoleCmdExec("exec scripts/on_server.scr 0");
+	// if the server is dedicated ... add some other script
+	if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
+
+	_min_players_paused = false;
+	CheckMinPlayers();
+
+	/* Try to register us to the master server */
+	_network_last_advertise_frame = 0;
+	_network_need_advertise = true;
+	NetworkUDPAdvertise();
+	return true;
+}
+
+// The server is rebooting...
+// The only difference with NetworkDisconnect, is the packets that is sent
+void NetworkReboot(void)
+{
+	if (_network_server) {
+		NetworkClientState *cs;
+		FOR_ALL_CLIENTS(cs) {
+			SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
+			NetworkSend_Packets(cs);
+		}
+	}
+
+	NetworkClose();
+
+	// Free all queued commands
+	while (_local_command_queue != NULL) {
+		CommandPacket *p = _local_command_queue;
+		_local_command_queue = _local_command_queue->next;
+		free(p);
+	}
+
+	_networking = false;
+	_network_server = false;
+}
+
+// We want to disconnect from the host/clients
+void NetworkDisconnect(void)
+{
+	if (_network_server) {
+		NetworkClientState *cs;
+		FOR_ALL_CLIENTS(cs) {
+			SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
+			NetworkSend_Packets(cs);
+		}
+	}
+
+	if (_network_advertise) NetworkUDPRemoveAdvertise();
+
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+	NetworkClose();
+
+	// Free all queued commands
+	while (_local_command_queue != NULL) {
+		CommandPacket *p = _local_command_queue;
+		_local_command_queue = _local_command_queue->next;
+		free(p);
+	}
+
+	_networking = false;
+	_network_server = false;
+}
+
+// Receives something from the network
+static bool NetworkReceive(void)
+{
+	NetworkClientState *cs;
+	int n;
+	fd_set read_fd, write_fd;
+	struct timeval tv;
+
+	FD_ZERO(&read_fd);
+	FD_ZERO(&write_fd);
+
+	FOR_ALL_CLIENTS(cs) {
+		FD_SET(cs->socket, &read_fd);
+		FD_SET(cs->socket, &write_fd);
+	}
+
+	// take care of listener port
+	if (_network_server) FD_SET(_listensocket, &read_fd);
+
+	tv.tv_sec = tv.tv_usec = 0; // don't block at all.
+#if !defined(__MORPHOS__) && !defined(__AMIGA__)
+	n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
+#else
+	n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
+#endif
+	if (n == -1 && !_network_server) NetworkError(STR_NETWORK_ERR_LOSTCONNECTION);
+
+	// accept clients..
+	if (_network_server && FD_ISSET(_listensocket, &read_fd)) NetworkAcceptClients();
+
+	// read stuff from clients
+	FOR_ALL_CLIENTS(cs) {
+		cs->writable = !!FD_ISSET(cs->socket, &write_fd);
+		if (FD_ISSET(cs->socket, &read_fd)) {
+			if (_network_server) {
+				NetworkServer_ReadPackets(cs);
+			} else {
+				NetworkRecvStatus res;
+
+				// The client already was quiting!
+				if (cs->has_quit) return false;
+
+				res = NetworkClient_ReadPackets(cs);
+				if (res != NETWORK_RECV_STATUS_OKAY) {
+					// The client made an error of which we can not recover
+					//   close the client and drop back to main menu
+					NetworkClientError(res, cs);
+					return false;
+				}
+			}
+		}
+	}
+	return true;
+}
+
+// This sends all buffered commands (if possible)
+static void NetworkSend(void)
+{
+	NetworkClientState *cs;
+	FOR_ALL_CLIENTS(cs) {
+		if (cs->writable) {
+			NetworkSend_Packets(cs);
+
+			if (cs->status == STATUS_MAP) {
+				// This client is in the middle of a map-send, call the function for that
+				SEND_COMMAND(PACKET_SERVER_MAP)(cs);
+			}
+		}
+	}
+}
+
+// Handle the local-command-queue
+static void NetworkHandleLocalQueue(void)
+{
+	CommandPacket *cp, **cp_prev;
+
+	cp_prev = &_local_command_queue;
+
+	while ( (cp = *cp_prev) != NULL) {
+
+		// The queue is always in order, which means
+		// that the first element will be executed first.
+		if (_frame_counter < cp->frame) break;
+
+		if (_frame_counter > cp->frame) {
+			// If we reach here, it means for whatever reason, we've already executed
+			// past the command we need to execute.
+			DEBUG(net, 0, "Trying to execute a packet in the past!");
+			assert(0);
+		}
+
+		// We can execute this command
+		NetworkExecuteCommand(cp);
+
+		*cp_prev = cp->next;
+		free(cp);
+	}
+
+	// Just a safety check, to be removed in the future.
+	// Make sure that no older command appears towards the end of the queue
+	// In that case we missed executing it. This will never happen.
+	for (cp = _local_command_queue; cp; cp = cp->next) {
+		assert(_frame_counter < cp->frame);
+	}
+
+}
+
+static bool NetworkDoClientLoop(void)
+{
+	_frame_counter++;
+
+	NetworkHandleLocalQueue();
+
+	StateGameLoop();
+
+	// Check if we are in sync!
+	if (_sync_frame != 0) {
+		if (_sync_frame == _frame_counter) {
+#ifdef NETWORK_SEND_DOUBLE_SEED
+			if (_sync_seed_1 != _random_seeds[0][0] || _sync_seed_2 != _random_seeds[0][1]) {
+#else
+			if (_sync_seed_1 != _random_seeds[0][0]) {
+#endif
+				NetworkError(STR_NETWORK_ERR_DESYNC);
+				DEBUG(net, 0, "Sync error detected!");
+				NetworkClientError(NETWORK_RECV_STATUS_DESYNC, DEREF_CLIENT(0));
+				return false;
+			}
+
+			// If this is the first time we have a sync-frame, we
+			//   need to let the server know that we are ready and at the same
+			//   frame as he is.. so we can start playing!
+			if (_network_first_time) {
+				_network_first_time = false;
+				SEND_COMMAND(PACKET_CLIENT_ACK)();
+			}
+
+			_sync_frame = 0;
+		} else if (_sync_frame < _frame_counter) {
+			DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
+			_sync_frame = 0;
+		}
+	}
+
+	return true;
+}
+
+// We have to do some UDP checking
+void NetworkUDPGameLoop(void)
+{
+	if (_network_udp_server) {
+		NetworkUDPReceive(_udp_server_socket);
+		if (_udp_master_socket != INVALID_SOCKET) {
+			NetworkUDPReceive(_udp_master_socket);
+		}
+	} else if (_udp_client_socket != INVALID_SOCKET) {
+		NetworkUDPReceive(_udp_client_socket);
+		if (_network_udp_broadcast > 0) _network_udp_broadcast--;
+	}
+}
+
+// The main loop called from ttd.c
+//  Here we also have to do StateGameLoop if needed!
+void NetworkGameLoop(void)
+{
+	if (!_networking) return;
+
+	if (!NetworkReceive()) return;
+
+	if (_network_server) {
+		bool send_frame = false;
+
+		// We first increase the _frame_counter
+		_frame_counter++;
+		// Update max-frame-counter
+		if (_frame_counter > _frame_counter_max) {
+			_frame_counter_max = _frame_counter + _network_frame_freq;
+			send_frame = true;
+		}
+
+		NetworkHandleLocalQueue();
+
+		// Then we make the frame
+		StateGameLoop();
+
+		_sync_seed_1 = _random_seeds[0][0];
+#ifdef NETWORK_SEND_DOUBLE_SEED
+		_sync_seed_2 = _random_seeds[0][1];
+#endif
+
+		NetworkServer_Tick(send_frame);
+	} else {
+		// Client
+
+		// Make sure we are at the frame were the server is (quick-frames)
+		if (_frame_counter_server > _frame_counter) {
+			while (_frame_counter_server > _frame_counter) {
+				if (!NetworkDoClientLoop()) break;
+			}
+		} else {
+			// Else, keep on going till _frame_counter_max
+			if (_frame_counter_max > _frame_counter) NetworkDoClientLoop();
+		}
+	}
+
+	NetworkSend();
+}
+
+static void NetworkGenerateUniqueId(void)
+{
+	md5_state_t state;
+	md5_byte_t digest[16];
+	char hex_output[16*2 + 1];
+	char coding_string[NETWORK_NAME_LENGTH];
+	int di;
+
+	snprintf(coding_string, sizeof(coding_string), "%d%s", (uint)Random(), "OpenTTD Unique ID");
+
+	/* Generate the MD5 hash */
+	md5_init(&state);
+	md5_append(&state, (const md5_byte_t*)coding_string, strlen(coding_string));
+	md5_finish(&state, digest);
+
+	for (di = 0; di < 16; ++di)
+		sprintf(hex_output + di * 2, "%02x", digest[di]);
+
+	/* _network_unique_id is our id */
+	snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
+}
+
+// This tries to launch the network for a given OS
+void NetworkStartUp(void)
+{
+	DEBUG(net, 3, "[core] starting network...");
+
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+	/*
+	 *  IMPORTANT NOTE: SocketBase needs to be initialized before we use _any_
+	 *  network related function, else: crash.
+	 */
+	DEBUG(net, 3, "[core] loading bsd socket library");
+	SocketBase = OpenLibrary("bsdsocket.library", 4);
+	if (SocketBase == NULL) {
+		DEBUG(net, 0, "[core] can't open bsdsocket.library version 4, network unavailable");
+		_network_available = false;
+		return;
+	}
+
+#if defined(__AMIGA__)
+	// for usleep() implementation (only required for legacy AmigaOS builds)
+	TimerPort = CreateMsgPort();
+	if (TimerPort != NULL) {
+		TimerRequest = (struct timerequest*)CreateIORequest(TimerPort, sizeof(struct timerequest);
+		if (TimerRequest != NULL) {
+			if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest*)TimerRequest, 0) == 0) {
+				TimerBase = TimerRequest->tr_node.io_Device;
+				if (TimerBase == NULL) {
+					// free ressources...
+					DEBUG(net, 0, "[core] can't initialize timer, network unavailable");
+					_network_available = false;
+					return;
+				}
+			}
+		}
+	}
+#endif // __AMIGA__
+#endif // __MORPHOS__ / __AMIGA__
+
+	// Network is available
+	_network_available = true;
+	_network_dedicated = false;
+	_network_last_advertise_frame = 0;
+	_network_need_advertise = true;
+	_network_advertise_retries = 0;
+
+	/* Load the ip from the openttd.cfg */
+	_network_server_bind_ip = inet_addr(_network_server_bind_ip_host);
+	/* And put the data back in it in case it was an invalid ip */
+	snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
+
+	/* Generate an unique id when there is none yet */
+	if (_network_unique_id[0] == '\0') NetworkGenerateUniqueId();
+
+	{
+		byte cl_max = _network_game_info.clients_max;
+		byte cp_max = _network_game_info.companies_max;
+		byte sp_max = _network_game_info.spectators_max;
+
+		memset(&_network_game_info, 0, sizeof(_network_game_info));
+		_network_game_info.clients_max = cl_max;
+		_network_game_info.companies_max = cp_max;
+		_network_game_info.spectators_max = sp_max;
+	}
+
+	// Let's load the network in windows
+	#if defined(WIN32)
+	{
+		WSADATA wsa;
+		DEBUG(net, 3, "[core] loading windows socket library");
+		if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
+			DEBUG(net, 0, "[core] WSAStartup failed, network unavailable");
+			_network_available = false;
+			return;
+		}
+	}
+	#endif // WIN32
+
+	NetworkInitialize();
+	DEBUG(net, 3, "[core] network online, multiplayer available");
+	NetworkFindIPs();
+}
+
+// This shuts the network down
+void NetworkShutDown(void)
+{
+	NetworkDisconnect();
+	NetworkUDPClose();
+
+	DEBUG(net, 3, "[core] shutting down network");
+
+	_network_available = false;
+
+#if defined(__MORPHOS__) || defined(__AMIGA__)
+	// free allocated ressources
+#if defined(__AMIGA__)
+	if (TimerBase    != NULL) CloseDevice((struct IORequest*)TimerRequest); // XXX This smells wrong
+	if (TimerRequest != NULL) DeleteIORequest(TimerRequest);
+	if (TimerPort    != NULL) DeleteMsgPort(TimerPort);
+#endif
+
+	if (SocketBase != NULL) CloseLibrary(SocketBase);
+#endif
+
+#if defined(WIN32)
+	WSACleanup();
+#endif
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,212 @@
+/* $Id$ */
+
+#ifndef NETWORK_H
+#define NETWORK_H
+
+#define NOREV_STRING "norev000"
+
+#ifdef ENABLE_NETWORK
+
+#include "../player.h"
+#include "core/config.h"
+#include "core/game.h"
+
+// If this line is enable, every frame will have a sync test
+//  this is not needed in normal games. Normal is like 1 sync in 100
+//  frames. You can enable this if you have a lot of desyncs on a certain
+//  game.
+// Remember: both client and server have to be compiled with this
+//  option enabled to make it to work. If one of the two has it disabled
+//  nothing will happen.
+//#define ENABLE_NETWORK_SYNC_EVERY_FRAME
+
+// In theory sending 1 of the 2 seeds is enough to check for desyncs
+//   so in theory, this next define can be left off.
+//#define NETWORK_SEND_DOUBLE_SEED
+
+// How many clients can we have? Like.. MAX_PLAYERS - 1 is the amount of
+//  players that can really play.. so.. a max of 4 spectators.. gives us..
+//  MAX_PLAYERS + 3
+#define MAX_CLIENTS (MAX_PLAYERS + 3)
+
+
+// Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1
+#define MAX_CLIENT_INFO (MAX_CLIENTS + 1)
+
+#define MAX_INTERFACES 9
+
+
+// How many vehicle/station types we put over the network
+#define NETWORK_VEHICLE_TYPES 5
+#define NETWORK_STATION_TYPES 5
+
+typedef struct NetworkPlayerInfo {
+	char company_name[NETWORK_NAME_LENGTH];         // Company name
+	char password[NETWORK_PASSWORD_LENGTH];         // The password for the player
+	Year inaugurated_year;                          // What year the company started in
+	int64 company_value;                            // The company value
+	int64 money;                                    // The amount of money the company has
+	int64 income;                                   // How much did the company earned last year
+	uint16 performance;                             // What was his performance last month?
+	byte use_password;                              // 0: No password 1: There is a password
+	uint16 num_vehicle[NETWORK_VEHICLE_TYPES];      // How many vehicles are there of this type?
+	uint16 num_station[NETWORK_STATION_TYPES];      // How many stations are there of this type?
+	char players[NETWORK_PLAYERS_LENGTH];           // The players that control this company (Name1, name2, ..)
+	uint16 months_empty;                            // How many months the company is empty
+} NetworkPlayerInfo;
+
+typedef struct NetworkClientInfo {
+	uint16 client_index;                            // Index of the client (same as ClientState->index)
+	char client_name[NETWORK_CLIENT_NAME_LENGTH];   // Name of the client
+	byte client_lang;                               // The language of the client
+	byte client_playas;                             // As which player is this client playing (PlayerID)
+	uint32 client_ip;                               // IP-address of the client (so he can be banned)
+	Date join_date;                                 // Gamedate the player has joined
+	char unique_id[NETWORK_NAME_LENGTH];            // Every play sends an unique id so we can indentify him
+} NetworkClientInfo;
+
+typedef struct NetworkGameList {
+	NetworkGameInfo info;
+	uint32 ip;
+	uint16 port;
+	bool online;                                    // False if the server did not respond (default status)
+	bool manually;                                  // True if the server was added manually
+	struct NetworkGameList *next;
+} NetworkGameList;
+
+typedef enum {
+	NETWORK_JOIN_STATUS_CONNECTING,
+	NETWORK_JOIN_STATUS_AUTHORIZING,
+	NETWORK_JOIN_STATUS_WAITING,
+	NETWORK_JOIN_STATUS_DOWNLOADING,
+	NETWORK_JOIN_STATUS_PROCESSING,
+	NETWORK_JOIN_STATUS_REGISTERING,
+
+	NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO,
+} NetworkJoinStatus;
+
+// language ids for server_lang and client_lang
+typedef enum {
+	NETLANG_ANY     = 0,
+	NETLANG_ENGLISH = 1,
+	NETLANG_GERMAN  = 2,
+	NETLANG_FRENCH  = 3,
+} NetworkLanguage;
+
+VARDEF NetworkGameList *_network_game_list;
+
+VARDEF NetworkGameInfo _network_game_info;
+VARDEF NetworkPlayerInfo _network_player_info[MAX_PLAYERS];
+VARDEF NetworkClientInfo _network_client_info[MAX_CLIENT_INFO];
+
+VARDEF char _network_player_name[NETWORK_CLIENT_NAME_LENGTH];
+VARDEF char _network_default_ip[NETWORK_HOSTNAME_LENGTH];
+
+VARDEF uint16 _network_own_client_index;
+VARDEF char _network_unique_id[NETWORK_NAME_LENGTH]; // Our own unique ID
+
+VARDEF uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode
+VARDEF uint32 _frame_counter_max; // To where we may go with our clients
+
+VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients.
+
+// networking settings
+VARDEF uint32 _broadcast_list[MAX_INTERFACES + 1];
+
+VARDEF uint16 _network_server_port;
+/* We use bind_ip and bind_ip_host, where bind_ip_host is the readable form of
+    bind_ip_host, and bind_ip the numeric value, because we want a nice number
+    in the openttd.cfg, but we wants to use the uint32 internally.. */
+VARDEF uint32 _network_server_bind_ip;
+VARDEF char _network_server_bind_ip_host[NETWORK_HOSTNAME_LENGTH];
+VARDEF bool _is_network_server; // Does this client wants to be a network-server?
+VARDEF char _network_server_name[NETWORK_NAME_LENGTH];
+VARDEF char _network_server_password[NETWORK_PASSWORD_LENGTH];
+VARDEF char _network_rcon_password[NETWORK_PASSWORD_LENGTH];
+
+VARDEF uint16 _network_max_join_time;             ///< Time a client can max take to join
+VARDEF bool _network_pause_on_join;               ///< Pause the game when a client tries to join (more chance of succeeding join)
+
+VARDEF uint16 _redirect_console_to_client;
+
+VARDEF uint16 _network_sync_freq;
+VARDEF uint8 _network_frame_freq;
+
+VARDEF uint32 _sync_seed_1, _sync_seed_2;
+VARDEF uint32 _sync_frame;
+VARDEF bool _network_first_time;
+// Vars needed for the join-GUI
+VARDEF NetworkJoinStatus _network_join_status;
+VARDEF uint8 _network_join_waiting;
+VARDEF uint16 _network_join_kbytes;
+VARDEF uint16 _network_join_kbytes_total;
+
+VARDEF char _network_last_host[NETWORK_HOSTNAME_LENGTH];
+VARDEF short _network_last_port;
+VARDEF uint32 _network_last_host_ip;
+VARDEF uint8 _network_reconnect;
+
+VARDEF bool _network_udp_server;
+VARDEF uint16 _network_udp_broadcast;
+
+VARDEF byte _network_lan_internet;
+
+VARDEF bool _network_need_advertise;
+VARDEF uint32 _network_last_advertise_frame;
+VARDEF uint8 _network_advertise_retries;
+
+VARDEF bool _network_autoclean_companies;
+VARDEF uint8 _network_autoclean_unprotected; // Remove a company after X months
+VARDEF uint8 _network_autoclean_protected;   // Unprotect a company after X months
+
+VARDEF Year _network_restart_game_year;      // If this year is reached, the server automaticly restarts
+VARDEF uint8 _network_min_players;           // Minimum number of players for game to unpause
+
+NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info);
+
+byte NetworkSpectatorCount(void);
+
+VARDEF char *_network_host_list[10];
+VARDEF char *_network_ban_list[25];
+
+void ParseConnectionString(const char **player, const char **port, char *connection_string);
+void NetworkUpdateClientInfo(uint16 client_index);
+void NetworkAddServer(const char *b);
+void NetworkRebuildHostList(void);
+bool NetworkChangeCompanyPassword(byte argc, char *argv[]);
+void NetworkPopulateCompanyInfo(void);
+void UpdateNetworkGameWindow(bool unselect);
+void CheckMinPlayers(void);
+
+void NetworkStartUp(void);
+void NetworkUDPClose(void);
+void NetworkShutDown(void);
+void NetworkGameLoop(void);
+void NetworkUDPGameLoop(void);
+bool NetworkServerStart(void);
+bool NetworkClientConnectGame(const char *host, uint16 port);
+void NetworkReboot(void);
+void NetworkDisconnect(void);
+
+VARDEF bool _networking;         ///< are we in networking mode?
+VARDEF bool _network_server;     ///< network-server is active
+VARDEF bool _network_available;  ///< is network mode available?
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void NetworkStartUp(void) {}
+static inline void NetworkShutDown(void) {}
+
+#define _networking 0
+#define _network_server 0
+#define _network_available 0
+
+#endif /* ENABLE_NETWORK */
+
+/* These variables must always be registered! */
+VARDEF bool _network_dedicated;  ///< are we a dedicated server?
+VARDEF bool _network_advertise;  ///< is the server advertising to the master server?
+VARDEF PlayerID _network_playas; ///< an id to play as.. (see players.h:Players)
+
+#endif /* NETWORK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_client.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,819 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
+#include "network_data.h"
+#include "core/tcp.h"
+#include "../date.h"
+#include "../table/strings.h"
+#include "../functions.h"
+#include "network_client.h"
+#include "network_gamelist.h"
+#include "network_gui.h"
+#include "../saveload.h"
+#include "../command.h"
+#include "../window.h"
+#include "../console.h"
+#include "../variables.h"
+#include "../ai/ai.h"
+
+
+// This file handles all the client-commands
+
+
+// So we don't make too much typos ;)
+#define MY_CLIENT DEREF_CLIENT(0)
+
+static uint32 last_ack_frame;
+
+// **********
+// Sending functions
+//   DEF_CLIENT_SEND_COMMAND has no parameters
+// **********
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)
+{
+	//
+	// Packet: CLIENT_COMPANY_INFO
+	// Function: Request company-info (in detail)
+	// Data:
+	//    <none>
+	//
+	Packet *p;
+	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
+	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+	p = NetworkSend_Init(PACKET_CLIENT_COMPANY_INFO);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
+{
+	//
+	// Packet: CLIENT_JOIN
+	// Function: Try to join the server
+	// Data:
+	//    String: OpenTTD Revision (norev000 if no revision)
+	//    String: Player Name (max NETWORK_NAME_LENGTH)
+	//    uint8:  Play as Player id (1..MAX_PLAYERS)
+	//    uint8:  Language ID
+	//    String: Unique id to find the player back in server-listing
+	//
+
+	extern const char _openttd_revision[];
+	Packet *p;
+	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
+	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+	p = NetworkSend_Init(PACKET_CLIENT_JOIN);
+	NetworkSend_string(p, _openttd_revision);
+	NetworkSend_string(p, _network_player_name); // Player name
+	NetworkSend_uint8(p, _network_playas); // PlayAs
+	NetworkSend_uint8(p, NETLANG_ANY); // Language
+	NetworkSend_string(p, _network_unique_id);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password)
+{
+	//
+	// Packet: CLIENT_PASSWORD
+	// Function: Send a password to the server to authorize
+	// Data:
+	//    uint8:  NetworkPasswordType
+	//    String: Password
+	//
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_PASSWORD);
+	NetworkSend_uint8(p, type);
+	NetworkSend_string(p, password);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GETMAP)
+{
+	//
+	// Packet: CLIENT_GETMAP
+	// Function: Request the map from the server
+	// Data:
+	//    <none>
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_GETMAP);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_MAP_OK)
+{
+	//
+	// Packet: CLIENT_MAP_OK
+	// Function: Tell the server that we are done receiving/loading the map
+	// Data:
+	//    <none>
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_MAP_OK);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK)
+{
+	//
+	// Packet: CLIENT_ACK
+	// Function: Tell the server we are done with this frame
+	// Data:
+	//    uint32: current FrameCounter of the client
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_ACK);
+
+	NetworkSend_uint32(p, _frame_counter);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send a command packet to the server
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp)
+{
+	//
+	// Packet: CLIENT_COMMAND
+	// Function: Send a DoCommand to the Server
+	// Data:
+	//    uint8:  PlayerID (0..MAX_PLAYERS-1)
+	//    uint32: CommandID (see command.h)
+	//    uint32: P1 (free variables used in DoCommand)
+	//    uint32: P2
+	//    uint32: Tile
+	//    string: text
+	//    uint8:  CallBackID (see callback_table.c)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_COMMAND);
+
+	NetworkSend_uint8(p, cp->player);
+	NetworkSend_uint32(p, cp->cmd);
+	NetworkSend_uint32(p, cp->p1);
+	NetworkSend_uint32(p, cp->p2);
+	NetworkSend_uint32(p, (uint32)cp->tile);
+	NetworkSend_string(p, cp->text);
+	NetworkSend_uint8(p, cp->callback);
+
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send a chat-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType type, int dest, const char *msg)
+{
+	//
+	// Packet: CLIENT_CHAT
+	// Function: Send a chat-packet to the serve
+	// Data:
+	//    uint8:  ActionID (see network_data.h, NetworkAction)
+	//    uint8:  Destination Type (see network_data.h, DestType);
+	//    uint8:  Destination Player (1..MAX_PLAYERS)
+	//    String: Message (max MAX_TEXT_MSG_LEN)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_CHAT);
+
+	NetworkSend_uint8(p, action);
+	NetworkSend_uint8(p, type);
+	NetworkSend_uint8(p, dest);
+	NetworkSend_string(p, msg);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send an error-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno)
+{
+	//
+	// Packet: CLIENT_ERROR
+	// Function: The client made an error and is quiting the game
+	// Data:
+	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
+	//
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_ERROR);
+
+	NetworkSend_uint8(p, errorno);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password)
+{
+	//
+	// Packet: PACKET_CLIENT_SET_PASSWORD
+	// Function: Set the password for the clients current company
+	// Data:
+	//    String: Password
+	//
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_PASSWORD);
+
+	NetworkSend_string(p, password);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name)
+{
+	//
+	// Packet: PACKET_CLIENT_SET_NAME
+	// Function: Gives the player a new name
+	// Data:
+	//    String: Name
+	//
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_NAME);
+
+	NetworkSend_string(p, name);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+// Send an quit-packet over the network
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg)
+{
+	//
+	// Packet: CLIENT_QUIT
+	// Function: The client is quiting the game
+	// Data:
+	//    String: leave-message
+	//
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_QUIT);
+
+	NetworkSend_string(p, leavemsg);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command)
+{
+	Packet *p = NetworkSend_Init(PACKET_CLIENT_RCON);
+	NetworkSend_string(p, pass);
+	NetworkSend_string(p, command);
+	NetworkSend_Packet(p, MY_CLIENT);
+}
+
+
+// **********
+// Receiving functions
+//   DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
+// **********
+
+extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FULL)
+{
+	// We try to join a server which is full
+	_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+	return NETWORK_RECV_STATUS_SERVER_FULL;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_BANNED)
+{
+	// We try to join a server where we are banned
+	_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_BANNED;
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+	return NETWORK_RECV_STATUS_SERVER_BANNED;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO)
+{
+	byte company_info_version;
+	int i;
+
+	company_info_version = NetworkRecv_uint8(MY_CLIENT, p);
+
+	if (!MY_CLIENT->has_quit && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
+		byte total;
+		byte current;
+
+		total = NetworkRecv_uint8(MY_CLIENT, p);
+
+		// There is no data at all..
+		if (total == 0) return NETWORK_RECV_STATUS_CLOSE_QUERY;
+
+		current = NetworkRecv_uint8(MY_CLIENT, p);
+		if (!IsValidPlayer(current)) return NETWORK_RECV_STATUS_CLOSE_QUERY;
+
+		NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].company_name, sizeof(_network_player_info[current].company_name));
+		_network_player_info[current].inaugurated_year = NetworkRecv_uint32(MY_CLIENT, p);
+		_network_player_info[current].company_value = NetworkRecv_uint64(MY_CLIENT, p);
+		_network_player_info[current].money = NetworkRecv_uint64(MY_CLIENT, p);
+		_network_player_info[current].income = NetworkRecv_uint64(MY_CLIENT, p);
+		_network_player_info[current].performance = NetworkRecv_uint16(MY_CLIENT, p);
+		_network_player_info[current].use_password = NetworkRecv_uint8(MY_CLIENT, p);
+		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
+			_network_player_info[current].num_vehicle[i] = NetworkRecv_uint16(MY_CLIENT, p);
+		for (i = 0; i < NETWORK_STATION_TYPES; i++)
+			_network_player_info[current].num_station[i] = NetworkRecv_uint16(MY_CLIENT, p);
+
+		NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].players, sizeof(_network_player_info[current].players));
+
+		InvalidateWindow(WC_NETWORK_WINDOW, 0);
+
+		return NETWORK_RECV_STATUS_OKAY;
+	}
+
+	return NETWORK_RECV_STATUS_CLOSE_QUERY;
+}
+
+// This packet contains info about the client (playas and name)
+//  as client we save this in NetworkClientInfo, linked via 'index'
+//  which is always an unique number on a server.
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
+{
+	NetworkClientInfo *ci;
+	uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
+	PlayerID playas = NetworkRecv_uint8(MY_CLIENT, p);
+	char name[NETWORK_NAME_LENGTH];
+	char unique_id[NETWORK_NAME_LENGTH];
+
+	NetworkRecv_string(MY_CLIENT, p, name, sizeof(name));
+	NetworkRecv_string(MY_CLIENT, p, unique_id, sizeof(unique_id));
+
+	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
+
+	/* Do we receive a change of data? Most likely we changed playas */
+	if (index == _network_own_client_index) _network_playas = playas;
+
+	ci = NetworkFindClientInfoFromIndex(index);
+	if (ci != NULL) {
+		if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
+			// Client name changed, display the change
+			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", name);
+		} else if (playas != ci->client_playas) {
+			// The player changed from client-player..
+			// Do not display that for now
+		}
+
+		ci->client_playas = playas;
+		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+
+		InvalidateWindow(WC_CLIENT_LIST, 0);
+
+		return NETWORK_RECV_STATUS_OKAY;
+	}
+
+	// We don't have this index yet, find an empty index, and put the data there
+	ci = NetworkFindClientInfoFromIndex(NETWORK_EMPTY_INDEX);
+	if (ci != NULL) {
+		ci->client_index = index;
+		ci->client_playas = playas;
+
+		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+		ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
+
+		InvalidateWindow(WC_CLIENT_LIST, 0);
+
+		return NETWORK_RECV_STATUS_OKAY;
+	}
+
+	// Here the program should never ever come.....
+	return NETWORK_RECV_STATUS_MALFORMED_PACKET;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
+{
+	NetworkErrorCode error = NetworkRecv_uint8(MY_CLIENT, p);
+
+	switch (error) {
+		/* We made an error in the protocol, and our connection is closed.... */
+		case NETWORK_ERROR_NOT_AUTHORIZED:
+		case NETWORK_ERROR_NOT_EXPECTED:
+		case NETWORK_ERROR_PLAYER_MISMATCH:
+			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_ERROR;
+			break;
+		case NETWORK_ERROR_FULL:
+			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
+			break;
+		case NETWORK_ERROR_WRONG_REVISION:
+			_switch_mode_errorstr = STR_NETWORK_ERR_WRONG_REVISION;
+			break;
+		case NETWORK_ERROR_WRONG_PASSWORD:
+			_switch_mode_errorstr = STR_NETWORK_ERR_WRONG_PASSWORD;
+			break;
+		case NETWORK_ERROR_KICKED:
+			_switch_mode_errorstr = STR_NETWORK_ERR_KICKED;
+			break;
+		case NETWORK_ERROR_CHEATER:
+			_switch_mode_errorstr = STR_NETWORK_ERR_CHEATER;
+			break;
+		default:
+			_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
+	}
+
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+	return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD)
+{
+	NetworkPasswordType type = NetworkRecv_uint8(MY_CLIENT, p);
+
+	switch (type) {
+		case NETWORK_GAME_PASSWORD:
+		case NETWORK_COMPANY_PASSWORD:
+			ShowNetworkNeedPassword(type);
+			return NETWORK_RECV_STATUS_OKAY;
+
+		default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
+	}
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WELCOME)
+{
+	_network_own_client_index = NetworkRecv_uint16(MY_CLIENT, p);
+
+	// Start receiving the map
+	SEND_COMMAND(PACKET_CLIENT_GETMAP)();
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WAIT)
+{
+	_network_join_status = NETWORK_JOIN_STATUS_WAITING;
+	_network_join_waiting = NetworkRecv_uint8(MY_CLIENT, p);
+	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+	// We are put on hold for receiving the map.. we need GUI for this ;)
+	DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
+	DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
+{
+	static char filename[256];
+	static FILE *file_pointer;
+
+	byte maptype;
+
+	maptype = NetworkRecv_uint8(MY_CLIENT, p);
+
+	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
+
+	// First packet, init some stuff
+	if (maptype == MAP_PACKET_START) {
+		// The name for the temp-map
+		snprintf(filename, lengthof(filename), "%s%snetwork_client.tmp",  _paths.autosave_dir, PATHSEP);
+
+		file_pointer = fopen(filename, "wb");
+		if (file_pointer == NULL) {
+			_switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
+			return NETWORK_RECV_STATUS_SAVEGAME;
+		}
+
+		_frame_counter = _frame_counter_server = _frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
+
+		_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
+		_network_join_kbytes = 0;
+		_network_join_kbytes_total = NetworkRecv_uint32(MY_CLIENT, p) / 1024;
+		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+		// The first packet does not contain any more data
+		return NETWORK_RECV_STATUS_OKAY;
+	}
+
+	if (maptype == MAP_PACKET_NORMAL) {
+		// We are still receiving data, put it to the file
+		fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer);
+
+		_network_join_kbytes = ftell(file_pointer) / 1024;
+		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+	}
+
+	// Check if this was the last packet
+	if (maptype == MAP_PACKET_END) {
+		fclose(file_pointer);
+
+		_network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
+		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
+
+		/* The map is done downloading, load it */
+		if (!SafeSaveOrLoad(filename, SL_LOAD, GM_NORMAL)) {
+			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+			_switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
+			return NETWORK_RECV_STATUS_SAVEGAME;
+		}
+		/* If the savegame has successfully loaded, ALL windows have been removed,
+		 * only toolbar/statusbar and gamefield are visible */
+
+		_opt_ptr = &_opt; // during a network game you are always in-game
+
+		// Say we received the map and loaded it correctly!
+		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
+
+		/* New company/spectator (invalid player) or company we want to join is not active
+		 * Switch local player to spectator and await the server's judgement */
+		if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas) ||
+				!GetPlayer(_network_playas)->is_active) {
+
+			SetLocalPlayer(PLAYER_SPECTATOR);
+
+			if (_network_playas != PLAYER_SPECTATOR) {
+				/* We have arrived and ready to start playing; send a command to make a new player;
+				 * the server will give us a client-id and let us in */
+				_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
+				ShowJoinStatusWindow();
+				NetworkSend_Command(0, 0, 0, CMD_PLAYER_CTRL, NULL);
+			}
+		} else {
+			// take control over an existing company
+			SetLocalPlayer(_network_playas);
+		}
+	}
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FRAME)
+{
+	_frame_counter_server = NetworkRecv_uint32(MY_CLIENT, p);
+	_frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
+	// Test if the server supports this option
+	//  and if we are at the frame the server is
+	if (p->pos < p->size) {
+		_sync_frame = _frame_counter_server;
+		_sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+		_sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
+#endif
+	}
+#endif
+	DEBUG(net, 5, "Received FRAME %d", _frame_counter_server);
+
+	// Let the server know that we received this frame correctly
+	//  We do this only once per day, to save some bandwidth ;)
+	if (!_network_first_time && last_ack_frame < _frame_counter) {
+		last_ack_frame = _frame_counter + DAY_TICKS;
+		DEBUG(net, 4, "Sent ACK at %d", _frame_counter);
+		SEND_COMMAND(PACKET_CLIENT_ACK)();
+	}
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SYNC)
+{
+	_sync_frame = NetworkRecv_uint32(MY_CLIENT, p);
+	_sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+	_sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
+#endif
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMMAND)
+{
+	CommandPacket *cp = malloc(sizeof(CommandPacket));
+	cp->player = NetworkRecv_uint8(MY_CLIENT, p);
+	cp->cmd = NetworkRecv_uint32(MY_CLIENT, p);
+	cp->p1 = NetworkRecv_uint32(MY_CLIENT, p);
+	cp->p2 = NetworkRecv_uint32(MY_CLIENT, p);
+	cp->tile = NetworkRecv_uint32(MY_CLIENT, p);
+	NetworkRecv_string(MY_CLIENT, p, cp->text, sizeof(cp->text));
+	cp->callback = NetworkRecv_uint8(MY_CLIENT, p);
+	cp->frame = NetworkRecv_uint32(MY_CLIENT, p);
+	cp->next = NULL;
+
+	// The server did send us this command..
+	//  queue it in our own queue, so we can handle it in the upcoming frame!
+
+	if (_local_command_queue == NULL) {
+		_local_command_queue = cp;
+	} else {
+		// Find last packet
+		CommandPacket *c = _local_command_queue;
+		while (c->next != NULL) c = c->next;
+		c->next = cp;
+	}
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CHAT)
+{
+	char name[NETWORK_NAME_LENGTH], msg[MAX_TEXT_MSG_LEN];
+	const NetworkClientInfo *ci = NULL, *ci_to;
+
+	NetworkAction action = NetworkRecv_uint8(MY_CLIENT, p);
+	uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
+	bool self_send = NetworkRecv_uint8(MY_CLIENT, p);
+	NetworkRecv_string(MY_CLIENT, p, msg, MAX_TEXT_MSG_LEN);
+
+	ci_to = NetworkFindClientInfoFromIndex(index);
+	if (ci_to == NULL) return NETWORK_RECV_STATUS_OKAY;
+
+	/* Did we initiate the action locally? */
+	if (self_send) {
+		switch (action) {
+			case NETWORK_ACTION_CHAT_CLIENT:
+				/* For speaking to client we need the client-name */
+				snprintf(name, sizeof(name), "%s", ci_to->client_name);
+				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+				break;
+
+			/* For speaking to company or giving money, we need the player-name */
+			case NETWORK_ACTION_GIVE_MONEY:
+				if (!IsValidPlayer(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
+				/* fallthrough */
+			case NETWORK_ACTION_CHAT_COMPANY: {
+				StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
+
+				GetString(name, str, lastof(name));
+				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
+			} break;
+
+			default: NOT_REACHED(); break;
+		}
+	} else {
+		/* Display message from somebody else */
+		snprintf(name, sizeof(name), "%s", ci_to->client_name);
+		ci = ci_to;
+	}
+
+	if (ci != NULL)
+		NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), self_send, name, "%s", msg);
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
+{
+	char str[100];
+	uint16 index;
+	NetworkClientInfo *ci;
+
+	index = NetworkRecv_uint16(MY_CLIENT, p);
+	GetNetworkErrorMsg(str, NetworkRecv_uint8(MY_CLIENT, p), lastof(str));
+
+	ci = NetworkFindClientInfoFromIndex(index);
+	if (ci != NULL) {
+		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
+
+		// The client is gone, give the NetworkClientInfo free
+		ci->client_index = NETWORK_EMPTY_INDEX;
+	}
+
+	InvalidateWindow(WC_CLIENT_LIST, 0);
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_QUIT)
+{
+	char str[100];
+	uint16 index;
+	NetworkClientInfo *ci;
+
+	index = NetworkRecv_uint16(MY_CLIENT, p);
+	NetworkRecv_string(MY_CLIENT, p, str, lengthof(str));
+
+	ci = NetworkFindClientInfoFromIndex(index);
+	if (ci != NULL) {
+		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
+
+		// The client is gone, give the NetworkClientInfo free
+		ci->client_index = NETWORK_EMPTY_INDEX;
+	} else {
+		DEBUG(net, 0, "Unknown client (%d) is leaving the game", index);
+	}
+
+	InvalidateWindow(WC_CLIENT_LIST, 0);
+
+	// If we come here it means we could not locate the client.. strange :s
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_JOIN)
+{
+	uint16 index;
+	NetworkClientInfo *ci;
+
+	index = NetworkRecv_uint16(MY_CLIENT, p);
+
+	ci = NetworkFindClientInfoFromIndex(index);
+	if (ci != NULL)
+		NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, ci->client_name, "");
+
+	InvalidateWindow(WC_CLIENT_LIST, 0);
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN)
+{
+	_switch_mode_errorstr = STR_NETWORK_SERVER_SHUTDOWN;
+
+	return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
+{
+	// To trottle the reconnects a bit, every clients waits
+	//  his _local_player value before reconnecting
+	// PLAYER_SPECTATOR is currently 255, so to avoid long wait periods
+	//  set the max to 10.
+	_network_reconnect = min(_local_player + 1, 10);
+	_switch_mode_errorstr = STR_NETWORK_SERVER_REBOOT;
+
+	return NETWORK_RECV_STATUS_SERVER_ERROR;
+}
+
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_RCON)
+{
+	char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
+	uint16 color_code;
+
+	color_code = NetworkRecv_uint16(MY_CLIENT, p);
+	NetworkRecv_string(MY_CLIENT, p, rcon_out, sizeof(rcon_out));
+
+	IConsolePrint(color_code, rcon_out);
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+
+
+// The layout for the receive-functions by the client
+typedef NetworkRecvStatus NetworkClientPacket(Packet *p);
+
+// This array matches PacketType. At an incoming
+//  packet it is matches against this array
+//  and that way the right function to handle that
+//  packet is found.
+static NetworkClientPacket* const _network_client_packet[] = {
+	RECEIVE_COMMAND(PACKET_SERVER_FULL),
+	RECEIVE_COMMAND(PACKET_SERVER_BANNED),
+	NULL, /*PACKET_CLIENT_JOIN,*/
+	RECEIVE_COMMAND(PACKET_SERVER_ERROR),
+	NULL, /*PACKET_CLIENT_COMPANY_INFO,*/
+	RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO),
+	RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO),
+	RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD),
+	NULL, /*PACKET_CLIENT_PASSWORD,*/
+	RECEIVE_COMMAND(PACKET_SERVER_WELCOME),
+	NULL, /*PACKET_CLIENT_GETMAP,*/
+	RECEIVE_COMMAND(PACKET_SERVER_WAIT),
+	RECEIVE_COMMAND(PACKET_SERVER_MAP),
+	NULL, /*PACKET_CLIENT_MAP_OK,*/
+	RECEIVE_COMMAND(PACKET_SERVER_JOIN),
+	RECEIVE_COMMAND(PACKET_SERVER_FRAME),
+	RECEIVE_COMMAND(PACKET_SERVER_SYNC),
+	NULL, /*PACKET_CLIENT_ACK,*/
+	NULL, /*PACKET_CLIENT_COMMAND,*/
+	RECEIVE_COMMAND(PACKET_SERVER_COMMAND),
+	NULL, /*PACKET_CLIENT_CHAT,*/
+	RECEIVE_COMMAND(PACKET_SERVER_CHAT),
+	NULL, /*PACKET_CLIENT_SET_PASSWORD,*/
+	NULL, /*PACKET_CLIENT_SET_NAME,*/
+	NULL, /*PACKET_CLIENT_QUIT,*/
+	NULL, /*PACKET_CLIENT_ERROR,*/
+	RECEIVE_COMMAND(PACKET_SERVER_QUIT),
+	RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT),
+	RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN),
+	RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
+	RECEIVE_COMMAND(PACKET_SERVER_RCON),
+	NULL, /*PACKET_CLIENT_RCON,*/
+};
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_client_packet) == PACKET_END);
+
+// Is called after a client is connected to the server
+void NetworkClient_Connected(void)
+{
+	// Set the frame-counter to 0 so nothing happens till we are ready
+	_frame_counter = 0;
+	_frame_counter_server = 0;
+	last_ack_frame = 0;
+	// Request the game-info
+	SEND_COMMAND(PACKET_CLIENT_JOIN)();
+}
+
+// Reads the packets from the socket-stream, if available
+NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs)
+{
+	Packet *p;
+	NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY;
+
+	while (res == NETWORK_RECV_STATUS_OKAY && (p = NetworkRecv_Packet(cs, &res)) != NULL) {
+		byte type = NetworkRecv_uint8(MY_CLIENT, p);
+		if (type < PACKET_END && _network_client_packet[type] != NULL && !MY_CLIENT->has_quit) {
+			res = _network_client_packet[type](p);
+		} else {
+			res = NETWORK_RECV_STATUS_MALFORMED_PACKET;
+			DEBUG(net, 0, "[client] received invalid packet type %d", type);
+		}
+
+		free(p);
+	}
+
+	return res;
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_client.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,25 @@
+/* $Id$ */
+
+#ifndef NETWORK_CLIENT_H
+#define NETWORK_CLIENT_H
+
+#ifdef ENABLE_NETWORK
+
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GAME_INFO);
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType desttype, int dest, const char *msg);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name);
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command);
+
+NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs);
+void NetworkClient_Connected(void);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CLIENT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_data.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,106 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "network_data.h"
+#include "../string.h"
+#include "network_client.h"
+#include "../command.h"
+#include "../callback_table.h"
+
+// Add a command to the local command queue
+void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
+{
+	CommandPacket* new_cp = malloc(sizeof(*new_cp));
+
+	*new_cp = *cp;
+
+	if (cs->command_queue == NULL) {
+		cs->command_queue = new_cp;
+	} else {
+		CommandPacket *c = cs->command_queue;
+		while (c->next != NULL) c = c->next;
+		c->next = new_cp;
+	}
+}
+
+// Prepare a DoCommand to be send over the network
+void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
+{
+	CommandPacket *c = malloc(sizeof(CommandPacket));
+	byte temp_callback;
+
+	c->player = _local_player;
+	c->next = NULL;
+	c->tile = tile;
+	c->p1 = p1;
+	c->p2 = p2;
+	c->cmd = cmd;
+	c->callback = 0;
+
+	temp_callback = 0;
+
+	while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
+		temp_callback++;
+	if (temp_callback == _callback_table_count) {
+		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
+		temp_callback = 0; /* _callback_table[0] == NULL */
+	}
+
+	if (_network_server) {
+		// We are the server, so set the command to be executed next possible frame
+		c->frame = _frame_counter_max + 1;
+	} else {
+		c->frame = 0; // The client can't tell which frame, so just make it 0
+	}
+
+	ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
+
+	if (_network_server) {
+		// If we are the server, we queue the command in our 'special' queue.
+		//   In theory, we could execute the command right away, but then the
+		//   client on the server can do everything 1 tick faster than others.
+		//   So to keep the game fair, we delay the command with 1 tick
+		//   which gives about the same speed as most clients.
+		NetworkClientState *cs;
+
+		// And we queue it for delivery to the clients
+		FOR_ALL_CLIENTS(cs) {
+			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
+		}
+
+		// Only the server gets the callback, because clients should not get them
+		c->callback = temp_callback;
+		if (_local_command_queue == NULL) {
+			_local_command_queue = c;
+		} else {
+			// Find last packet
+			CommandPacket *cp = _local_command_queue;
+			while (cp->next != NULL) cp = cp->next;
+			cp->next = c;
+		}
+
+		return;
+	}
+
+	// Clients send their command to the server and forget all about the packet
+	c->callback = temp_callback;
+	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
+}
+
+// Execute a DoCommand we received from the network
+void NetworkExecuteCommand(CommandPacket *cp)
+{
+	_current_player = cp->player;
+	_cmd_text = cp->text;
+	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
+	if (cp->callback > _callback_table_count) {
+		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
+		cp->callback = 0;
+	}
+	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_data.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,167 @@
+/* $Id$ */
+
+#ifndef NETWORK_DATA_H
+#define NETWORK_DATA_H
+
+// Is the network enabled?
+#ifdef ENABLE_NETWORK
+
+#include "../openttd.h"
+#include "network.h"
+#include "core/os_abstraction.h"
+#include "core/config.h"
+#include "core/packet.h"
+
+#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */
+
+// The client-info-server-index is always 1
+#define NETWORK_SERVER_INDEX 1
+#define NETWORK_EMPTY_INDEX 0
+
+typedef struct CommandPacket {
+	struct CommandPacket *next;
+	PlayerID player; /// player that is executing the command
+	uint32 cmd;    /// command being executed
+	uint32 p1;     /// parameter p1
+	uint32 p2;     /// parameter p2
+	TileIndex tile; /// tile command being executed on
+	char text[80];
+	uint32 frame;  /// the frame in which this packet is executed
+	byte callback; /// any callback function executed upon successful completion of the command
+} CommandPacket;
+
+typedef enum {
+	STATUS_INACTIVE,
+	STATUS_AUTH, // This means that the client is authorized
+	STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map
+	STATUS_MAP,
+	STATUS_DONE_MAP,
+	STATUS_PRE_ACTIVE,
+	STATUS_ACTIVE,
+} ClientStatus;
+
+typedef enum {
+	MAP_PACKET_START,
+	MAP_PACKET_NORMAL,
+	MAP_PACKET_END,
+} MapPacket;
+
+typedef enum {
+	NETWORK_RECV_STATUS_OKAY,
+	NETWORK_RECV_STATUS_DESYNC,
+	NETWORK_RECV_STATUS_SAVEGAME,
+	NETWORK_RECV_STATUS_CONN_LOST,
+	NETWORK_RECV_STATUS_MALFORMED_PACKET,
+	NETWORK_RECV_STATUS_SERVER_ERROR, // The server told us we made an error
+	NETWORK_RECV_STATUS_SERVER_FULL,
+	NETWORK_RECV_STATUS_SERVER_BANNED,
+	NETWORK_RECV_STATUS_CLOSE_QUERY, // Done quering the server
+} NetworkRecvStatus;
+
+typedef enum {
+	NETWORK_ERROR_GENERAL, // Try to use thisone like never
+
+	// Signals from clients
+	NETWORK_ERROR_DESYNC,
+	NETWORK_ERROR_SAVEGAME_FAILED,
+	NETWORK_ERROR_CONNECTION_LOST,
+	NETWORK_ERROR_ILLEGAL_PACKET,
+
+	// Signals from servers
+	NETWORK_ERROR_NOT_AUTHORIZED,
+	NETWORK_ERROR_NOT_EXPECTED,
+	NETWORK_ERROR_WRONG_REVISION,
+	NETWORK_ERROR_NAME_IN_USE,
+	NETWORK_ERROR_WRONG_PASSWORD,
+	NETWORK_ERROR_PLAYER_MISMATCH, // Happens in CLIENT_COMMAND
+	NETWORK_ERROR_KICKED,
+	NETWORK_ERROR_CHEATER,
+	NETWORK_ERROR_FULL,
+} NetworkErrorCode;
+
+// Actions that can be used for NetworkTextMessage
+typedef enum {
+	NETWORK_ACTION_JOIN,
+	NETWORK_ACTION_LEAVE,
+	NETWORK_ACTION_SERVER_MESSAGE,
+	NETWORK_ACTION_CHAT,
+	NETWORK_ACTION_CHAT_COMPANY,
+	NETWORK_ACTION_CHAT_CLIENT,
+	NETWORK_ACTION_GIVE_MONEY,
+	NETWORK_ACTION_NAME_CHANGE,
+} NetworkAction;
+
+typedef enum {
+	NETWORK_GAME_PASSWORD,
+	NETWORK_COMPANY_PASSWORD,
+} NetworkPasswordType;
+
+// To keep the clients all together
+struct NetworkClientState { // Typedeffed in network_core/packet.h
+	SOCKET socket;
+	uint16 index;
+	uint32 last_frame;
+	uint32 last_frame_server;
+	byte lag_test; // This byte is used for lag-testing the client
+
+	ClientStatus status;
+	bool writable; // is client ready to write to?
+	bool has_quit;
+
+	Packet *packet_queue; // Packets that are awaiting delivery
+	Packet *packet_recv; // Partially received packet
+
+	CommandPacket *command_queue; // The command-queue awaiting delivery
+};
+
+typedef enum {
+	DESTTYPE_BROADCAST, ///< Send message/notice to all players (All)
+	DESTTYPE_TEAM,    ///< Send message/notice to everyone playing the same company (Team)
+	DESTTYPE_CLIENT,    ///< Send message/notice to only a certain player (Private)
+} DestType;
+
+CommandPacket *_local_command_queue;
+
+SOCKET _udp_client_socket; // udp client socket
+SOCKET _udp_server_socket; // udp server socket
+SOCKET _udp_master_socket; // udp master socket
+
+// Here we keep track of the clients
+//  (and the client uses [0] for his own communication)
+NetworkClientState _clients[MAX_CLIENTS];
+#define DEREF_CLIENT(i) (&_clients[i])
+// This returns the NetworkClientInfo from a NetworkClientState
+#define DEREF_CLIENT_INFO(cs) (&_network_client_info[cs - _clients])
+
+// Macros to make life a bit more easier
+#define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p)
+#define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(void)
+#define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
+#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkClientState *cs, Packet *p)
+#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkClientState *cs)
+#define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
+
+#define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command
+#define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command
+
+#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->socket != INVALID_SOCKET; cs++)
+#define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX)
+
+void NetworkExecuteCommand(CommandPacket *cp);
+void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp);
+
+// from network.c
+void NetworkCloseClient(NetworkClientState *cs);
+void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...);
+void NetworkGetClientName(char *clientname, size_t size, const NetworkClientState *cs);
+uint NetworkCalculateLag(const NetworkClientState *cs);
+byte NetworkGetCurrentLanguageIndex(void);
+NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index);
+NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip);
+NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index);
+unsigned long NetworkResolveHost(const char *hostname);
+char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_DATA_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_gamelist.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,74 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "network_data.h"
+#include "../newgrf_config.h"
+
+// This file handles the GameList
+// Also, it handles the request to a server for data about the server
+
+/** Add a new item to the linked gamelist. If the IP and Port match
+ * return the existing item instead of adding it again
+ * @param ip the IP-address (inet_addr) of the to-be added item
+ * @param port the port the server is running on
+ * @return a point to the newly added or already existing item */
+NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port)
+{
+	NetworkGameList *item, *prev_item;
+
+	prev_item = NULL;
+	for (item = _network_game_list; item != NULL; item = item->next) {
+		if (item->ip == ip && item->port == port) return item;
+		prev_item = item;
+	}
+
+	item = malloc(sizeof(*item));
+	memset(item, 0, sizeof(*item));
+	item->next = NULL;
+	item->ip = ip;
+	item->port = port;
+
+	if (prev_item == NULL) {
+		_network_game_list = item;
+	} else {
+		prev_item->next = item;
+	}
+	DEBUG(net, 4, "[gamelist] added server to list");
+
+	UpdateNetworkGameWindow(false);
+
+	return item;
+}
+
+/** Remove an item from the gamelist linked list
+ * @param remove pointer to the item to be removed */
+void NetworkGameListRemoveItem(NetworkGameList *remove)
+{
+	NetworkGameList *item, *prev_item;
+
+	prev_item = NULL;
+	for (item = _network_game_list; item != NULL; item = item->next) {
+		if (remove == item) {
+			if (prev_item == NULL) {
+				_network_game_list = remove->next;
+			} else {
+				prev_item->next = remove->next;
+			}
+
+			/* Remove GRFConfig information */
+			ClearGRFConfigList(&remove->info.grfconfig);
+			free(remove);
+			remove = NULL;
+
+			DEBUG(net, 4, "[gamelist] removed server from list");
+			UpdateNetworkGameWindow(false);
+			return;
+		}
+		prev_item = item;
+	}
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_gamelist.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,11 @@
+/* $Id$ */
+
+#ifndef NETWORK_GAMELIST_H
+#define NETWORK_GAMELIST_H
+
+void NetworkGameListClear(void);
+NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port);
+void NetworkGameListRemoveItem(NetworkGameList *remove);
+void NetworkGameListAddQueriedItem(const NetworkGameInfo *info, bool server_online);
+
+#endif /* NETWORK_GAMELIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,1706 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../table/sprites.h"
+#include "network.h"
+#include "../date.h"
+
+#include "../fios.h"
+#include "../table/strings.h"
+#include "../functions.h"
+#include "network_data.h"
+#include "network_client.h"
+#include "network_gui.h"
+#include "network_gamelist.h"
+#include "../window.h"
+#include "../gui.h"
+#include "../gfx.h"
+#include "../command.h"
+#include "../variables.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "../settings.h"
+#include "../string.h"
+#include "../town.h"
+#include "../newgrf.h"
+
+#define BGC 5
+#define BTC 15
+
+typedef struct network_d {
+	PlayerID company;        // select company in network lobby
+	byte field;              // select text-field in start-server and game-listing
+	NetworkGameList *server; // selected server in lobby and game-listing
+	FiosItem *map;           // selected map in start-server
+} network_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
+
+typedef struct network_ql_d {
+	network_d n;                 // see above; general stuff
+	querystr_d q;                // text-input in start-server and game-listing
+	NetworkGameList **sort_list; // list of games (sorted)
+	list_d l;                    // accompanying list-administration
+} network_ql_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_ql_d));
+
+/* Global to remember sorting after window has been closed */
+static Listing _ng_sorting;
+
+static char _edit_str_buf[150];
+static bool _chat_tab_completion_active;
+
+static void ShowNetworkStartServerWindow(void);
+static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
+extern void SwitchMode(int new_mode);
+
+static const StringID _connection_types_dropdown[] = {
+	STR_NETWORK_LAN_INTERNET,
+	STR_NETWORK_INTERNET_ADVERTISE,
+	INVALID_STRING_ID
+};
+
+static const StringID _lan_internet_types_dropdown[] = {
+	STR_NETWORK_LAN,
+	STR_NETWORK_INTERNET,
+	INVALID_STRING_ID
+};
+
+static const StringID _players_dropdown[] = {
+	STR_NETWORK_0_PLAYERS,
+	STR_NETWORK_1_PLAYERS,
+	STR_NETWORK_2_PLAYERS,
+	STR_NETWORK_3_PLAYERS,
+	STR_NETWORK_4_PLAYERS,
+	STR_NETWORK_5_PLAYERS,
+	STR_NETWORK_6_PLAYERS,
+	STR_NETWORK_7_PLAYERS,
+	STR_NETWORK_8_PLAYERS,
+	STR_NETWORK_9_PLAYERS,
+	STR_NETWORK_10_PLAYERS,
+	INVALID_STRING_ID
+};
+
+static const StringID _language_dropdown[] = {
+	STR_NETWORK_LANG_ANY,
+	STR_NETWORK_LANG_ENGLISH,
+	STR_NETWORK_LANG_GERMAN,
+	STR_NETWORK_LANG_FRENCH,
+	INVALID_STRING_ID
+};
+
+enum {
+	NET_PRC__OFFSET_TOP_WIDGET          = 54,
+	NET_PRC__OFFSET_TOP_WIDGET_COMPANY  = 52,
+	NET_PRC__SIZE_OF_ROW                = 14,
+};
+
+/** Update the network new window because a new server is
+ * found on the network.
+ * @param unselect unselect the currently selected item */
+void UpdateNetworkGameWindow(bool unselect)
+{
+	SendWindowMessage(WC_NETWORK_WINDOW, 0, unselect, 0, 0);
+}
+
+static bool _internal_sort_order; // Used for Qsort order-flipping
+typedef int CDECL NGameNameSortFunction(const void*, const void*);
+
+/** Qsort function to sort by name. */
+static int CDECL NGameNameSorter(const void *a, const void *b)
+{
+	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+	int r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+	return _internal_sort_order ? -r : r;
+}
+
+/** Qsort function to sort by the amount of clients online on a
+ * server. If the two servers have the same amount, the one with the
+ * higher maximum is preferred. */
+static int CDECL NGameClientSorter(const void *a, const void *b)
+{
+	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+	/* Reverse as per default we are interested in most-clients first */
+	int r = cmp1->info.clients_on - cmp2->info.clients_on;
+
+	if (r == 0) r = cmp1->info.clients_max - cmp2->info.clients_max;
+	if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+	return _internal_sort_order ? -r : r;
+}
+
+/** Qsort function to sort by joinability. If both servers are the
+ * same, prefer the non-passworded server first. */
+static int CDECL NGameAllowedSorter(const void *a, const void *b)
+{
+	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
+	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
+	/* Reverse default as we are interested in compatible clients first */
+	int r = cmp2->info.compatible - cmp1->info.compatible;
+
+	if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
+	if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
+
+	return _internal_sort_order ? -r : r;
+}
+
+/** (Re)build the network game list as its amount has changed because
+ * an item has been added or deleted for example
+ * @param ngl list_d struct that contains all necessary information for sorting */
+static void BuildNetworkGameList(network_ql_d *nqld)
+{
+	NetworkGameList *ngl_temp;
+	uint n = 0;
+
+	if (!(nqld->l.flags & VL_REBUILD)) return;
+
+	/* Count the number of games in the list */
+	for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
+	if (n == 0) return;
+
+	/* Create temporary array of games to use for listing */
+	free(nqld->sort_list);
+	nqld->sort_list = malloc(n * sizeof(nqld->sort_list[0]));
+	if (nqld->sort_list == NULL) error("Could not allocate memory for the network-game-sorting-list");
+	nqld->l.list_length = n;
+
+	for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
+		nqld->sort_list[n++] = ngl_temp;
+	}
+
+	/* Force resort */
+	nqld->l.flags &= ~VL_REBUILD;
+	nqld->l.flags |= VL_RESORT;
+}
+
+static void SortNetworkGameList(network_ql_d *nqld)
+{
+	static NGameNameSortFunction * const ngame_sorter[] = {
+		&NGameNameSorter,
+		&NGameClientSorter,
+		&NGameAllowedSorter
+	};
+
+	NetworkGameList *item;
+	uint i;
+
+	if (!(nqld->l.flags & VL_RESORT)) return;
+	if (nqld->l.list_length == 0) return;
+
+	_internal_sort_order = !!(nqld->l.flags & VL_DESC);
+	qsort(nqld->sort_list, nqld->l.list_length, sizeof(nqld->sort_list[0]), ngame_sorter[nqld->l.sort_type]);
+
+	/* After sorting ngl->sort_list contains the sorted items. Put these back
+	 * into the original list. Basically nothing has changed, we are only
+	 * shuffling the ->next pointers */
+	_network_game_list = nqld->sort_list[0];
+	for (item = _network_game_list, i = 1; i != nqld->l.list_length; i++) {
+		item->next = nqld->sort_list[i];
+		item = item->next;
+	}
+	item->next = NULL;
+
+	nqld->l.flags &= ~VL_RESORT;
+}
+
+/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
+static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
+{
+	network_d *nd = &WP(w, network_ql_d).n;
+	list_d *ld = &WP(w, network_ql_d).l;
+
+	switch (e->event) {
+	case WE_CREATE: /* Focus input box */
+		nd->field = 3;
+		nd->server = NULL;
+
+		WP(w, network_ql_d).sort_list = NULL;
+		ld->flags = VL_REBUILD | (_ng_sorting.order << (VL_DESC - 1));
+		ld->sort_type = _ng_sorting.criteria;
+		break;
+
+	case WE_PAINT: {
+		const NetworkGameList *sel = nd->server;
+		const char *arrow = (ld->flags & VL_DESC) ? DOWNARROW : UPARROW;
+
+		if (ld->flags & VL_REBUILD) {
+			BuildNetworkGameList(&WP(w, network_ql_d));
+			SetVScrollCount(w, ld->list_length);
+		}
+		if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
+
+		SetWindowWidgetDisabledState(w, 17, sel == NULL);
+		/* Join Button disabling conditions */
+		SetWindowWidgetDisabledState(w, 16, sel == NULL || // no Selected Server
+				!sel->online || // Server offline
+				sel->info.clients_on >= sel->info.clients_max || // Server full
+				!sel->info.compatible); // Revision mismatch
+
+		SetWindowWidgetHiddenState(w, 18, sel == NULL ||
+				!sel->online ||
+				sel->info.grfconfig == NULL);
+
+		SetDParam(0, 0x00);
+		SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
+		DrawWindowWidgets(w);
+
+		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
+
+		DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
+		DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
+
+		/* Sort based on widgets: name, clients, compatibility */
+		switch (ld->sort_type) {
+			case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, 0x10); break;
+			case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, 0x10); break;
+			case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, 0x10); break;
+		}
+
+		{ // draw list of games
+			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
+			int32 n = 0;
+			int32 pos = w->vscroll.pos;
+			uint max_name_width = w->widget[6].right - w->widget[6].left - 5;
+			const NetworkGameList *cur_item = _network_game_list;
+
+			while (pos > 0 && cur_item != NULL) {
+				pos--;
+				cur_item = cur_item->next;
+			}
+
+			while (cur_item != NULL) {
+				// show highlighted item with a different colour
+				if (cur_item == sel) GfxFillRect(w->widget[6].left + 1, y - 2, w->widget[8].right - 1, y + 9, 10);
+
+				SetDParamStr(0, cur_item->info.server_name);
+				DrawStringTruncated(w->widget[6].left + 5, y, STR_02BD, 16, max_name_width);
+
+				SetDParam(0, cur_item->info.clients_on);
+				SetDParam(1, cur_item->info.clients_max);
+				SetDParam(2, cur_item->info.companies_on);
+				SetDParam(3, cur_item->info.companies_max);
+				DrawStringCentered(210, y, STR_NETWORK_GENERAL_ONLINE, 2);
+
+				// only draw icons if the server is online
+				if (cur_item->online) {
+					// draw a lock if the server is password protected.
+					if (cur_item->info.use_password) DrawSprite(SPR_LOCK, w->widget[8].left + 5, y - 1);
+
+					// draw red or green icon, depending on compatibility with server.
+					DrawSprite(SPR_BLOT | (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[8].left + 15, y);
+
+					// draw flag according to server language
+					DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, w->widget[8].left + 25, y);
+				}
+
+				cur_item = cur_item->next;
+				y += NET_PRC__SIZE_OF_ROW;
+				if (++n == w->vscroll.cap) break; // max number of games in the window
+			}
+		}
+
+		/* Draw the right menu */
+		GfxFillRect(311, 43, 539, 92, 157);
+		if (sel == NULL) {
+			DrawStringCentered(425, 58, STR_NETWORK_GAME_INFO, 0);
+		} else if (!sel->online) {
+			SetDParamStr(0, sel->info.server_name);
+			DrawStringCentered(425, 68, STR_ORANGE, 0); // game name
+
+			DrawStringCentered(425, 132, STR_NETWORK_SERVER_OFFLINE, 0); // server offline
+		} else { // show game info
+			uint16 y = 100;
+			const uint16 x = w->widget[15].left + 5;
+
+			DrawStringCentered(425, 48, STR_NETWORK_GAME_INFO, 0);
+
+
+			SetDParamStr(0, sel->info.server_name);
+			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 62, STR_ORANGE, 16); // game name
+
+			SetDParamStr(0, sel->info.map_name);
+			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 74, STR_02BD, 16); // map name
+
+			SetDParam(0, sel->info.clients_on);
+			SetDParam(1, sel->info.clients_max);
+			SetDParam(2, sel->info.companies_on);
+			SetDParam(3, sel->info.companies_max);
+			DrawString(x, y, STR_NETWORK_CLIENTS, 2);
+			y += 10;
+
+			SetDParam(0, _language_dropdown[sel->info.server_lang]);
+			DrawString(x, y, STR_NETWORK_LANGUAGE, 2); // server language
+			y += 10;
+
+			SetDParam(0, STR_TEMPERATE_LANDSCAPE + sel->info.map_set);
+			DrawString(x, y, STR_NETWORK_TILESET, 2); // tileset
+			y += 10;
+
+			SetDParam(0, sel->info.map_width);
+			SetDParam(1, sel->info.map_height);
+			DrawString(x, y, STR_NETWORK_MAP_SIZE, 2); // map size
+			y += 10;
+
+			SetDParamStr(0, sel->info.server_revision);
+			DrawString(x, y, STR_NETWORK_SERVER_VERSION, 2); // server version
+			y += 10;
+
+			SetDParamStr(0, sel->info.hostname);
+			SetDParam(1, sel->port);
+			DrawString(x, y, STR_NETWORK_SERVER_ADDRESS, 2); // server address
+			y += 10;
+
+			SetDParam(0, sel->info.start_date);
+			DrawString(x, y, STR_NETWORK_START_DATE, 2); // start date
+			y += 10;
+
+			SetDParam(0, sel->info.game_date);
+			DrawString(x, y, STR_NETWORK_CURRENT_DATE, 2); // current date
+			y += 10;
+
+			y += 2;
+
+			if (!sel->info.compatible) {
+				DrawStringCentered(425, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, 0); // server mismatch
+			} else if (sel->info.clients_on == sel->info.clients_max) {
+				// Show: server full, when clients_on == clients_max
+				DrawStringCentered(425, y, STR_NETWORK_SERVER_FULL, 0); // server full
+			} else if (sel->info.use_password) {
+				DrawStringCentered(425, y, STR_NETWORK_PASSWORD, 0); // password warning
+			}
+
+			y += 10;
+		}
+	}	break;
+
+	case WE_CLICK:
+		nd->field = e->we.click.widget;
+		switch (e->we.click.widget) {
+		case 0: case 14: /* Close 'X' | Cancel button */
+			DeleteWindowById(WC_NETWORK_WINDOW, 0);
+			break;
+		case 4: case 5:
+			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
+			break;
+		case 6: /* Sort by name */
+		case 7: /* Sort by connected clients */
+		case 8: /* Connectivity (green dot) */
+			if (ld->sort_type == e->we.click.widget - 6) ld->flags ^= VL_DESC;
+			ld->flags |= VL_RESORT;
+			ld->sort_type = e->we.click.widget - 6;
+
+			_ng_sorting.order = !!(ld->flags & VL_DESC);
+			_ng_sorting.criteria = ld->sort_type;
+			SetWindowDirty(w);
+			break;
+		case 9: { /* Matrix to show networkgames */
+			NetworkGameList *cur_item;
+			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
+
+			if (id_v >= w->vscroll.cap) return; // click out of bounds
+			id_v += w->vscroll.pos;
+
+			cur_item = _network_game_list;
+			for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
+
+			nd->server = cur_item;
+			SetWindowDirty(w);
+		} break;
+		case 11: /* Find server automatically */
+			switch (_network_lan_internet) {
+				case 0: NetworkUDPSearchGame(); break;
+				case 1: NetworkUDPQueryMasterServer(); break;
+			}
+			break;
+		case 12: { // Add a server
+				ShowQueryString(
+				BindCString(_network_default_ip),
+				STR_NETWORK_ENTER_IP,
+				31 | 0x1000,  // maximum number of characters OR
+				250, // characters up to this width pixels, whichever is satisfied first
+				w, CS_ALPHANUMERAL);
+		} break;
+		case 13: /* Start server */
+			ShowNetworkStartServerWindow();
+			break;
+		case 16: /* Join Game */
+			if (nd->server != NULL) {
+				snprintf(_network_last_host, sizeof(_network_last_host), "%s", inet_ntoa(*(struct in_addr *)&nd->server->ip));
+				_network_last_port = nd->server->port;
+				ShowNetworkLobbyWindow(nd->server);
+			}
+			break;
+		case 17: // Refresh
+			if (nd->server != NULL)
+				NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
+			break;
+		case 18: // NewGRF Settings
+			if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
+			break;
+
+	}	break;
+
+	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+		switch (e->we.dropdown.button) {
+			case 5:
+				_network_lan_internet = e->we.dropdown.index;
+				break;
+		}
+
+		SetWindowDirty(w);
+		break;
+
+	case WE_MOUSELOOP:
+		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
+		break;
+
+	case WE_MESSAGE:
+		if (e->we.message.msg != 0) nd->server = NULL;
+		ld->flags |= VL_REBUILD;
+		SetWindowDirty(w);
+		break;
+
+	case WE_KEYPRESS:
+		if (nd->field != 3) {
+			if (nd->server != NULL) {
+				if (e->we.keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
+					NetworkGameListRemoveItem(nd->server);
+					NetworkRebuildHostList();
+					nd->server = NULL;
+				}
+			}
+			break;
+		}
+
+		if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
+
+		// The name is only allowed when it starts with a letter!
+		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
+			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
+		} else {
+			ttd_strlcpy(_network_player_name, "Player", lengthof(_network_player_name));
+		}
+
+		break;
+
+	case WE_ON_EDIT_TEXT:
+		NetworkAddServer(e->we.edittext.str);
+		NetworkRebuildHostList();
+		break;
+
+	case WE_DESTROY: /* Nicely clean up the sort-list */
+		free(WP(w, network_ql_d).sort_list);
+		break;
+	}
+}
+
+static const Widget _network_game_window_widgets[] = {
+{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
+{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   549,     0,    13, STR_NETWORK_MULTIPLAYER,     STR_NULL},
+{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   549,    14,   263, 0x0,                         STR_NULL},
+
+/* LEFT SIDE */
+{      WWT_PANEL,   RESIZE_NONE,   BGC,   310,   461,    22,    33, 0x0,                         STR_NETWORK_ENTER_NAME_TIP},
+
+{      WWT_INSET,   RESIZE_NONE,   BGC,    90,   181,    22,    33, STR_NETWORK_COMBO1,          STR_NETWORK_CONNECTION_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   170,   180,    23,    32, STR_0225,                    STR_NETWORK_CONNECTION_TIP},
+
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   170,    42,    53, STR_NETWORK_GAME_NAME,       STR_NETWORK_GAME_NAME_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   171,   250,    42,    53, STR_NETWORK_CLIENTS_CAPTION, STR_NETWORK_CLIENTS_CAPTION_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   251,   290,    42,    53, STR_EMPTY,                   STR_NETWORK_INFO_ICONS_TIP},
+
+{     WWT_MATRIX,   RESIZE_NONE,   BGC,    10,   290,    54,   236, (13 << 8) + 1,               STR_NETWORK_CLICK_GAME_TO_SELECT},
+{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   291,   302,    42,   236, STR_NULL,                    STR_0190_SCROLL_BAR_SCROLLS_LIST},
+
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    30,   130,   246,   257, STR_NETWORK_FIND_SERVER,     STR_NETWORK_FIND_SERVER_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   180,   280,   246,   257, STR_NETWORK_ADD_SERVER,      STR_NETWORK_ADD_SERVER_TIP},
+
+/* RIGHT SIDE */
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   315,   415,   246,   257, STR_NETWORK_START_SERVER,    STR_NETWORK_START_SERVER_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   246,   257, STR_012E_CANCEL,             STR_NULL},
+
+{      WWT_PANEL,   RESIZE_NONE,   BGC,   310,   540,    42,   236, 0x0,                         STR_NULL},
+
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   315,   415,   215,   226, STR_NETWORK_JOIN_GAME,       STR_NULL},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   215,   226, STR_NETWORK_REFRESH,         STR_NETWORK_REFRESH_TIP},
+
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   197,   208, STR_NEWGRF_SETTINGS_BUTTON,  STR_NULL},
+
+{   WIDGETS_END},
+};
+
+static const WindowDesc _network_game_window_desc = {
+	WDP_CENTER, WDP_CENTER, 550, 264,
+	WC_NETWORK_WINDOW,0,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+	_network_game_window_widgets,
+	NetworkGameWindowWndProc,
+};
+
+void ShowNetworkGameWindow(void)
+{
+	static bool first = true;
+	Window *w;
+	DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+	/* Only show once */
+	if (first) {
+		char* const *srv;
+
+		first = false;
+		// add all servers from the config file to our list
+		for (srv = &_network_host_list[0]; srv != endof(_network_host_list) && *srv != NULL; srv++) {
+			NetworkAddServer(*srv);
+		}
+
+		_ng_sorting.criteria = 2; // sort default by collectivity (green-dots on top)
+		_ng_sorting.order = 0;    // sort ascending by default
+	}
+
+	w = AllocateWindowDesc(&_network_game_window_desc);
+	if (w != NULL) {
+		querystr_d *querystr = &WP(w, network_ql_d).q;
+
+		ttd_strlcpy(_edit_str_buf, _network_player_name, lengthof(_edit_str_buf));
+		w->vscroll.cap = 13;
+
+		querystr->afilter = CS_ALPHANUMERAL;
+		InitializeTextBuffer(&querystr->text, _edit_str_buf, lengthof(_edit_str_buf), 120);
+
+		UpdateNetworkGameWindow(true);
+	}
+}
+
+enum {
+	NSSWND_START = 64,
+	NSSWND_ROWSIZE = 12
+};
+
+/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
+static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
+{
+	network_d *nd = &WP(w, network_ql_d).n;
+
+	switch (e->event) {
+	case WE_CREATE: /* focus input box */
+		nd->field = 3;
+		_network_game_info.use_password = (_network_server_password[0] != '\0');
+		break;
+
+	case WE_PAINT: {
+		int y = NSSWND_START, pos;
+		const FiosItem *item;
+
+		SetDParam( 7, _connection_types_dropdown[_network_advertise]);
+		SetDParam( 9, _players_dropdown[_network_game_info.clients_max]);
+		SetDParam(11, _players_dropdown[_network_game_info.companies_max]);
+		SetDParam(13, _players_dropdown[_network_game_info.spectators_max]);
+		SetDParam(15, _language_dropdown[_network_game_info.server_lang]);
+		DrawWindowWidgets(w);
+
+		GfxFillRect(11, 63, 258, 215, 0xD7);
+		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
+
+		DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
+
+		DrawString(10, 43, STR_NETWORK_SELECT_MAP, 2);
+
+		DrawString(280,  63, STR_NETWORK_CONNECTION, 2);
+		DrawString(280,  95, STR_NETWORK_NUMBER_OF_CLIENTS, 2);
+		DrawString(280, 127, STR_NETWORK_NUMBER_OF_COMPANIES, 2);
+		DrawString(280, 159, STR_NETWORK_NUMBER_OF_SPECTATORS, 2);
+		DrawString(280, 191, STR_NETWORK_LANGUAGE_SPOKEN, 2);
+
+		if (_network_game_info.use_password) DoDrawString("*", 408, 23, 3);
+
+		// draw list of maps
+		pos = w->vscroll.pos;
+		while (pos < _fios_num + 1) {
+			item = _fios_list + pos - 1;
+			if (item == nd->map || (pos == 0 && nd->map == NULL))
+				GfxFillRect(11, y - 1, 258, y + 10, 155); // show highlighted item with a different colour
+
+			if (pos == 0) {
+				DrawString(14, y, STR_4010_GENERATE_RANDOM_NEW_GAME, 9);
+			} else {
+				DoDrawString(item->title, 14, y, _fios_colors[item->type] );
+			}
+			pos++;
+			y += NSSWND_ROWSIZE;
+
+			if (y >= w->vscroll.cap * NSSWND_ROWSIZE + NSSWND_START) break;
+		}
+	}	break;
+
+	case WE_CLICK:
+		nd->field = e->we.click.widget;
+		switch (e->we.click.widget) {
+		case 0: /* Close 'X' */
+		case 19: /* Cancel button */
+			ShowNetworkGameWindow();
+			break;
+
+		case 4: /* Set password button */
+			ShowQueryString(BindCString(_network_server_password), STR_NETWORK_SET_PASSWORD, 20, 250, w, CS_ALPHANUMERAL);
+			break;
+
+		case 5: { /* Select map */
+			int y = (e->we.click.pt.y - NSSWND_START) / NSSWND_ROWSIZE;
+
+			y += w->vscroll.pos;
+			if (y >= w->vscroll.count) return;
+
+			nd->map = (y == 0) ? NULL : _fios_list + y - 1;
+			SetWindowDirty(w);
+			} break;
+		case 7: case 8: /* Connection type */
+			ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8
+			break;
+		case 9: case 10: /* Number of Players (hide 0 and 1 players) */
+			ShowDropDownMenu(w, _players_dropdown, _network_game_info.clients_max, 10, 0, 3);
+			break;
+		case 11: case 12: /* Number of Companies (hide 0, 9 and 10 companies; max is 8) */
+			ShowDropDownMenu(w, _players_dropdown, _network_game_info.companies_max, 12, 0, 1537);
+			break;
+		case 13: case 14: /* Number of Spectators */
+			ShowDropDownMenu(w, _players_dropdown, _network_game_info.spectators_max, 14, 0, 0);
+			break;
+		case 15: case 16: /* Language */
+			ShowDropDownMenu(w, _language_dropdown, _network_game_info.server_lang, 16, 0, 0);
+			break;
+		case 17: /* Start game */
+			_is_network_server = true;
+
+			if (nd->map == NULL) { // start random new game
+				ShowGenerateLandscape();
+			} else { // load a scenario
+				char *name = FiosBrowseTo(nd->map);
+				if (name != NULL) {
+					SetFiosType(nd->map->type);
+					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+					ttd_strlcpy(_file_to_saveload.title, nd->map->title, sizeof(_file_to_saveload.title));
+
+					DeleteWindow(w);
+					SwitchMode(SM_START_SCENARIO);
+				}
+			}
+			break;
+		case 18: /* Load game */
+			_is_network_server = true;
+			/* XXX - WC_NETWORK_WINDOW should stay, but if it stays, it gets
+			 * copied all the elements of 'load game' and upon closing that, it segfaults */
+			DeleteWindowById(WC_NETWORK_WINDOW, 0);
+			ShowSaveLoadDialog(SLD_LOAD_GAME);
+			break;
+		}
+		break;
+
+	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
+		switch (e->we.dropdown.button) {
+			case  8: _network_advertise                = (e->we.dropdown.index != 0); break;
+			case 10: _network_game_info.clients_max    = e->we.dropdown.index;        break;
+			case 12: _network_game_info.companies_max  = e->we.dropdown.index;        break;
+			case 14: _network_game_info.spectators_max = e->we.dropdown.index;        break;
+			case 16: _network_game_info.server_lang    = e->we.dropdown.index;        break;
+		}
+
+		SetWindowDirty(w);
+		break;
+
+	case WE_MOUSELOOP:
+		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
+		break;
+
+	case WE_KEYPRESS:
+		if (nd->field == 3) {
+			if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
+
+			ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
+			UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
+		}
+		break;
+
+	case WE_ON_EDIT_TEXT: {
+		ttd_strlcpy(_network_server_password, e->we.edittext.str, lengthof(_network_server_password));
+		_network_game_info.use_password = (_network_server_password[0] != '\0');
+		SetWindowDirty(w);
+	} break;
+	}
+}
+
+static const Widget _network_start_server_window_widgets[] = {
+{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                      STR_018B_CLOSE_WINDOW },
+{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   419,     0,    13, STR_NETWORK_START_GAME_WINDOW, STR_NULL},
+{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   419,    14,   243, 0x0,                           STR_NULL},
+
+{      WWT_PANEL,   RESIZE_NONE,   BGC,   100,   272,    22,    33, 0x0,                           STR_NETWORK_NEW_GAME_NAME_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   285,   405,    22,    33, STR_NETWORK_SET_PASSWORD,      STR_NETWORK_PASSWORD_TIP},
+
+{      WWT_INSET,   RESIZE_NONE,   BGC,    10,   271,    62,   216, 0x0,                           STR_NETWORK_SELECT_MAP_TIP},
+{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   259,   270,    63,   215, 0x0,                           STR_0190_SCROLL_BAR_SCROLLS_LIST},
+/* Combo boxes to control Connection Type / Max Clients / Max Companies / Max Observers / Language */
+{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,    77,    88, STR_NETWORK_COMBO1,            STR_NETWORK_CONNECTION_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,    78,    87, STR_0225,                      STR_NETWORK_CONNECTION_TIP},
+{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   109,   120, STR_NETWORK_COMBO2,            STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   110,   119, STR_0225,                      STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
+{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   141,   152, STR_NETWORK_COMBO3,            STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   142,   151, STR_0225,                      STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
+{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   173,   184, STR_NETWORK_COMBO4,            STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   174,   183, STR_0225,                      STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
+{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   205,   216, STR_NETWORK_COMBO5,            STR_NETWORK_LANGUAGE_TIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   206,   215, STR_0225,                      STR_NETWORK_LANGUAGE_TIP},
+
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    40,   140,   224,   235, STR_NETWORK_START_GAME,        STR_NETWORK_START_GAME_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   150,   250,   224,   235, STR_NETWORK_LOAD_GAME,         STR_NETWORK_LOAD_GAME_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   260,   360,   224,   235, STR_012E_CANCEL,               STR_NULL},
+{   WIDGETS_END},
+};
+
+static const WindowDesc _network_start_server_window_desc = {
+	WDP_CENTER, WDP_CENTER, 420, 244,
+	WC_NETWORK_WINDOW,0,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+	_network_start_server_window_widgets,
+	NetworkStartServerWindowWndProc,
+};
+
+static void ShowNetworkStartServerWindow(void)
+{
+	Window *w;
+	DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+	w = AllocateWindowDesc(&_network_start_server_window_desc);
+	ttd_strlcpy(_edit_str_buf, _network_server_name, lengthof(_edit_str_buf));
+
+	_saveload_mode = SLD_NEW_GAME;
+	BuildFileList();
+	w->vscroll.cap = 12;
+	w->vscroll.count = _fios_num+1;
+
+	WP(w, network_ql_d).q.afilter = CS_ALPHANUMERAL;
+	InitializeTextBuffer(&WP(w, network_ql_d).q.text, _edit_str_buf, lengthof(_edit_str_buf), 160);
+}
+
+static byte NetworkLobbyFindCompanyIndex(byte pos)
+{
+	byte i;
+
+	/* Scroll through all _network_player_info and get the 'pos' item
+	    that is not empty */
+	for (i = 0; i < MAX_PLAYERS; i++) {
+		if (_network_player_info[i].company_name[0] != '\0') {
+			if (pos-- == 0) return i;
+		}
+	}
+
+	return 0;
+}
+
+/* uses network_d WP macro */
+static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
+{
+	network_d *nd = &WP(w, network_d);
+
+	switch (e->event) {
+	case WE_CREATE:
+		nd->company = (byte)-1;
+		break;
+
+	case WE_PAINT: {
+		const NetworkGameInfo *gi = &nd->server->info;
+		int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY, pos;
+
+		SetWindowWidgetDisabledState(w, 7, nd->company == (byte)-1);
+		SetWindowWidgetDisabledState(w, 8, gi->companies_on >= gi->companies_max);
+		/* You can not join a server as spectator when it has no companies active..
+		 * it causes some nasty crashes */
+		SetWindowWidgetDisabledState(w, 9, gi->spectators_on >= gi->spectators_max ||
+				gi->companies_on == 0);
+
+		DrawWindowWidgets(w);
+
+		SetDParamStr(0, gi->server_name);
+		DrawString(10, 22, STR_NETWORK_PREPARE_TO_JOIN, 2);
+
+		/* Draw company list */
+		pos = w->vscroll.pos;
+		while (pos < gi->companies_on) {
+			byte company = NetworkLobbyFindCompanyIndex(pos);
+			bool income = false;
+			if (nd->company == company)
+				GfxFillRect(11, y - 1, 154, y + 10, 10); // show highlighted item with a different colour
+
+			DoDrawStringTruncated(_network_player_info[company].company_name, 13, y, 16, 135 - 13);
+			if (_network_player_info[company].use_password != 0) DrawSprite(SPR_LOCK, 135, y);
+
+			/* If the company's income was positive puts a green dot else a red dot */
+			if (_network_player_info[company].income >= 0) income = true;
+			DrawSprite(SPR_BLOT | (income ? PALETTE_TO_GREEN : PALETTE_TO_RED), 145, y);
+
+			pos++;
+			y += NET_PRC__SIZE_OF_ROW;
+			if (pos >= w->vscroll.cap) break;
+		}
+
+		/* Draw info about selected company when it is selected in the left window */
+		GfxFillRect(174, 39, 403, 75, 157);
+		DrawStringCentered(290, 50, STR_NETWORK_COMPANY_INFO, 0);
+		if (nd->company != (byte)-1) {
+			const uint x = 183;
+			const uint trunc_width = w->widget[6].right - x;
+			y = 80;
+
+			SetDParam(0, nd->server->info.clients_on);
+			SetDParam(1, nd->server->info.clients_max);
+			SetDParam(2, nd->server->info.companies_on);
+			SetDParam(3, nd->server->info.companies_max);
+			DrawString(x, y, STR_NETWORK_CLIENTS, 2);
+			y += 10;
+
+			SetDParamStr(0, _network_player_info[nd->company].company_name);
+			DrawStringTruncated(x, y, STR_NETWORK_COMPANY_NAME, 2, trunc_width);
+			y += 10;
+
+			SetDParam(0, _network_player_info[nd->company].inaugurated_year);
+			DrawString(x, y, STR_NETWORK_INAUGURATION_YEAR, 2); // inauguration year
+			y += 10;
+
+			SetDParam64(0, _network_player_info[nd->company].company_value);
+			DrawString(x, y, STR_NETWORK_VALUE, 2); // company value
+			y += 10;
+
+			SetDParam64(0, _network_player_info[nd->company].money);
+			DrawString(x, y, STR_NETWORK_CURRENT_BALANCE, 2); // current balance
+			y += 10;
+
+			SetDParam64(0, _network_player_info[nd->company].income);
+			DrawString(x, y, STR_NETWORK_LAST_YEARS_INCOME, 2); // last year's income
+			y += 10;
+
+			SetDParam(0, _network_player_info[nd->company].performance);
+			DrawString(x, y, STR_NETWORK_PERFORMANCE, 2); // performance
+			y += 10;
+
+			SetDParam(0, _network_player_info[nd->company].num_vehicle[0]);
+			SetDParam(1, _network_player_info[nd->company].num_vehicle[1]);
+			SetDParam(2, _network_player_info[nd->company].num_vehicle[2]);
+			SetDParam(3, _network_player_info[nd->company].num_vehicle[3]);
+			SetDParam(4, _network_player_info[nd->company].num_vehicle[4]);
+			DrawString(x, y, STR_NETWORK_VEHICLES, 2); // vehicles
+			y += 10;
+
+			SetDParam(0, _network_player_info[nd->company].num_station[0]);
+			SetDParam(1, _network_player_info[nd->company].num_station[1]);
+			SetDParam(2, _network_player_info[nd->company].num_station[2]);
+			SetDParam(3, _network_player_info[nd->company].num_station[3]);
+			SetDParam(4, _network_player_info[nd->company].num_station[4]);
+			DrawString(x, y, STR_NETWORK_STATIONS, 2); // stations
+			y += 10;
+
+			SetDParamStr(0, _network_player_info[nd->company].players);
+			DrawStringTruncated(x, y, STR_NETWORK_PLAYERS, 2, trunc_width); // players
+		}
+	}	break;
+
+	case WE_CLICK:
+		switch (e->we.click.widget) {
+		case 0: case 11: /* Close 'X' | Cancel button */
+			ShowNetworkGameWindow();
+			break;
+		case 4: { /* Company list */
+			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET_COMPANY) / NET_PRC__SIZE_OF_ROW;
+
+			if (id_v >= w->vscroll.cap) return;
+
+			id_v += w->vscroll.pos;
+			nd->company = (id_v >= nd->server->info.companies_on) ? (byte)-1 : NetworkLobbyFindCompanyIndex(id_v);
+			SetWindowDirty(w);
+		}	break;
+		case 7: /* Join company */
+			if (nd->company != (byte)-1) {
+				_network_playas = nd->company;
+				NetworkClientConnectGame(_network_last_host, _network_last_port);
+			}
+			break;
+		case 8: /* New company */
+			_network_playas = PLAYER_NEW_COMPANY;
+			NetworkClientConnectGame(_network_last_host, _network_last_port);
+			break;
+		case 9: /* Spectate game */
+			_network_playas = PLAYER_SPECTATOR;
+			NetworkClientConnectGame(_network_last_host, _network_last_port);
+			break;
+		case 10: /* Refresh */
+			NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
+			NetworkUDPQueryServer(_network_last_host, _network_last_port);     // general data
+			break;
+		}	break;
+
+	case WE_MESSAGE:
+		SetWindowDirty(w);
+		break;
+	}
+}
+
+static const Widget _network_lobby_window_widgets[] = {
+{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                  STR_018B_CLOSE_WINDOW },
+{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   419,     0,    13, STR_NETWORK_GAME_LOBBY,    STR_NULL},
+{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   419,    14,   234, 0x0,                       STR_NULL},
+
+// company list
+{      WWT_PANEL,   RESIZE_NONE,   BTC,    10,   155,    38,    49, 0x0,                       STR_NULL},
+{     WWT_MATRIX,   RESIZE_NONE,   BGC,    10,   155,    50,   190, (10 << 8) + 1,             STR_NETWORK_COMPANY_LIST_TIP},
+{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   156,   167,    38,   190, STR_NULL,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
+
+// company/player info
+{      WWT_PANEL,   RESIZE_NONE,   BGC,   173,   404,    38,   190, 0x0,                       STR_NULL},
+
+// buttons
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   151,   200,   211, STR_NETWORK_JOIN_COMPANY,  STR_NETWORK_JOIN_COMPANY_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   151,   215,   226, STR_NETWORK_NEW_COMPANY,   STR_NETWORK_NEW_COMPANY_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   158,   268,   200,   211, STR_NETWORK_SPECTATE_GAME, STR_NETWORK_SPECTATE_GAME_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   158,   268,   215,   226, STR_NETWORK_REFRESH,       STR_NETWORK_REFRESH_TIP},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   278,   388,   200,   211, STR_012E_CANCEL,           STR_NULL},
+
+{   WIDGETS_END},
+};
+
+static const WindowDesc _network_lobby_window_desc = {
+	WDP_CENTER, WDP_CENTER, 420, 235,
+	WC_NETWORK_WINDOW,0,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+	_network_lobby_window_widgets,
+	NetworkLobbyWindowWndProc,
+};
+
+/* Show the networklobbywindow with the selected server
+ * @param ngl Selected game pointer which is passed to the new window */
+static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
+{
+	Window *w;
+	DeleteWindowById(WC_NETWORK_WINDOW, 0);
+
+	NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
+	NetworkUDPQueryServer(_network_last_host, _network_last_port);     // general data
+
+	w = AllocateWindowDesc(&_network_lobby_window_desc);
+	if (w != NULL) {
+		WP(w, network_ql_d).n.server = ngl;
+		strcpy(_edit_str_buf, "");
+		w->vscroll.cap = 10;
+	}
+}
+
+// The window below gives information about the connected clients
+//  and also makes able to give money to them, kick them (if server)
+//  and stuff like that.
+
+extern void DrawPlayerIcon(PlayerID pid, int x, int y);
+
+// Every action must be of this form
+typedef void ClientList_Action_Proc(byte client_no);
+
+// Max 10 actions per client
+#define MAX_CLIENTLIST_ACTION 10
+
+// Some standard bullshit.. defines variables ;)
+static void ClientListWndProc(Window *w, WindowEvent *e);
+static void ClientListPopupWndProc(Window *w, WindowEvent *e);
+static byte _selected_clientlist_item = 255;
+static byte _selected_clientlist_y = 0;
+static char _clientlist_action[MAX_CLIENTLIST_ACTION][50];
+static ClientList_Action_Proc *_clientlist_proc[MAX_CLIENTLIST_ACTION];
+
+enum {
+	CLNWND_OFFSET = 16,
+	CLNWND_ROWSIZE = 10
+};
+
+static const Widget _client_list_widgets[] = {
+{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                 STR_018B_CLOSE_WINDOW},
+{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   249,     0,    13, STR_NETWORK_CLIENT_LIST,  STR_018C_WINDOW_TITLE_DRAG_THIS},
+
+{      WWT_PANEL,   RESIZE_NONE,    14,     0,   249,    14,    14 + CLNWND_ROWSIZE + 1, 0x0, STR_NULL},
+{   WIDGETS_END},
+};
+
+static const Widget _client_list_popup_widgets[] = {
+{      WWT_PANEL,   RESIZE_NONE,    14,     0,   99,     0,     0,     0, STR_NULL},
+{   WIDGETS_END},
+};
+
+static WindowDesc _client_list_desc = {
+	WDP_AUTO, WDP_AUTO, 250, 1,
+	WC_CLIENT_LIST,0,
+	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+	_client_list_widgets,
+	ClientListWndProc
+};
+
+// Finds the Xth client-info that is active
+static const NetworkClientInfo *NetworkFindClientInfo(byte client_no)
+{
+	const NetworkClientInfo *ci;
+
+	FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+		if (client_no == 0) return ci;
+		client_no--;
+	}
+
+	return NULL;
+}
+
+// Here we start to define the options out of the menu
+static void ClientList_Kick(byte client_no)
+{
+	if (client_no < MAX_PLAYERS)
+		SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
+}
+
+static void ClientList_Ban(byte client_no)
+{
+	uint i;
+	uint32 ip = NetworkFindClientInfo(client_no)->client_ip;
+
+	for (i = 0; i < lengthof(_network_ban_list); i++) {
+		if (_network_ban_list[i] == NULL) {
+			_network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ip));
+			break;
+		}
+	}
+
+	if (client_no < MAX_PLAYERS)
+		SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
+}
+
+static void ClientList_GiveMoney(byte client_no)
+{
+	if (NetworkFindClientInfo(client_no) != NULL)
+		ShowNetworkGiveMoneyWindow(NetworkFindClientInfo(client_no)->client_playas);
+}
+
+static void ClientList_SpeakToClient(byte client_no)
+{
+	if (NetworkFindClientInfo(client_no) != NULL)
+		ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, NetworkFindClientInfo(client_no)->client_index);
+}
+
+static void ClientList_SpeakToCompany(byte client_no)
+{
+	if (NetworkFindClientInfo(client_no) != NULL)
+		ShowNetworkChatQueryWindow(DESTTYPE_TEAM, NetworkFindClientInfo(client_no)->client_playas);
+}
+
+static void ClientList_SpeakToAll(byte client_no)
+{
+	ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
+}
+
+static void ClientList_None(byte client_no)
+{
+	// No action ;)
+}
+
+
+
+// Help, a action is clicked! What do we do?
+static void HandleClientListPopupClick(byte index, byte clientno) {
+	// A click on the Popup of the ClientList.. handle the command
+	if (index < MAX_CLIENTLIST_ACTION && _clientlist_proc[index] != NULL) {
+		_clientlist_proc[index](clientno);
+	}
+}
+
+// Finds the amount of clients and set the height correct
+static bool CheckClientListHeight(Window *w)
+{
+	int num = 0;
+	const NetworkClientInfo *ci;
+
+	// Should be replaced with a loop through all clients
+	FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+		num++;
+	}
+
+	num *= CLNWND_ROWSIZE;
+
+	// If height is changed
+	if (w->height != CLNWND_OFFSET + num + 1) {
+		// XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1)
+		SetWindowDirty(w);
+		w->widget[2].bottom = w->widget[2].top + num + 2;
+		w->height = CLNWND_OFFSET + num + 1;
+		SetWindowDirty(w);
+		return false;
+	}
+	return true;
+}
+
+// Finds the amount of actions in the popup and set the height correct
+static uint ClientListPopupHeigth(void) {
+	int i, num = 0;
+
+	// Find the amount of actions
+	for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
+		if (_clientlist_action[i][0] == '\0') continue;
+		if (_clientlist_proc[i] == NULL) continue;
+		num++;
+	}
+
+	num *= CLNWND_ROWSIZE;
+
+	return num + 1;
+}
+
+// Show the popup (action list)
+static Window *PopupClientList(Window *w, int client_no, int x, int y)
+{
+	int i, h;
+	const NetworkClientInfo *ci;
+	DeleteWindowById(WC_TOOLBAR_MENU, 0);
+
+	// Clean the current actions
+	for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
+		_clientlist_action[i][0] = '\0';
+		_clientlist_proc[i] = NULL;
+	}
+
+	// Fill the actions this client has
+	// Watch is, max 50 chars long!
+
+	ci = NetworkFindClientInfo(client_no);
+	if (ci == NULL) return NULL;
+
+	i = 0;
+	if (_network_own_client_index != ci->client_index) {
+		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(_clientlist_action[i]));
+		_clientlist_proc[i++] = &ClientList_SpeakToClient;
+	}
+
+	if (IsValidPlayer(ci->client_playas) || ci->client_playas == PLAYER_SPECTATOR) {
+		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(_clientlist_action[i]));
+		_clientlist_proc[i++] = &ClientList_SpeakToCompany;
+	}
+	GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(_clientlist_action[i]));
+	_clientlist_proc[i++] = &ClientList_SpeakToAll;
+
+	if (_network_own_client_index != ci->client_index) {
+		/* We are no spectator and the player we want to give money to is no spectator */
+		if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas)) {
+			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i]));
+			_clientlist_proc[i++] = &ClientList_GiveMoney;
+		}
+	}
+
+	// A server can kick clients (but not himself)
+	if (_network_server && _network_own_client_index != ci->client_index) {
+		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(_clientlist_action[i]));
+		_clientlist_proc[i++] = &ClientList_Kick;
+
+		sprintf(_clientlist_action[i],"Ban"); // XXX GetString?
+		_clientlist_proc[i++] = &ClientList_Ban;
+	}
+
+	if (i == 0) {
+		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i]));
+		_clientlist_proc[i++] = &ClientList_None;
+	}
+
+	/* Calculate the height */
+	h = ClientListPopupHeigth();
+
+	// Allocate the popup
+	w = AllocateWindow(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets);
+	w->widget[0].bottom = w->widget[0].top + h;
+	w->widget[0].right = w->widget[0].left + 150;
+
+	w->flags4 &= ~WF_WHITE_BORDER_MASK;
+	WP(w,menu_d).item_count = 0;
+	// Save our client
+	WP(w,menu_d).main_button = client_no;
+	WP(w,menu_d).sel_index = 0;
+	// We are a popup
+	_popup_menu_active = true;
+
+	return w;
+}
+
+/** Main handle for the client popup list
+ * uses menu_d WP macro */
+static void ClientListPopupWndProc(Window *w, WindowEvent *e)
+{
+	switch (e->event) {
+	case WE_PAINT: {
+		int i, y, sel;
+		byte colour;
+		DrawWindowWidgets(w);
+
+		// Draw the actions
+		sel = WP(w,menu_d).sel_index;
+		y = 1;
+		for (i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += CLNWND_ROWSIZE) {
+			if (_clientlist_action[i][0] == '\0') continue;
+			if (_clientlist_proc[i] == NULL) continue;
+
+			if (sel-- == 0) { // Selected item, highlight it
+				GfxFillRect(1, y, 150 - 2, y + CLNWND_ROWSIZE - 1, 0);
+				colour = 0xC;
+			} else {
+				colour = 0x10;
+			}
+
+			DoDrawString(_clientlist_action[i], 4, y, colour);
+		}
+	}	break;
+
+	case WE_POPUPMENU_SELECT: {
+		// We selected an action
+		int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
+
+		if (index >= 0 && e->we.popupmenu.pt.y >= w->top)
+			HandleClientListPopupClick(index, WP(w,menu_d).main_button);
+
+		DeleteWindowById(WC_TOOLBAR_MENU, 0);
+	}	break;
+
+	case WE_POPUPMENU_OVER: {
+		// Our mouse hoovers over an action? Select it!
+		int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
+
+		if (index == -1 || index == WP(w,menu_d).sel_index) return;
+
+		WP(w,menu_d).sel_index = index;
+		SetWindowDirty(w);
+	} break;
+
+	}
+}
+
+// Main handle for clientlist
+static void ClientListWndProc(Window *w, WindowEvent *e)
+{
+	switch (e->event) {
+	case WE_PAINT: {
+		NetworkClientInfo *ci;
+		int y, i = 0;
+		byte colour;
+
+		// Check if we need to reset the height
+		if (!CheckClientListHeight(w)) break;
+
+		DrawWindowWidgets(w);
+
+		y = CLNWND_OFFSET;
+
+		FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
+			if (_selected_clientlist_item == i++) { // Selected item, highlight it
+				GfxFillRect(1, y, 248, y + CLNWND_ROWSIZE - 1, 0);
+				colour = 0xC;
+			} else {
+				colour = 0x10;
+			}
+
+			if (ci->client_index == NETWORK_SERVER_INDEX) {
+				DrawString(4, y, STR_NETWORK_SERVER, colour);
+			} else {
+				DrawString(4, y, STR_NETWORK_CLIENT, colour);
+			}
+
+			// Filter out spectators
+			if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1);
+
+			DoDrawString(ci->client_name, 81, y, colour);
+
+			y += CLNWND_ROWSIZE;
+		}
+	}	break;
+
+	case WE_CLICK:
+		// Show the popup with option
+		if (_selected_clientlist_item != 255) {
+			PopupClientList(w, _selected_clientlist_item, e->we.click.pt.x + w->left, e->we.click.pt.y + w->top);
+		}
+
+		break;
+
+	case WE_MOUSEOVER:
+		// -1 means we left the current window
+		if (e->we.mouseover.pt.y == -1) {
+			_selected_clientlist_y = 0;
+			_selected_clientlist_item = 255;
+			SetWindowDirty(w);
+			break;
+		}
+		// It did not change.. no update!
+		if (e->we.mouseover.pt.y == _selected_clientlist_y) break;
+
+		// Find the new selected item (if any)
+		_selected_clientlist_y = e->we.mouseover.pt.y;
+		if (e->we.mouseover.pt.y > CLNWND_OFFSET) {
+			_selected_clientlist_item = (e->we.mouseover.pt.y - CLNWND_OFFSET) / CLNWND_ROWSIZE;
+		} else {
+			_selected_clientlist_item = 255;
+		}
+
+		// Repaint
+		SetWindowDirty(w);
+		break;
+
+	case WE_DESTROY: case WE_CREATE:
+		// When created or destroyed, data is reset
+		_selected_clientlist_item = 255;
+		_selected_clientlist_y = 0;
+		break;
+	}
+}
+
+void ShowClientList(void)
+{
+	AllocateWindowDescFront(&_client_list_desc, 0);
+}
+
+
+static NetworkPasswordType pw_type;
+
+
+void ShowNetworkNeedPassword(NetworkPasswordType npt)
+{
+	StringID caption;
+
+	pw_type = npt;
+	switch (npt) {
+		default: NOT_REACHED();
+		case NETWORK_GAME_PASSWORD:    caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break;
+		case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break;
+	}
+	ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL);
+}
+
+
+static void NetworkJoinStatusWindowWndProc(Window *w, WindowEvent *e)
+{
+	switch (e->event) {
+	case WE_PAINT: {
+		uint8 progress; // used for progress bar
+		DrawWindowWidgets(w);
+
+		DrawStringCentered(125, 35, STR_NETWORK_CONNECTING_1 + _network_join_status, 14);
+		switch (_network_join_status) {
+			case NETWORK_JOIN_STATUS_CONNECTING: case NETWORK_JOIN_STATUS_AUTHORIZING:
+			case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO:
+				progress = 10; // first two stages 10%
+				break;
+			case NETWORK_JOIN_STATUS_WAITING:
+				SetDParam(0, _network_join_waiting);
+				DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_WAITING, 14);
+				progress = 15; // third stage is 15%
+				break;
+			case NETWORK_JOIN_STATUS_DOWNLOADING:
+				SetDParam(0, _network_join_kbytes);
+				SetDParam(1, _network_join_kbytes_total);
+				DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_DOWNLOADING, 14);
+				/* Fallthrough */
+			default: /* Waiting is 15%, so the resting receivement of map is maximum 70% */
+				progress = 15 + _network_join_kbytes * (100 - 15) / _network_join_kbytes_total;
+		}
+
+		/* Draw nice progress bar :) */
+		DrawFrameRect(20, 18, (int)((w->width - 20) * progress / 100), 28, 10, 0);
+	}	break;
+
+	case WE_CLICK:
+		switch (e->we.click.widget) {
+			case 2: /* Disconnect button */
+				NetworkDisconnect();
+				DeleteWindow(w);
+				SwitchMode(SM_MENU);
+				ShowNetworkGameWindow();
+				break;
+		}
+		break;
+
+		/* If the server asks for a password, we need to fill it in */
+		case WE_ON_EDIT_TEXT_CANCEL:
+			NetworkDisconnect();
+			ShowNetworkGameWindow();
+			break;
+
+		case WE_ON_EDIT_TEXT:
+			SEND_COMMAND(PACKET_CLIENT_PASSWORD)(pw_type, e->we.edittext.str);
+			break;
+	}
+}
+
+static const Widget _network_join_status_window_widget[] = {
+{    WWT_CAPTION,   RESIZE_NONE,    14,     0,   249,     0,    13, STR_NETWORK_CONNECTING, STR_018C_WINDOW_TITLE_DRAG_THIS},
+{      WWT_PANEL,   RESIZE_NONE,    14,     0,   249,    14,    84, 0x0,                    STR_NULL},
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    75,   175,    69,    80, STR_NETWORK_DISCONNECT, STR_NULL},
+{   WIDGETS_END},
+};
+
+static const WindowDesc _network_join_status_window_desc = {
+	WDP_CENTER, WDP_CENTER, 250, 85,
+	WC_NETWORK_STATUS_WINDOW, 0,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_MODAL,
+	_network_join_status_window_widget,
+	NetworkJoinStatusWindowWndProc,
+};
+
+void ShowJoinStatusWindow(void)
+{
+	Window *w;
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+	w = AllocateWindowDesc(&_network_join_status_window_desc);
+	/* Parent the status window to the lobby */
+	if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0);
+}
+
+static void SendChat(const char *buf, DestType type, byte dest)
+{
+	if (buf[0] == '\0') return;
+	if (!_network_server) {
+		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT + type, type, dest, buf);
+	} else {
+		NetworkServer_HandleChat(NETWORK_ACTION_CHAT + type, type, dest, buf, NETWORK_SERVER_INDEX);
+	}
+}
+
+/**
+ * Find the next item of the list of things that can be auto-completed.
+ * @param item The current indexed item to return. This function can, and most
+ *     likely will, alter item, to skip empty items in the arrays.
+ * @return Returns the char that matched to the index.
+ */
+static const char *ChatTabCompletionNextItem(uint *item)
+{
+	static char chat_tab_temp_buffer[64];
+
+	/* First, try clients */
+	if (*item < MAX_CLIENT_INFO) {
+		/* Skip inactive clients */
+		while (_network_client_info[*item].client_index == NETWORK_EMPTY_INDEX && *item < MAX_CLIENT_INFO) (*item)++;
+		if (*item < MAX_CLIENT_INFO) return _network_client_info[*item].client_name;
+	}
+
+	/* Then, try townnames */
+	/* Not that the following assumes all town indices are adjacent, ie no
+	 * towns have been deleted. */
+	if (*item <= (uint)MAX_CLIENT_INFO + GetMaxTownIndex()) {
+		const Town *t;
+
+		FOR_ALL_TOWNS_FROM(t, *item - MAX_CLIENT_INFO) {
+			/* Get the town-name via the string-system */
+			SetDParam(0, t->townnameparts);
+			GetString(chat_tab_temp_buffer, t->townnametype, lastof(chat_tab_temp_buffer));
+			return &chat_tab_temp_buffer[0];
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * Find what text to complete. It scans for a space from the left and marks
+ *  the word right from that as to complete. It also writes a \0 at the
+ *  position of the space (if any). If nothing found, buf is returned.
+ */
+static char *ChatTabCompletionFindText(char *buf)
+{
+	char *p = strrchr(buf, ' ');
+	if (p == NULL) return buf;
+
+	*p = '\0';
+	return p + 1;
+}
+
+/**
+ * See if we can auto-complete the current text of the user.
+ */
+static void ChatTabCompletion(Window *w)
+{
+	static char _chat_tab_completion_buf[lengthof(_edit_str_buf)];
+	Textbuf *tb = &WP(w, querystr_d).text;
+	uint len, tb_len;
+	uint item;
+	char *tb_buf, *pre_buf;
+	const char *cur_name;
+	bool second_scan = false;
+
+	item = 0;
+
+	/* Copy the buffer so we can modify it without damaging the real data */
+	pre_buf = (_chat_tab_completion_active) ? strdup(_chat_tab_completion_buf) : strdup(tb->buf);
+
+	tb_buf  = ChatTabCompletionFindText(pre_buf);
+	tb_len  = strlen(tb_buf);
+
+	while ((cur_name = ChatTabCompletionNextItem(&item)) != NULL) {
+		item++;
+
+		if (_chat_tab_completion_active) {
+			/* We are pressing TAB again on the same name, is there an other name
+			 *  that starts with this? */
+			if (!second_scan) {
+				uint offset;
+				uint length;
+
+				/* If we are completing at the begin of the line, skip the ': ' we added */
+				if (tb_buf == pre_buf) {
+					offset = 0;
+					length = tb->length - 2;
+				} else {
+					/* Else, find the place we are completing at */
+					offset = strlen(pre_buf) + 1;
+					length = tb->length - offset;
+				}
+
+				/* Compare if we have a match */
+				if (strlen(cur_name) == length && strncmp(cur_name, tb->buf + offset, length) == 0) second_scan = true;
+
+				continue;
+			}
+
+			/* Now any match we make on _chat_tab_completion_buf after this, is perfect */
+		}
+
+		len = strlen(cur_name);
+		if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
+			/* Save the data it was before completion */
+			if (!second_scan) snprintf(_chat_tab_completion_buf, lengthof(_chat_tab_completion_buf), "%s", tb->buf);
+			_chat_tab_completion_active = true;
+
+			/* Change to the found name. Add ': ' if we are at the start of the line (pretty) */
+			if (pre_buf == tb_buf) {
+				snprintf(tb->buf, lengthof(_edit_str_buf), "%s: ", cur_name);
+			} else {
+				snprintf(tb->buf, lengthof(_edit_str_buf), "%s %s", pre_buf, cur_name);
+			}
+
+			/* Update the textbuffer */
+			UpdateTextBufferSize(&WP(w, querystr_d).text);
+
+			SetWindowDirty(w);
+			free(pre_buf);
+			return;
+		}
+	}
+
+	if (second_scan) {
+		/* We walked all posibilities, and the user presses tab again.. revert to original text */
+		strcpy(tb->buf, _chat_tab_completion_buf);
+		_chat_tab_completion_active = false;
+
+		/* Update the textbuffer */
+		UpdateTextBufferSize(&WP(w, querystr_d).text);
+
+		SetWindowDirty(w);
+	}
+	free(pre_buf);
+}
+
+/* uses querystr_d WP macro
+ * uses querystr_d->caption to store
+ * - type of chat message (Private/Team/All) in bytes 0-7
+ * - destination of chat message in the case of Team/Private in bytes 8-15 */
+static void ChatWindowWndProc(Window *w, WindowEvent *e)
+{
+	switch (e->event) {
+	case WE_CREATE:
+		SendWindowMessage(WC_NEWS_WINDOW, 0, WE_CREATE, w->height, 0);
+		SETBIT(_no_scroll, SCROLL_CHAT); // do not scroll the game with the arrow-keys
+		break;
+
+	case WE_PAINT: {
+		static const StringID chat_captions[] = {
+			STR_NETWORK_CHAT_ALL_CAPTION,
+			STR_NETWORK_CHAT_COMPANY_CAPTION,
+			STR_NETWORK_CHAT_CLIENT_CAPTION
+		};
+		StringID msg;
+
+		DrawWindowWidgets(w);
+
+		assert(GB(WP(w, querystr_d).caption, 0, 8) < lengthof(chat_captions));
+		msg = chat_captions[GB(WP(w, querystr_d).caption, 0, 8)];
+		DrawStringRightAligned(w->widget[2].left - 2, w->widget[2].top + 1, msg, 16);
+		DrawEditBox(w, &WP(w, querystr_d), 2);
+	} break;
+
+	case WE_CLICK:
+		switch (e->we.click.widget) {
+			case 3: { /* Send */
+				DestType type = GB(WP(w, querystr_d).caption, 0, 8);
+				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
+				SendChat(WP(w, querystr_d).text.buf, type, dest);
+			} /* FALLTHROUGH */
+			case 0: /* Cancel */ DeleteWindow(w); break;
+		}
+		break;
+
+	case WE_MOUSELOOP:
+		HandleEditBox(w, &WP(w, querystr_d), 2);
+		break;
+
+	case WE_KEYPRESS:
+		if (e->we.keypress.keycode == WKC_TAB) {
+			ChatTabCompletion(w);
+		} else {
+			_chat_tab_completion_active = false;
+			switch (HandleEditBoxKey(w, &WP(w, querystr_d), 2, e)) {
+				case 1: { /* Return */
+				DestType type = GB(WP(w, querystr_d).caption, 0, 8);
+				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
+				SendChat(WP(w, querystr_d).text.buf, type, dest);
+			} /* FALLTHROUGH */
+				case 2: /* Escape */ DeleteWindow(w); break;
+			}
+		}
+		break;
+
+	case WE_DESTROY:
+		SendWindowMessage(WC_NEWS_WINDOW, 0, WE_DESTROY, 0, 0);
+		CLRBIT(_no_scroll, SCROLL_CHAT);
+		break;
+	}
+}
+
+static const Widget _chat_window_widgets[] = {
+{   WWT_CLOSEBOX, RESIZE_NONE, 14,   0,  10,  0, 13, STR_00C5,         STR_018B_CLOSE_WINDOW},
+{      WWT_PANEL, RESIZE_NONE, 14,  11, 639,  0, 13, 0x0,              STR_NULL}, // background
+{      WWT_PANEL, RESIZE_NONE, 14,  75, 577,  1, 12, 0x0,              STR_NULL}, // text box
+{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 578, 639,  1, 12, STR_NETWORK_SEND, STR_NULL}, // send button
+{   WIDGETS_END},
+};
+
+static const WindowDesc _chat_window_desc = {
+	WDP_CENTER, -26, 640, 14, // x, y, width, height
+	WC_SEND_NETWORK_MSG,0,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET,
+	_chat_window_widgets,
+	ChatWindowWndProc
+};
+
+void ShowNetworkChatQueryWindow(DestType type, byte dest)
+{
+	Window *w;
+
+	DeleteWindowById(WC_SEND_NETWORK_MSG, 0);
+
+	_edit_str_buf[0] = '\0';
+	_chat_tab_completion_active = false;
+
+	w = AllocateWindowDesc(&_chat_window_desc);
+
+	LowerWindowWidget(w, 2);
+	WP(w, querystr_d).caption = GB(type, 0, 8) | (dest << 8); // Misuse of caption
+	WP(w, querystr_d).afilter = CS_ALPHANUMERAL;
+	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_gui.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+#ifndef NETWORK_GUI_H
+#define NETWORK_GUI_H
+
+#ifdef ENABLE_NETWORK
+
+#include "network_data.h"
+
+void ShowNetworkNeedPassword(NetworkPasswordType npt);
+void ShowNetworkGiveMoneyWindow(byte player); // PlayerID
+void ShowNetworkChatQueryWindow(DestType type, byte dest);
+void ShowJoinStatusWindow(void);
+void ShowNetworkGameWindow(void);
+void ShowClientList(void);
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void ShowNetworkChatQueryWindow(byte desttype, byte dest) {}
+static inline void ShowClientList(void) {}
+static inline void ShowNetworkGameWindow(void) {}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_GUI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_server.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,1528 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../openttd.h" // XXX StringID
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
+#include "network_data.h"
+#include "core/tcp.h"
+#include "../train.h"
+#include "../date.h"
+#include "../table/strings.h"
+#include "../functions.h"
+#include "network_server.h"
+#include "network_udp.h"
+#include "../console.h"
+#include "../command.h"
+#include "../saveload.h"
+#include "../vehicle.h"
+#include "../station.h"
+#include "../variables.h"
+#include "../genworld.h"
+
+// This file handles all the server-commands
+
+static void NetworkHandleCommandQueue(NetworkClientState* cs);
+
+// **********
+// Sending functions
+//   DEF_SERVER_SEND_COMMAND has parameter: NetworkClientState *cs
+// **********
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkClientState *cs, NetworkClientInfo *ci)
+{
+	//
+	// Packet: SERVER_CLIENT_INFO
+	// Function: Sends info about a client
+	// Data:
+	//    uint16:  The index of the client (always unique on a server. 1 = server)
+	//    uint8:  As which player the client is playing
+	//    String: The name of the client
+	//    String: The unique id of the client
+	//
+
+	if (ci->client_index != NETWORK_EMPTY_INDEX) {
+		Packet *p = NetworkSend_Init(PACKET_SERVER_CLIENT_INFO);
+		NetworkSend_uint16(p, ci->client_index);
+		NetworkSend_uint8 (p, ci->client_playas);
+		NetworkSend_string(p, ci->client_name);
+		NetworkSend_string(p, ci->unique_id);
+
+		NetworkSend_Packet(p, cs);
+	}
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)
+{
+//
+	// Packet: SERVER_COMPANY_INFO
+	// Function: Sends info about the companies
+	// Data:
+	//
+
+	int i;
+
+	Player *player;
+	Packet *p;
+
+	byte active = ActivePlayerCount();
+
+	if (active == 0) {
+		p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+		NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+		NetworkSend_uint8 (p, active);
+
+		NetworkSend_Packet(p, cs);
+		return;
+	}
+
+	NetworkPopulateCompanyInfo();
+
+	FOR_ALL_PLAYERS(player) {
+		if (!player->is_active) continue;
+
+		p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+		NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+		NetworkSend_uint8 (p, active);
+		NetworkSend_uint8 (p, player->index);
+
+		NetworkSend_string(p, _network_player_info[player->index].company_name);
+		NetworkSend_uint32(p, _network_player_info[player->index].inaugurated_year);
+		NetworkSend_uint64(p, _network_player_info[player->index].company_value);
+		NetworkSend_uint64(p, _network_player_info[player->index].money);
+		NetworkSend_uint64(p, _network_player_info[player->index].income);
+		NetworkSend_uint16(p, _network_player_info[player->index].performance);
+
+		/* Send 1 if there is a passord for the company else send 0 */
+		if (_network_player_info[player->index].password[0] != '\0') {
+			NetworkSend_uint8(p, 1);
+		} else {
+			NetworkSend_uint8(p, 0);
+		}
+
+		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
+			NetworkSend_uint16(p, _network_player_info[player->index].num_vehicle[i]);
+		}
+
+		for (i = 0; i < NETWORK_STATION_TYPES; i++) {
+			NetworkSend_uint16(p, _network_player_info[player->index].num_station[i]);
+		}
+
+		if (_network_player_info[player->index].players[0] == '\0') {
+			NetworkSend_string(p, "<none>");
+		} else {
+			NetworkSend_string(p, _network_player_info[player->index].players);
+		}
+
+		NetworkSend_Packet(p, cs);
+	}
+
+	p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
+
+	NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
+	NetworkSend_uint8 (p, 0);
+
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error)
+{
+	//
+	// Packet: SERVER_ERROR
+	// Function: The client made an error
+	// Data:
+	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
+	//
+
+	char str[100];
+	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR);
+
+	NetworkSend_uint8(p, error);
+	NetworkSend_Packet(p, cs);
+
+	GetNetworkErrorMsg(str, error, lastof(str));
+
+	// Only send when the current client was in game
+	if (cs->status > STATUS_AUTH) {
+		NetworkClientState *new_cs;
+		char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+		NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+		DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
+
+		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+		FOR_ALL_CLIENTS(new_cs) {
+			if (new_cs->status > STATUS_AUTH && new_cs != cs) {
+				// Some errors we filter to a more general error. Clients don't have to know the real
+				//  reason a joining failed.
+				if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION)
+					error = NETWORK_ERROR_ILLEGAL_PACKET;
+
+				SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, error);
+			}
+		}
+	} else {
+		DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", cs->index, str);
+	}
+
+	cs->has_quit = true;
+
+	// Make sure the data get's there before we close the connection
+	NetworkSend_Packets(cs);
+
+	// The client made a mistake, so drop his connection now!
+	NetworkCloseClient(cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientState *cs, NetworkPasswordType type)
+{
+	//
+	// Packet: SERVER_NEED_PASSWORD
+	// Function: Indication to the client that the server needs a password
+	// Data:
+	//    uint8:  Type of password
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
+	NetworkSend_uint8(p, type);
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
+{
+	//
+	// Packet: SERVER_WELCOME
+	// Function: The client is joined and ready to receive his map
+	// Data:
+	//    uint16:  Own ClientID
+	//
+
+	Packet *p;
+	const NetworkClientState *new_cs;
+
+	// Invalid packet when status is AUTH or higher
+	if (cs->status >= STATUS_AUTH) return;
+
+	cs->status = STATUS_AUTH;
+	_network_game_info.clients_on++;
+
+	p = NetworkSend_Init(PACKET_SERVER_WELCOME);
+	NetworkSend_uint16(p, cs->index);
+	NetworkSend_Packet(p, cs);
+
+		// Transmit info about all the active clients
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs != cs && new_cs->status > STATUS_AUTH)
+			SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, DEREF_CLIENT_INFO(new_cs));
+	}
+	// Also send the info of the server
+	SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX));
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WAIT)
+{
+	//
+	// Packet: PACKET_SERVER_WAIT
+	// Function: The client can not receive the map at the moment because
+	//             someone else is already receiving the map
+	// Data:
+	//    uint8:  Clients awaiting map
+	//
+	int waiting = 0;
+	NetworkClientState *new_cs;
+	Packet *p;
+
+	// Count how many players are waiting in the queue
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs->status == STATUS_MAP_WAIT) waiting++;
+	}
+
+	p = NetworkSend_Init(PACKET_SERVER_WAIT);
+	NetworkSend_uint8(p, waiting);
+	NetworkSend_Packet(p, cs);
+}
+
+// This sends the map to the client
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP)
+{
+	//
+	// Packet: SERVER_MAP
+	// Function: Sends the map to the client, or a part of it (it is splitted in
+	//   a lot of multiple packets)
+	// Data:
+	//    uint8:  packet-type (MAP_PACKET_START, MAP_PACKET_NORMAL and MAP_PACKET_END)
+	//  if MAP_PACKET_START:
+	//    uint32: The current FrameCounter
+	//  if MAP_PACKET_NORMAL:
+	//    piece of the map (till max-size of packet)
+	//  if MAP_PACKET_END:
+	//    uint32: seed0 of player
+	//    uint32: seed1 of player
+	//      last 2 are repeated MAX_PLAYERS time
+	//
+
+	static FILE *file_pointer;
+	static uint sent_packets; // How many packets we did send succecfully last time
+
+	if (cs->status < STATUS_AUTH) {
+		// Illegal call, return error and ignore the packet
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
+		return;
+	}
+
+	if (cs->status == STATUS_AUTH) {
+		char filename[256];
+		Packet *p;
+
+		// Make a dump of the current game
+		snprintf(filename, lengthof(filename), "%s%snetwork_server.tmp",  _paths.autosave_dir, PATHSEP);
+		if (SaveOrLoad(filename, SL_SAVE) != SL_OK) error("network savedump failed");
+
+		file_pointer = fopen(filename, "rb");
+		fseek(file_pointer, 0, SEEK_END);
+
+		// Now send the _frame_counter and how many packets are coming
+		p = NetworkSend_Init(PACKET_SERVER_MAP);
+		NetworkSend_uint8(p, MAP_PACKET_START);
+		NetworkSend_uint32(p, _frame_counter);
+		NetworkSend_uint32(p, ftell(file_pointer));
+		NetworkSend_Packet(p, cs);
+
+		fseek(file_pointer, 0, SEEK_SET);
+
+		sent_packets = 4; // We start with trying 4 packets
+
+		cs->status = STATUS_MAP;
+		/* Mark the start of download */
+		cs->last_frame = _frame_counter;
+		cs->last_frame_server = _frame_counter;
+	}
+
+	if (cs->status == STATUS_MAP) {
+		uint i;
+		int res;
+		for (i = 0; i < sent_packets; i++) {
+			Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
+			NetworkSend_uint8(p, MAP_PACKET_NORMAL);
+			res = (int)fread(p->buffer + p->size, 1, SEND_MTU - p->size, file_pointer);
+
+			if (ferror(file_pointer)) error("Error reading temporary network savegame!");
+
+			p->size += res;
+			NetworkSend_Packet(p, cs);
+			if (feof(file_pointer)) {
+				// Done reading!
+				Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
+				NetworkSend_uint8(p, MAP_PACKET_END);
+				NetworkSend_Packet(p, cs);
+
+				// Set the status to DONE_MAP, no we will wait for the client
+				//  to send it is ready (maybe that happens like never ;))
+				cs->status = STATUS_DONE_MAP;
+				fclose(file_pointer);
+
+				{
+					NetworkClientState *new_cs;
+					bool new_map_client = false;
+					// Check if there is a client waiting for receiving the map
+					//  and start sending him the map
+					FOR_ALL_CLIENTS(new_cs) {
+						if (new_cs->status == STATUS_MAP_WAIT) {
+							// Check if we already have a new client to send the map to
+							if (!new_map_client) {
+								// If not, this client will get the map
+								new_cs->status = STATUS_AUTH;
+								new_map_client = true;
+								SEND_COMMAND(PACKET_SERVER_MAP)(new_cs);
+							} else {
+								// Else, send the other clients how many clients are in front of them
+								SEND_COMMAND(PACKET_SERVER_WAIT)(new_cs);
+							}
+						}
+					}
+				}
+
+				// There is no more data, so break the for
+				break;
+			}
+		}
+
+		// Send all packets (forced) and check if we have send it all
+		NetworkSend_Packets(cs);
+		if (cs->packet_queue == NULL) {
+			// All are sent, increase the sent_packets
+			sent_packets *= 2;
+		} else {
+			// Not everything is sent, decrease the sent_packets
+			if (sent_packets > 1) sent_packets /= 2;
+		}
+	}
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkClientState *cs, uint16 client_index)
+{
+	//
+	// Packet: SERVER_JOIN
+	// Function: A client is joined (all active clients receive this after a
+	//     PACKET_CLIENT_MAP_OK) Mostly what directly follows is a
+	//     PACKET_SERVER_CLIENT_INFO
+	// Data:
+	//    uint16:  Client-Index
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_JOIN);
+
+	NetworkSend_uint16(p, client_index);
+
+	NetworkSend_Packet(p, cs);
+}
+
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_FRAME)
+{
+	//
+	// Packet: SERVER_FRAME
+	// Function: Sends the current frame-counter to the client
+	// Data:
+	//    uint32: Frame Counter
+	//    uint32: Frame Counter Max (how far may the client walk before the server?)
+	//    [uint32: general-seed-1]
+	//    [uint32: general-seed-2]
+	//      (last two depends on compile-settings, and are not default settings)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_FRAME);
+	NetworkSend_uint32(p, _frame_counter);
+	NetworkSend_uint32(p, _frame_counter_max);
+#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
+	NetworkSend_uint32(p, _sync_seed_1);
+#ifdef NETWORK_SEND_DOUBLE_SEED
+	NetworkSend_uint32(p, _sync_seed_2);
+#endif
+#endif
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SYNC)
+{
+	//
+	// Packet: SERVER_SYNC
+	// Function: Sends a sync-check to the client
+	// Data:
+	//    uint32: Frame Counter
+	//    uint32: General-seed-1
+	//    [uint32: general-seed-2]
+	//      (last one depends on compile-settings, and are not default settings)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_SYNC);
+	NetworkSend_uint32(p, _frame_counter);
+	NetworkSend_uint32(p, _sync_seed_1);
+
+#ifdef NETWORK_SEND_DOUBLE_SEED
+	NetworkSend_uint32(p, _sync_seed_2);
+#endif
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientState *cs, CommandPacket *cp)
+{
+	//
+	// Packet: SERVER_COMMAND
+	// Function: Sends a DoCommand to the client
+	// Data:
+	//    uint8:  PlayerID (0..MAX_PLAYERS-1)
+	//    uint32: CommandID (see command.h)
+	//    uint32: P1 (free variables used in DoCommand)
+	//    uint32: P2
+	//    uint32: Tile
+	//    string: text
+	//    uint8:  CallBackID (see callback_table.c)
+	//    uint32: Frame of execution
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_COMMAND);
+
+	NetworkSend_uint8(p, cp->player);
+	NetworkSend_uint32(p, cp->cmd);
+	NetworkSend_uint32(p, cp->p1);
+	NetworkSend_uint32(p, cp->p2);
+	NetworkSend_uint32(p, cp->tile);
+	NetworkSend_string(p, cp->text);
+	NetworkSend_uint8(p, cp->callback);
+	NetworkSend_uint32(p, cp->frame);
+
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
+{
+	//
+	// Packet: SERVER_CHAT
+	// Function: Sends a chat-packet to the client
+	// Data:
+	//    uint8:  ActionID (see network_data.h, NetworkAction)
+	//    uint16:  Client-index
+	//    String: Message (max MAX_TEXT_MSG_LEN)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_CHAT);
+
+	NetworkSend_uint8(p, action);
+	NetworkSend_uint16(p, client_index);
+	NetworkSend_uint8(p, self_send);
+	NetworkSend_string(p, msg);
+
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno)
+{
+	//
+	// Packet: SERVER_ERROR_QUIT
+	// Function: One of the clients made an error and is quiting the game
+	//      This packet informs the other clients of that.
+	// Data:
+	//    uint16:  Client-index
+	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR_QUIT);
+
+	NetworkSend_uint16(p, client_index);
+	NetworkSend_uint8(p, errorno);
+
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkClientState *cs, uint16 client_index, const char *leavemsg)
+{
+	//
+	// Packet: SERVER_ERROR_QUIT
+	// Function: A client left the game, and this packets informs the other clients
+	//      of that.
+	// Data:
+	//    uint16:  Client-index
+	//    String: leave-message
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_QUIT);
+
+	NetworkSend_uint16(p, client_index);
+	NetworkSend_string(p, leavemsg);
+
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN)
+{
+	//
+	// Packet: SERVER_SHUTDOWN
+	// Function: Let the clients know that the server is closing
+	// Data:
+	//     <none>
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_SHUTDOWN);
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
+{
+	//
+	// Packet: PACKET_SERVER_NEWGAME
+	// Function: Let the clients know that the server is loading a new map
+	// Data:
+	//     <none>
+	//
+
+	Packet *p = NetworkSend_Init(PACKET_SERVER_NEWGAME);
+	NetworkSend_Packet(p, cs);
+}
+
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command)
+{
+	Packet *p = NetworkSend_Init(PACKET_SERVER_RCON);
+
+	NetworkSend_uint16(p, color);
+	NetworkSend_string(p, command);
+	NetworkSend_Packet(p, cs);
+}
+
+// **********
+// Receiving functions
+//   DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p
+// **********
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO)
+{
+	SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)(cs);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
+{
+	char name[NETWORK_CLIENT_NAME_LENGTH];
+	char unique_id[NETWORK_NAME_LENGTH];
+	NetworkClientInfo *ci;
+	byte playas;
+	NetworkLanguage client_lang;
+	char client_revision[NETWORK_REVISION_LENGTH];
+
+	NetworkRecv_string(cs, p, client_revision, sizeof(client_revision));
+
+#if defined(WITH_REV) || defined(WITH_REV_HACK)
+	// Check if the client has revision control enabled
+	if (strcmp(NOREV_STRING, client_revision) != 0 &&
+			strcmp(_network_game_info.server_revision, client_revision) != 0) {
+		// Different revisions!!
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
+		return;
+	}
+#endif
+
+	NetworkRecv_string(cs, p, name, sizeof(name));
+	playas = NetworkRecv_uint8(cs, p);
+	client_lang = NetworkRecv_uint8(cs, p);
+	NetworkRecv_string(cs, p, unique_id, sizeof(unique_id));
+
+	if (cs->has_quit) return;
+
+	// join another company does not affect these values
+	switch (playas) {
+		case PLAYER_NEW_COMPANY: /* New company */
+			if (ActivePlayerCount() >= _network_game_info.companies_max) {
+				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
+				return;
+			}
+			break;
+		case PLAYER_SPECTATOR: /* Spectator */
+			if (NetworkSpectatorCount() >= _network_game_info.spectators_max) {
+				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
+				return;
+			}
+			break;
+		default: /* Join another company (companies 1-8 (index 0-7)) */
+			if (!IsValidPlayer(playas)) {
+				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
+				return;
+			}
+			break;
+	}
+
+	// We need a valid name.. make it Player
+	if (*name == '\0') ttd_strlcpy(name, "Player", sizeof(name));
+
+	if (!NetworkFindName(name)) { // Change name if duplicate
+		// We could not create a name for this player
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NAME_IN_USE);
+		return;
+	}
+
+	ci = DEREF_CLIENT_INFO(cs);
+
+	ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
+	ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
+	ci->client_playas = playas;
+	ci->client_lang = client_lang;
+
+	// We now want a password from the client
+	//  else we do not allow him in!
+	if (_network_game_info.use_password) {
+		SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
+	} else {
+		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
+			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
+		} else {
+			SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+		}
+	}
+
+	/* Make sure companies to which people try to join are not autocleaned */
+	if (IsValidPlayer(playas)) _network_player_info[playas].months_empty = 0;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
+{
+	NetworkPasswordType type;
+	char password[NETWORK_PASSWORD_LENGTH];
+	const NetworkClientInfo *ci;
+
+	type = NetworkRecv_uint8(cs, p);
+	NetworkRecv_string(cs, p, password, sizeof(password));
+
+	if (cs->status == STATUS_INACTIVE && type == NETWORK_GAME_PASSWORD) {
+		// Check game-password
+		if (strcmp(password, _network_game_info.server_password) != 0) {
+			// Password is invalid
+			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
+			return;
+		}
+
+		ci = DEREF_CLIENT_INFO(cs);
+
+		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
+			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
+			return;
+		}
+
+		// Valid password, allow user
+		SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+		return;
+	} else if (cs->status == STATUS_INACTIVE && type == NETWORK_COMPANY_PASSWORD) {
+		ci = DEREF_CLIENT_INFO(cs);
+
+		if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
+			// Password is invalid
+			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
+			return;
+		}
+
+		SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+		return;
+	}
+
+
+	SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+	return;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP)
+{
+	const NetworkClientState *new_cs;
+
+	// The client was never joined.. so this is impossible, right?
+	//  Ignore the packet, give the client a warning, and close his connection
+	if (cs->status < STATUS_AUTH || cs->has_quit) {
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
+		return;
+	}
+
+	// Check if someone else is receiving the map
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs->status == STATUS_MAP) {
+			// Tell the new client to wait
+			cs->status = STATUS_MAP_WAIT;
+			SEND_COMMAND(PACKET_SERVER_WAIT)(cs);
+			return;
+		}
+	}
+
+	// We receive a request to upload the map.. give it to the client!
+	SEND_COMMAND(PACKET_SERVER_MAP)(cs);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
+{
+	// Client has the map, now start syncing
+	if (cs->status == STATUS_DONE_MAP && !cs->has_quit) {
+		char client_name[NETWORK_CLIENT_NAME_LENGTH];
+		NetworkClientState *new_cs;
+
+		NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+		NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, client_name, "");
+
+		// Mark the client as pre-active, and wait for an ACK
+		//  so we know he is done loading and in sync with us
+		cs->status = STATUS_PRE_ACTIVE;
+		NetworkHandleCommandQueue(cs);
+		SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
+		SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
+
+		// This is the frame the client receives
+		//  we need it later on to make sure the client is not too slow
+		cs->last_frame = _frame_counter;
+		cs->last_frame_server = _frame_counter;
+
+		FOR_ALL_CLIENTS(new_cs) {
+			if (new_cs->status > STATUS_AUTH) {
+				SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, DEREF_CLIENT_INFO(cs));
+				SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->index);
+			}
+		}
+
+		if (_network_pause_on_join) {
+			/* Now pause the game till the client is in sync */
+			DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+
+			NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (incoming client)", NETWORK_SERVER_INDEX);
+		}
+	} else {
+		// Wrong status for this packet, give a warning to client, and close connection
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+	}
+}
+
+/** Enforce the command flags.
+ * Eg a server-only command can only be executed by a server, etc.
+ * @param *cp the commandpacket that is going to be checked
+ * @param *ci client information for debugging output to console
+ */
+static bool CheckCommandFlags(const CommandPacket *cp, const NetworkClientInfo *ci)
+{
+	byte flags = GetCommandFlags(cp->cmd);
+
+	if (flags & CMD_SERVER && ci->client_index != NETWORK_SERVER_INDEX) {
+		IConsolePrintF(_icolour_err, "WARNING: server only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
+		return false;
+	}
+
+	if (flags & CMD_OFFLINE) {
+		IConsolePrintF(_icolour_err, "WARNING: offline only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
+		return false;
+	}
+
+	return true;
+}
+
+/** The client has done a command and wants us to handle it
+ * @param *cs the connected client that has sent the command
+ * @param *p the packet in which the command was sent
+ */
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
+{
+	NetworkClientState *new_cs;
+	const NetworkClientInfo *ci;
+	byte callback;
+
+	CommandPacket *cp = malloc(sizeof(CommandPacket));
+
+	// The client was never joined.. so this is impossible, right?
+	//  Ignore the packet, give the client a warning, and close his connection
+	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+		return;
+	}
+
+	cp->player = NetworkRecv_uint8(cs, p);
+	cp->cmd    = NetworkRecv_uint32(cs, p);
+	cp->p1     = NetworkRecv_uint32(cs, p);
+	cp->p2     = NetworkRecv_uint32(cs, p);
+	cp->tile   = NetworkRecv_uint32(cs, p);
+	NetworkRecv_string(cs, p, cp->text, lengthof(cp->text));
+
+	callback = NetworkRecv_uint8(cs, p);
+
+	if (cs->has_quit) return;
+
+	ci = DEREF_CLIENT_INFO(cs);
+
+	/* Check if cp->cmd is valid */
+	if (!IsValidCommand(cp->cmd)) {
+		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+		return;
+	}
+
+	if (!CheckCommandFlags(cp, ci)) {
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
+		return;
+	}
+
+	/** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
+	 * to match the player in the packet. If it doesn't, the client has done
+	 * something pretty naughty (or a bug), and will be kicked
+	 */
+	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
+		IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
+		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
+		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
+		return;
+	}
+
+	/** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
+	 * player the correct ID, the server injects p2 and executes the command. Any other p1
+	 * is prohibited. Pretty ugly and should be redone together with its function.
+	 * @see CmdPlayerCtrl() players.c:655
+	 */
+	if (cp->cmd == CMD_PLAYER_CTRL) {
+		if (cp->p1 != 0) {
+			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
+			return;
+		}
+
+		/* XXX - Execute the command as a valid player. Normally this would be done by a
+		 * spectator, but that is not allowed any commands. So do an impersonation. The drawback
+		 * of this is that the first company's last_built_tile is also updated... */
+		cp->player = 0;
+		cp->p2 = cs - _clients; // XXX - UGLY! p2 is mis-used to get the client-id in CmdPlayerCtrl
+	}
+
+	// The frame can be executed in the same frame as the next frame-packet
+	//  That frame just before that frame is saved in _frame_counter_max
+	cp->frame = _frame_counter_max + 1;
+	cp->next  = NULL;
+
+	// Queue the command for the clients (are send at the end of the frame
+	//   if they can handle it ;))
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs->status >= STATUS_MAP) {
+			// Callbacks are only send back to the client who sent them in the
+			//  first place. This filters that out.
+			cp->callback = (new_cs != cs) ? 0 : callback;
+			NetworkAddCommandQueue(new_cs, cp);
+		}
+	}
+
+	cp->callback = 0;
+	// Queue the command on the server
+	if (_local_command_queue == NULL) {
+		_local_command_queue = cp;
+	} else {
+		// Find last packet
+		CommandPacket *c = _local_command_queue;
+		while (c->next != NULL) c = c->next;
+		c->next = cp;
+	}
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR)
+{
+	// This packets means a client noticed an error and is reporting this
+	//  to us. Display the error and report it to the other clients
+	NetworkClientState *new_cs;
+	char str[100];
+	char client_name[NETWORK_CLIENT_NAME_LENGTH];
+	NetworkErrorCode errorno = NetworkRecv_uint8(cs, p);
+
+	// The client was never joined.. thank the client for the packet, but ignore it
+	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+		cs->has_quit = true;
+		return;
+	}
+
+	NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+	GetNetworkErrorMsg(str, errorno, lastof(str));
+
+	DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
+
+	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs->status > STATUS_AUTH) {
+			SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
+		}
+	}
+
+	cs->has_quit = true;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
+{
+	// The client wants to leave. Display this and report it to the other
+	//  clients.
+	NetworkClientState *new_cs;
+	char str[100];
+	char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+	// The client was never joined.. thank the client for the packet, but ignore it
+	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
+		cs->has_quit = true;
+		return;
+	}
+
+	NetworkRecv_string(cs, p, str, lengthof(str));
+
+	NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
+
+	FOR_ALL_CLIENTS(new_cs) {
+		if (new_cs->status > STATUS_AUTH) {
+			SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str);
+		}
+	}
+
+	cs->has_quit = true;
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK)
+{
+	uint32 frame = NetworkRecv_uint32(cs, p);
+
+	/* The client is trying to catch up with the server */
+	if (cs->status == STATUS_PRE_ACTIVE) {
+		/* The client is not yet catched up? */
+		if (frame + DAY_TICKS < _frame_counter) return;
+
+		/* Now he is! Unpause the game */
+		cs->status = STATUS_ACTIVE;
+
+		if (_network_pause_on_join) {
+			DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+			NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (client connected)", NETWORK_SERVER_INDEX);
+		}
+
+		CheckMinPlayers();
+
+		/* Execute script for, e.g. MOTD */
+		IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
+	}
+
+	// The client received the frame, make note of it
+	cs->last_frame = frame;
+	// With those 2 values we can calculate the lag realtime
+	cs->last_frame_server = _frame_counter;
+}
+
+
+
+void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index)
+{
+	NetworkClientState *cs;
+	const NetworkClientInfo *ci, *ci_own, *ci_to;
+
+	switch (desttype) {
+	case DESTTYPE_CLIENT:
+		/* Are we sending to the server? */
+		if (dest == NETWORK_SERVER_INDEX) {
+			ci = NetworkFindClientInfoFromIndex(from_index);
+			/* Display the text locally, and that is it */
+			if (ci != NULL)
+				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+		} else {
+			/* Else find the client to send the message to */
+			FOR_ALL_CLIENTS(cs) {
+				if (cs->index == dest) {
+					SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+					break;
+				}
+			}
+		}
+
+		// Display the message locally (so you know you have sent it)
+		if (from_index != dest) {
+			if (from_index == NETWORK_SERVER_INDEX) {
+				ci = NetworkFindClientInfoFromIndex(from_index);
+				ci_to = NetworkFindClientInfoFromIndex(dest);
+				if (ci != NULL && ci_to != NULL)
+					NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), true, ci_to->client_name, "%s", msg);
+			} else {
+				FOR_ALL_CLIENTS(cs) {
+					if (cs->index == from_index) {
+						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, dest, true, msg);
+						break;
+					}
+				}
+			}
+		}
+		break;
+	case DESTTYPE_TEAM: {
+		bool show_local = true; // If this is false, the message is already displayed
+														// on the client who did sent it.
+		/* Find all clients that belong to this player */
+		ci_to = NULL;
+		FOR_ALL_CLIENTS(cs) {
+			ci = DEREF_CLIENT_INFO(cs);
+			if (ci->client_playas == dest) {
+				SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+				if (cs->index == from_index) show_local = false;
+				ci_to = ci; // Remember a client that is in the company for company-name
+			}
+		}
+
+		ci = NetworkFindClientInfoFromIndex(from_index);
+		ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+		if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
+			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+			if (from_index == NETWORK_SERVER_INDEX) show_local = false;
+			ci_to = ci_own;
+		}
+
+		/* There is no such player */
+		if (ci_to == NULL) break;
+
+		// Display the message locally (so you know you have sent it)
+		if (ci != NULL && show_local) {
+			if (from_index == NETWORK_SERVER_INDEX) {
+				char name[NETWORK_NAME_LENGTH];
+				StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
+				GetString(name, str, lastof(name));
+				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
+			} else {
+				FOR_ALL_CLIENTS(cs) {
+					if (cs->index == from_index) {
+						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, ci_to->client_index, true, msg);
+					}
+				}
+			}
+		}
+		}
+		break;
+	default:
+		DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
+		/* fall-through to next case */
+	case DESTTYPE_BROADCAST:
+		FOR_ALL_CLIENTS(cs) {
+			SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
+		}
+		ci = NetworkFindClientInfoFromIndex(from_index);
+		if (ci != NULL)
+			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
+		break;
+	}
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
+{
+	NetworkAction action = NetworkRecv_uint8(cs, p);
+	DestType desttype = NetworkRecv_uint8(cs, p);
+	int dest = NetworkRecv_uint8(cs, p);
+	char msg[MAX_TEXT_MSG_LEN];
+
+	NetworkRecv_string(cs, p, msg, MAX_TEXT_MSG_LEN);
+
+	NetworkServer_HandleChat(action, desttype, dest, msg, cs->index);
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD)
+{
+	char password[NETWORK_PASSWORD_LENGTH];
+	const NetworkClientInfo *ci;
+
+	NetworkRecv_string(cs, p, password, sizeof(password));
+	ci = DEREF_CLIENT_INFO(cs);
+
+	if (IsValidPlayer(ci->client_playas)) {
+		ttd_strlcpy(_network_player_info[ci->client_playas].password, password, sizeof(_network_player_info[0].password));
+	}
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
+{
+	char client_name[NETWORK_CLIENT_NAME_LENGTH];
+	NetworkClientInfo *ci;
+
+	NetworkRecv_string(cs, p, client_name, sizeof(client_name));
+	ci = DEREF_CLIENT_INFO(cs);
+
+	if (cs->has_quit) return;
+
+	if (ci != NULL) {
+		// Display change
+		if (NetworkFindName(client_name)) {
+			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", client_name);
+			ttd_strlcpy(ci->client_name, client_name, sizeof(ci->client_name));
+			NetworkUpdateClientInfo(ci->client_index);
+		}
+	}
+}
+
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
+{
+	char pass[NETWORK_PASSWORD_LENGTH];
+	char command[NETWORK_RCONCOMMAND_LENGTH];
+
+	if (_network_game_info.rcon_password[0] == '\0') return;
+
+	NetworkRecv_string(cs, p, pass, sizeof(pass));
+	NetworkRecv_string(cs, p, command, sizeof(command));
+
+	if (strcmp(pass, _network_game_info.rcon_password) != 0) {
+		DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->index);
+		return;
+	}
+
+	DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", cs->index, command);
+
+	_redirect_console_to_client = cs->index;
+	IConsoleCmdExec(command);
+	_redirect_console_to_client = 0;
+	return;
+}
+
+// The layout for the receive-functions by the server
+typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p);
+
+
+// This array matches PacketType. At an incoming
+//  packet it is matches against this array
+//  and that way the right function to handle that
+//  packet is found.
+static NetworkServerPacket* const _network_server_packet[] = {
+	NULL, /*PACKET_SERVER_FULL,*/
+	NULL, /*PACKET_SERVER_BANNED,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
+	NULL, /*PACKET_SERVER_ERROR,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
+	NULL, /*PACKET_SERVER_COMPANY_INFO,*/
+	NULL, /*PACKET_SERVER_CLIENT_INFO,*/
+	NULL, /*PACKET_SERVER_NEED_PASSWORD,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD),
+	NULL, /*PACKET_SERVER_WELCOME,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_GETMAP),
+	NULL, /*PACKET_SERVER_WAIT,*/
+	NULL, /*PACKET_SERVER_MAP,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK),
+	NULL, /*PACKET_SERVER_JOIN,*/
+	NULL, /*PACKET_SERVER_FRAME,*/
+	NULL, /*PACKET_SERVER_SYNC,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_ACK),
+	RECEIVE_COMMAND(PACKET_CLIENT_COMMAND),
+	NULL, /*PACKET_SERVER_COMMAND,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_CHAT),
+	NULL, /*PACKET_SERVER_CHAT,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD),
+	RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME),
+	RECEIVE_COMMAND(PACKET_CLIENT_QUIT),
+	RECEIVE_COMMAND(PACKET_CLIENT_ERROR),
+	NULL, /*PACKET_SERVER_QUIT,*/
+	NULL, /*PACKET_SERVER_ERROR_QUIT,*/
+	NULL, /*PACKET_SERVER_SHUTDOWN,*/
+	NULL, /*PACKET_SERVER_NEWGAME,*/
+	NULL, /*PACKET_SERVER_RCON,*/
+	RECEIVE_COMMAND(PACKET_CLIENT_RCON),
+};
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_server_packet) == PACKET_END);
+
+// This update the company_info-stuff
+void NetworkPopulateCompanyInfo(void)
+{
+	char password[NETWORK_PASSWORD_LENGTH];
+	const Player *p;
+	const Vehicle *v;
+	const Station *s;
+	const NetworkClientState *cs;
+	const NetworkClientInfo *ci;
+	uint i;
+	uint16 months_empty;
+
+	FOR_ALL_PLAYERS(p) {
+		if (!p->is_active) {
+			memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
+			continue;
+		}
+
+		// Clean the info but not the password
+		ttd_strlcpy(password, _network_player_info[p->index].password, sizeof(password));
+		months_empty = _network_player_info[p->index].months_empty;
+		memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
+		_network_player_info[p->index].months_empty = months_empty;
+		ttd_strlcpy(_network_player_info[p->index].password, password, sizeof(_network_player_info[p->index].password));
+
+		// Grap the company name
+		SetDParam(0, p->name_1);
+		SetDParam(1, p->name_2);
+		GetString(_network_player_info[p->index].company_name, STR_JUST_STRING, lastof(_network_player_info[p->index].company_name));
+
+		// Check the income
+		if (_cur_year - 1 == p->inaugurated_year) {
+			// The player is here just 1 year, so display [2], else display[1]
+			for (i = 0; i < lengthof(p->yearly_expenses[2]); i++) {
+				_network_player_info[p->index].income -= p->yearly_expenses[2][i];
+			}
+		} else {
+			for (i = 0; i < lengthof(p->yearly_expenses[1]); i++) {
+				_network_player_info[p->index].income -= p->yearly_expenses[1][i];
+			}
+		}
+
+		// Set some general stuff
+		_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
+		_network_player_info[p->index].company_value = p->old_economy[0].company_value;
+		_network_player_info[p->index].money = p->money64;
+		_network_player_info[p->index].performance = p->old_economy[0].performance_history;
+	}
+
+	// Go through all vehicles and count the type of vehicles
+	FOR_ALL_VEHICLES(v) {
+		if (!IsValidPlayer(v->owner)) continue;
+
+		switch (v->type) {
+			case VEH_Train:
+				if (IsFrontEngine(v)) _network_player_info[v->owner].num_vehicle[0]++;
+				break;
+
+			case VEH_Road:
+				if (v->cargo_type != CT_PASSENGERS) {
+					_network_player_info[v->owner].num_vehicle[1]++;
+				} else {
+					_network_player_info[v->owner].num_vehicle[2]++;
+				}
+				break;
+
+			case VEH_Aircraft:
+				if (v->subtype <= 2) _network_player_info[v->owner].num_vehicle[3]++;
+				break;
+
+			case VEH_Ship:
+				_network_player_info[v->owner].num_vehicle[4]++;
+				break;
+
+			case VEH_Special:
+			case VEH_Disaster:
+				break;
+		}
+	}
+
+	// Go through all stations and count the types of stations
+	FOR_ALL_STATIONS(s) {
+		if (IsValidPlayer(s->owner)) {
+			NetworkPlayerInfo *npi = &_network_player_info[s->owner];
+
+			if (s->facilities & FACIL_TRAIN)      npi->num_station[0]++;
+			if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
+			if (s->facilities & FACIL_BUS_STOP)   npi->num_station[2]++;
+			if (s->facilities & FACIL_AIRPORT)    npi->num_station[3]++;
+			if (s->facilities & FACIL_DOCK)       npi->num_station[4]++;
+		}
+	}
+
+	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+	// Register local player (if not dedicated)
+	if (ci != NULL && IsValidPlayer(ci->client_playas))
+		ttd_strlcpy(_network_player_info[ci->client_playas].players, ci->client_name, sizeof(_network_player_info[0].players));
+
+	FOR_ALL_CLIENTS(cs) {
+		char client_name[NETWORK_CLIENT_NAME_LENGTH];
+
+		NetworkGetClientName(client_name, sizeof(client_name), cs);
+
+		ci = DEREF_CLIENT_INFO(cs);
+		if (ci != NULL && IsValidPlayer(ci->client_playas)) {
+			if (strlen(_network_player_info[ci->client_playas].players) != 0)
+				ttd_strlcat(_network_player_info[ci->client_playas].players, ", ", lengthof(_network_player_info[0].players));
+
+			ttd_strlcat(_network_player_info[ci->client_playas].players, client_name, lengthof(_network_player_info[0].players));
+		}
+	}
+}
+
+// Send a packet to all clients with updated info about this client_index
+void NetworkUpdateClientInfo(uint16 client_index)
+{
+	NetworkClientState *cs;
+	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(client_index);
+
+	if (ci == NULL) return;
+
+	FOR_ALL_CLIENTS(cs) {
+		SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
+	}
+}
+
+/* Check if we want to restart the map */
+static void NetworkCheckRestartMap(void)
+{
+	if (_network_restart_game_year != 0 && _cur_year >= _network_restart_game_year) {
+		DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
+
+		StartNewGameWithoutGUI(GENERATE_NEW_SEED);
+	}
+}
+
+/* Check if the server has autoclean_companies activated
+    Two things happen:
+      1) If a company is not protected, it is closed after 1 year (for example)
+      2) If a company is protected, protection is disabled after 3 years (for example)
+           (and item 1. happens a year later) */
+static void NetworkAutoCleanCompanies(void)
+{
+	const NetworkClientState *cs;
+	const NetworkClientInfo *ci;
+	const Player *p;
+	bool clients_in_company[MAX_PLAYERS];
+
+	if (!_network_autoclean_companies) return;
+
+	memset(clients_in_company, 0, sizeof(clients_in_company));
+
+	/* Detect the active companies */
+	FOR_ALL_CLIENTS(cs) {
+		ci = DEREF_CLIENT_INFO(cs);
+		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
+	}
+
+	if (!_network_dedicated) {
+		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
+	}
+
+	/* Go through all the comapnies */
+	FOR_ALL_PLAYERS(p) {
+		/* Skip the non-active once */
+		if (!p->is_active || p->is_ai) continue;
+
+		if (!clients_in_company[p->index]) {
+			/* The company is empty for one month more */
+			_network_player_info[p->index].months_empty++;
+
+			/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
+			if (_network_player_info[p->index].months_empty > _network_autoclean_unprotected && _network_player_info[p->index].password[0] == '\0') {
+				/* Shut the company down */
+				DoCommandP(0, 2, p->index, NULL, CMD_PLAYER_CTRL);
+				IConsolePrintF(_icolour_def, "Auto-cleaned company #%d", p->index + 1);
+			}
+			/* Is the compnay empty for autoclean_protected-months, and there is a protection? */
+			if (_network_player_info[p->index].months_empty > _network_autoclean_protected && _network_player_info[p->index].password[0] != '\0') {
+				/* Unprotect the company */
+				_network_player_info[p->index].password[0] = '\0';
+				IConsolePrintF(_icolour_def, "Auto-removed protection from company #%d", p->index+1);
+				_network_player_info[p->index].months_empty = 0;
+			}
+		} else {
+			/* It is not empty, reset the date */
+			_network_player_info[p->index].months_empty = 0;
+		}
+	}
+}
+
+// This function changes new_name to a name that is unique (by adding #1 ...)
+//  and it returns true if that succeeded.
+bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
+{
+	NetworkClientState *new_cs;
+	bool found_name = false;
+	byte number = 0;
+	char original_name[NETWORK_CLIENT_NAME_LENGTH];
+
+	// We use NETWORK_CLIENT_NAME_LENGTH in here, because new_name is really a pointer
+	ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
+
+	while (!found_name) {
+		const NetworkClientInfo *ci;
+
+		found_name = true;
+		FOR_ALL_CLIENTS(new_cs) {
+			ci = DEREF_CLIENT_INFO(new_cs);
+			if (strcmp(ci->client_name, new_name) == 0) {
+				// Name already in use
+				found_name = false;
+				break;
+			}
+		}
+		// Check if it is the same as the server-name
+		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+		if (ci != NULL) {
+			if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use
+		}
+
+		if (!found_name) {
+			// Try a new name (<name> #1, <name> #2, and so on)
+
+			// Stop if we tried for more than 50 times..
+			if (number++ > 50) break;
+			snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
+		}
+	}
+
+	return found_name;
+}
+
+// Reads a packet from the stream
+bool NetworkServer_ReadPackets(NetworkClientState *cs)
+{
+	Packet *p;
+	NetworkRecvStatus res;
+	while ((p = NetworkRecv_Packet(cs, &res)) != NULL) {
+		byte type = NetworkRecv_uint8(cs, p);
+		if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->has_quit) {
+			_network_server_packet[type](cs, p);
+		} else {
+			DEBUG(net, 0, "[server] received invalid packet type %d", type);
+		}
+		free(p);
+	}
+
+	return true;
+}
+
+// Handle the local command-queue
+static void NetworkHandleCommandQueue(NetworkClientState* cs)
+{
+	CommandPacket *cp;
+
+	while ( (cp = cs->command_queue) != NULL) {
+		SEND_COMMAND(PACKET_SERVER_COMMAND)(cs, cp);
+
+		cs->command_queue = cp->next;
+		free(cp);
+	}
+}
+
+// This is called every tick if this is a _network_server
+void NetworkServer_Tick(bool send_frame)
+{
+	NetworkClientState *cs;
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+	bool send_sync = false;
+#endif
+
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+	if (_frame_counter >= _last_sync_frame + _network_sync_freq) {
+		_last_sync_frame = _frame_counter;
+		send_sync = true;
+	}
+#endif
+
+	// Now we are done with the frame, inform the clients that they can
+	//  do their frame!
+	FOR_ALL_CLIENTS(cs) {
+		// Check if the speed of the client is what we can expect from a client
+		if (cs->status == STATUS_ACTIVE) {
+			// 1 lag-point per day
+			int lag = NetworkCalculateLag(cs) / DAY_TICKS;
+			if (lag > 0) {
+				if (lag > 3) {
+					// Client did still not report in after 4 game-day, drop him
+					//  (that is, the 3 of above, + 1 before any lag is counted)
+					IConsolePrintF(_icolour_err,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->index);
+					NetworkCloseClient(cs);
+					continue;
+				}
+
+				// Report once per time we detect the lag
+				if (cs->lag_test == 0) {
+					IConsolePrintF(_icolour_warn,"[%d] Client #%d is slow, try increasing *net_frame_freq to a higher value!", _frame_counter, cs->index);
+					cs->lag_test = 1;
+				}
+			} else {
+				cs->lag_test = 0;
+			}
+		} else if (cs->status == STATUS_PRE_ACTIVE) {
+			int lag = NetworkCalculateLag(cs);
+			if (lag > _network_max_join_time) {
+				IConsolePrintF(_icolour_err,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->index, _network_max_join_time);
+				NetworkCloseClient(cs);
+			}
+		}
+
+		if (cs->status >= STATUS_PRE_ACTIVE) {
+			// Check if we can send command, and if we have anything in the queue
+			NetworkHandleCommandQueue(cs);
+
+			// Send an updated _frame_counter_max to the client
+			if (send_frame) SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
+
+#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
+			// Send a sync-check packet
+			if (send_sync) SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
+#endif
+		}
+	}
+
+	/* See if we need to advertise */
+	NetworkUDPAdvertise();
+}
+
+void NetworkServerYearlyLoop(void)
+{
+	NetworkCheckRestartMap();
+}
+
+void NetworkServerMonthlyLoop(void)
+{
+	NetworkAutoCleanCompanies();
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_server.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,39 @@
+/* $Id$ */
+
+#ifndef NETWORK_SERVER_H
+#define NETWORK_SERVER_H
+
+#ifdef ENABLE_NETWORK
+
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error);
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN);
+DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command);
+
+bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]);
+void NetworkServer_HandleChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index);
+
+bool NetworkServer_ReadPackets(NetworkClientState *cs);
+void NetworkServer_Tick(bool send_frame);
+void NetworkServerMonthlyLoop(void);
+void NetworkServerYearlyLoop(void);
+
+static inline const char* GetPlayerIP(const NetworkClientInfo* ci)
+{
+	struct in_addr addr;
+
+	addr.s_addr = ci->client_ip;
+	return inet_ntoa(addr);
+}
+
+#else /* ENABLE_NETWORK */
+/* Network function stubs when networking is disabled */
+
+static inline void NetworkServerMonthlyLoop(void) {}
+static inline void NetworkServerYearlyLoop(void) {}
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_SERVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_udp.c	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,663 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
+#include "network_data.h"
+#include "../date.h"
+#include "../map.h"
+#include "network_gamelist.h"
+#include "network_udp.h"
+#include "../variables.h"
+#include "../newgrf_config.h"
+
+#include "core/udp.h"
+
+/**
+ * @file network_udp.c This file handles the UDP related communication.
+ *
+ * This is the GameServer <-> MasterServer and GameServer <-> GameClient
+ * communication before the game is being joined.
+ */
+
+enum {
+	ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
+	ADVERTISE_RETRY_INTERVAL  =   300, // readvertise when no response after this many ticks (9 seconds)
+	ADVERTISE_RETRY_TIMES     =     3  // give up readvertising after this much failed retries
+};
+
+#define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
+
+static NetworkClientState _udp_cs;
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
+{
+	Packet *packet;
+	// Just a fail-safe.. should never happen
+	if (!_network_udp_server)
+		return;
+
+	packet = NetworkSend_Init(PACKET_UDP_SERVER_RESPONSE);
+
+	// Update some game_info
+	_network_game_info.game_date     = _date;
+	_network_game_info.map_width     = MapSizeX();
+	_network_game_info.map_height    = MapSizeY();
+	_network_game_info.map_set       = _opt.landscape;
+	_network_game_info.companies_on  = ActivePlayerCount();
+	_network_game_info.spectators_on = NetworkSpectatorCount();
+	_network_game_info.grfconfig     = _grfconfig;
+
+	NetworkSend_NetworkGameInfo(p, &_network_game_info);
+
+	// Let the client know that we are here
+	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+
+	free(packet);
+
+	DEBUG(net, 2, "[udp] queried from '%s'", inet_ntoa(client_addr->sin_addr));
+}
+
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
+{
+	/* Find the matching GRF file */
+	const GRFConfig *f = FindGRFConfig(config->grfid, config->md5sum);
+	if (f == NULL) {
+		/* Don't know the GRF, so mark game incompatible and the (possibly)
+		 * already resolved name for this GRF (another server has sent the
+		 * name of the GRF already */
+		config->name     = FindUnknownGRFName(config->grfid, config->md5sum, true);
+		SETBIT(config->flags, GCF_NOT_FOUND);
+	} else {
+		config->filename = f->filename;
+		config->name     = f->name;
+		config->info     = f->info;
+	}
+	SETBIT(config->flags, GCF_COPY);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
+{
+	extern const char _openttd_revision[];
+	NetworkGameList *item;
+
+	// Just a fail-safe.. should never happen
+	if (_network_udp_server || _udp_cs.has_quit) return;
+
+	DEBUG(net, 4, "[udp] server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
+
+	// Find next item
+	item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
+
+	NetworkRecv_NetworkGameInfo(&_udp_cs, p, &item->info);
+
+	item->info.compatible = true;
+	{
+		/* Checks whether there needs to be a request for names of GRFs and makes
+		 * the request if necessary. GRFs that need to be requested are the GRFs
+		 * that do not exist on the clients system and we do not have the name
+		 * resolved of, i.e. the name is still UNKNOWN_GRF_NAME_PLACEHOLDER.
+		 * The in_request array and in_request_count are used so there is no need
+		 * to do a second loop over the GRF list, which can be relatively expensive
+		 * due to the string comparisons. */
+		const GRFConfig *in_request[NETWORK_MAX_GRF_COUNT];
+		const GRFConfig *c;
+		uint in_request_count = 0;
+		struct sockaddr_in out_addr;
+
+		for (c = item->info.grfconfig; c != NULL; c = c->next) {
+			if (HASBIT(c->flags, GCF_NOT_FOUND)) item->info.compatible = false;
+			if (!HASBIT(c->flags, GCF_NOT_FOUND) || strcmp(c->name, UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
+			in_request[in_request_count] = c;
+			in_request_count++;
+		}
+
+		if (in_request_count > 0) {
+			/* There are 'unknown' GRFs, now send a request for them */
+			uint i;
+			Packet *packet = NetworkSend_Init(PACKET_UDP_CLIENT_GET_NEWGRFS);
+
+			NetworkSend_uint8 (packet, in_request_count);
+			for (i = 0; i < in_request_count; i++) {
+				NetworkSend_GRFIdentifier(packet, in_request[i]);
+			}
+
+			out_addr.sin_family      = AF_INET;
+			out_addr.sin_port        = htons(item->port);
+			out_addr.sin_addr.s_addr = item->ip;
+			NetworkSendUDP_Packet(_udp_client_socket, packet, &out_addr);
+			free(packet);
+		}
+	}
+
+	if (item->info.server_lang >= NETWORK_NUM_LANGUAGES) item->info.server_lang = 0;
+	if (item->info.map_set >= NUM_LANDSCAPE ) item->info.map_set = 0;
+
+	if (item->info.hostname[0] == '\0')
+		snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
+
+	/* Check if we are allowed on this server based on the revision-match */
+	item->info.version_compatible =
+		strcmp(item->info.server_revision, _openttd_revision) == 0 ||
+		strcmp(item->info.server_revision, NOREV_STRING) == 0;
+	item->info.compatible &= item->info.version_compatible; // Already contains match for GRFs
+
+	item->online = true;
+
+	UpdateNetworkGameWindow(false);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
+{
+	NetworkClientState *cs;
+	NetworkClientInfo *ci;
+	Packet *packet;
+	Player *player;
+	byte current = 0;
+	int i;
+
+	// Just a fail-safe.. should never happen
+	if (!_network_udp_server) return;
+
+	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
+
+	/* Send the amount of active companies */
+	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
+	NetworkSend_uint8 (packet, ActivePlayerCount());
+
+	/* Fetch the latest version of everything */
+	NetworkPopulateCompanyInfo();
+
+	/* Go through all the players */
+	FOR_ALL_PLAYERS(player) {
+		/* Skip non-active players */
+		if (!player->is_active) continue;
+
+		current++;
+
+		/* Send the information */
+		NetworkSend_uint8(packet, current);
+
+		NetworkSend_string(packet, _network_player_info[player->index].company_name);
+		NetworkSend_uint32(packet, _network_player_info[player->index].inaugurated_year);
+		NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
+		NetworkSend_uint64(packet, _network_player_info[player->index].money);
+		NetworkSend_uint64(packet, _network_player_info[player->index].income);
+		NetworkSend_uint16(packet, _network_player_info[player->index].performance);
+
+		/* Send 1 if there is a passord for the company else send 0 */
+		if (_network_player_info[player->index].password[0] != '\0') {
+			NetworkSend_uint8(packet, 1);
+		} else {
+			NetworkSend_uint8(packet, 0);
+		}
+
+		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
+			NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
+
+		for (i = 0; i < NETWORK_STATION_TYPES; i++)
+			NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
+
+		/* Find the clients that are connected to this player */
+		FOR_ALL_CLIENTS(cs) {
+			ci = DEREF_CLIENT_INFO(cs);
+			if (ci->client_playas == player->index) {
+				/* The uint8 == 1 indicates that a client is following */
+				NetworkSend_uint8(packet, 1);
+				NetworkSend_string(packet, ci->client_name);
+				NetworkSend_string(packet, ci->unique_id);
+				NetworkSend_uint32(packet, ci->join_date);
+			}
+		}
+		/* Also check for the server itself */
+		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+		if (ci->client_playas == player->index) {
+			/* The uint8 == 1 indicates that a client is following */
+			NetworkSend_uint8(packet, 1);
+			NetworkSend_string(packet, ci->client_name);
+			NetworkSend_string(packet, ci->unique_id);
+			NetworkSend_uint32(packet, ci->join_date);
+		}
+
+		/* Indicates end of client list */
+		NetworkSend_uint8(packet, 0);
+	}
+
+	/* And check if we have any spectators */
+	FOR_ALL_CLIENTS(cs) {
+		ci = DEREF_CLIENT_INFO(cs);
+		if (!IsValidPlayer(ci->client_playas)) {
+			/* The uint8 == 1 indicates that a client is following */
+			NetworkSend_uint8(packet, 1);
+			NetworkSend_string(packet, ci->client_name);
+			NetworkSend_string(packet, ci->unique_id);
+			NetworkSend_uint32(packet, ci->join_date);
+		}
+	}
+
+	/* Also check for the server itself */
+	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+	if (!IsValidPlayer(ci->client_playas)) {
+		/* The uint8 == 1 indicates that a client is following */
+		NetworkSend_uint8(packet, 1);
+		NetworkSend_string(packet, ci->client_name);
+		NetworkSend_string(packet, ci->unique_id);
+		NetworkSend_uint32(packet, ci->join_date);
+	}
+
+	/* Indicates end of client list */
+	NetworkSend_uint8(packet, 0);
+
+	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+
+	free(packet);
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST)
+{
+	int i;
+	struct in_addr ip;
+	uint16 port;
+	uint8 ver;
+
+	/* packet begins with the protocol version (uint8)
+	 * then an uint16 which indicates how many
+	 * ip:port pairs are in this packet, after that
+	 * an uint32 (ip) and an uint16 (port) for each pair
+	 */
+
+	ver = NetworkRecv_uint8(&_udp_cs, p);
+
+	if (_udp_cs.has_quit) return;
+
+	if (ver == 1) {
+		for (i = NetworkRecv_uint16(&_udp_cs, p); i != 0 ; i--) {
+			ip.s_addr = TO_LE32(NetworkRecv_uint32(&_udp_cs, p));
+			port = NetworkRecv_uint16(&_udp_cs, p);
+			NetworkUDPQueryServer(inet_ntoa(ip), port);
+		}
+	}
+}
+
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER)
+{
+	_network_advertise_retries = 0;
+	DEBUG(net, 2, "[udp] advertising on master server successfull");
+
+	/* We are advertised, but we don't want to! */
+	if (!_network_advertise) NetworkUDPRemoveAdvertise();
+}
+
+/**
+ * A client has requested the names of some NewGRFs.
+ *
+ * Replying this can be tricky as we have a limit of SEND_MTU bytes
+ * in the reply packet and we can send up to 100 bytes per NewGRF
+ * (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name).
+ * As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
+ * could be that a packet overflows. To stop this we only reply
+ * with the first N NewGRFs so that if the first N + 1 NewGRFs
+ * would be sent, the packet overflows.
+ * in_reply and in_reply_count are used to keep a list of GRFs to
+ * send in the reply.
+ */
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS)
+{
+	uint8 num_grfs;
+	uint i;
+
+	const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT];
+	Packet *packet;
+	uint8 in_reply_count = 0;
+	uint packet_len = 0;
+
+	/* Just a fail-safe.. should never happen */
+	if (_udp_cs.has_quit) return;
+
+	DEBUG(net, 6, "[udp] newgrf data request from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));
+
+	num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
+	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
+
+	for (i = 0; i < num_grfs; i++) {
+		GRFConfig c;
+		const GRFConfig *f;
+
+		NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
+
+		/* Find the matching GRF file */
+		f = FindGRFConfig(c.grfid, c.md5sum);
+		if (f == NULL) continue; // The GRF is unknown to this server
+
+		/* If the reply might exceed the size of the packet, only reply
+		 * the current list and do not send the other data.
+		 * The name could be an empty string, if so take the filename. */
+		packet_len += sizeof(c.grfid) + sizeof(c.md5sum) +
+				min(strlen((f->name != NULL && strlen(f->name) > 0) ? f->name : f->filename) + 1, NETWORK_GRF_NAME_LENGTH);
+		if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply
+			break;
+		}
+		in_reply[in_reply_count] = f;
+		in_reply_count++;
+	}
+
+	if (in_reply_count == 0) return;
+
+	packet = NetworkSend_Init(PACKET_UDP_SERVER_NEWGRFS);
+	NetworkSend_uint8 (packet, in_reply_count);
+	for (i = 0; i < in_reply_count; i++) {
+		char name[NETWORK_GRF_NAME_LENGTH];
+
+		/* The name could be an empty string, if so take the filename */
+		ttd_strlcpy(name, (in_reply[i]->name != NULL && strlen(in_reply[i]->name) > 0) ?
+				in_reply[i]->name : in_reply[i]->filename, sizeof(name));
+	 	NetworkSend_GRFIdentifier(packet, in_reply[i]);
+		NetworkSend_string(packet, name);
+	}
+
+	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
+	free(packet);
+}
+
+/** The return of the client's request of the names of some NewGRFs */
+DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS)
+{
+	uint8 num_grfs;
+	uint i;
+
+	/* Just a fail-safe.. should never happen */
+	if (_udp_cs.has_quit) return;
+
+	DEBUG(net, 6, "[udp] newgrf data reply from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
+
+	num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
+	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
+
+	for (i = 0; i < num_grfs; i++) {
+		char *unknown_name;
+		char name[NETWORK_GRF_NAME_LENGTH];
+		GRFConfig c;
+
+		NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
+		NetworkRecv_string(&_udp_cs, p, name, sizeof(name));
+
+		/* An empty name is not possible under normal circumstances
+		 * and causes problems when showing the NewGRF list. */
+		if (strlen(name) == 0) continue;
+
+		/* Finds the fake GRFConfig for the just read GRF ID and MD5sum tuple.
+		 * If it exists and not resolved yet, then name of the fake GRF is
+		 * overwritten with the name from the reply. */
+		unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
+		if (unknown_name != NULL && strcmp(unknown_name, UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
+			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
+		}
+	}
+}
+
+
+// The layout for the receive-functions by UDP
+typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+
+static NetworkUDPPacket* const _network_udp_packet[] = {
+	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
+	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
+	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
+	NULL,
+	NULL,
+	RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
+	NULL,
+	RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST),
+	NULL,
+	RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),
+	RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),
+};
+
+
+// If this fails, check the array above with network_data.h
+assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
+
+
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
+{
+	byte type;
+
+	/* Fake a client, so we can see when there is an illegal packet */
+	_udp_cs.socket = INVALID_SOCKET;
+	_udp_cs.has_quit = false;
+
+	type = NetworkRecv_uint8(&_udp_cs, p);
+
+	if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.has_quit) {
+		_network_udp_packet[type](p, client_addr);
+	} else {
+		if (!_udp_cs.has_quit) {
+			DEBUG(net, 0, "[udp] received invalid packet type %d", type);
+		} else {
+			DEBUG(net, 0, "[udp] received illegal packet");
+		}
+	}
+}
+
+
+// Close UDP connection
+void NetworkUDPClose(void)
+{
+	DEBUG(net, 1, "[udp] closed listeners");
+
+	if (_network_udp_server) {
+		if (_udp_server_socket != INVALID_SOCKET) {
+			closesocket(_udp_server_socket);
+			_udp_server_socket = INVALID_SOCKET;
+		}
+
+		if (_udp_master_socket != INVALID_SOCKET) {
+			closesocket(_udp_master_socket);
+			_udp_master_socket = INVALID_SOCKET;
+		}
+
+		_network_udp_server = false;
+		_network_udp_broadcast = 0;
+	} else {
+		if (_udp_client_socket != INVALID_SOCKET) {
+			closesocket(_udp_client_socket);
+			_udp_client_socket = INVALID_SOCKET;
+		}
+		_network_udp_broadcast = 0;
+	}
+}
+
+// Broadcast to all ips
+static void NetworkUDPBroadCast(SOCKET udp)
+{
+	Packet* p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
+	uint i;
+
+	for (i = 0; _broadcast_list[i] != 0; i++) {
+		struct sockaddr_in out_addr;
+
+		out_addr.sin_family = AF_INET;
+		out_addr.sin_port = htons(_network_server_port);
+		out_addr.sin_addr.s_addr = _broadcast_list[i];
+
+		DEBUG(net, 4, "[udp] broadcasting to %s", inet_ntoa(out_addr.sin_addr));
+
+		NetworkSendUDP_Packet(udp, p, &out_addr);
+	}
+
+	free(p);
+}
+
+
+// Request the the server-list from the master server
+void NetworkUDPQueryMasterServer(void)
+{
+	struct sockaddr_in out_addr;
+	Packet *p;
+
+	if (_udp_client_socket == INVALID_SOCKET)
+		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+			return;
+
+	p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
+
+	out_addr.sin_family = AF_INET;
+	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+	// packet only contains protocol version
+	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+
+	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
+
+	DEBUG(net, 2, "[udp] master server queried at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
+
+	free(p);
+}
+
+// Find all servers
+void NetworkUDPSearchGame(void)
+{
+	// We are still searching..
+	if (_network_udp_broadcast > 0) return;
+
+	// No UDP-socket yet..
+	if (_udp_client_socket == INVALID_SOCKET)
+		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+			return;
+
+	DEBUG(net, 0, "[udp] searching server");
+
+	NetworkUDPBroadCast(_udp_client_socket);
+	_network_udp_broadcast = 300; // Stay searching for 300 ticks
+}
+
+NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
+{
+	struct sockaddr_in out_addr;
+	Packet *p;
+	NetworkGameList *item;
+
+	// No UDP-socket yet..
+	if (_udp_client_socket == INVALID_SOCKET)
+		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
+			return NULL;
+
+	out_addr.sin_family = AF_INET;
+	out_addr.sin_port = htons(port);
+	out_addr.sin_addr.s_addr = NetworkResolveHost(host);
+
+	// Clear item in gamelist
+	item = NetworkGameListAddItem(inet_addr(inet_ntoa(out_addr.sin_addr)), ntohs(out_addr.sin_port));
+	memset(&item->info, 0, sizeof(item->info));
+	ttd_strlcpy(item->info.server_name, host, lengthof(item->info.server_name));
+	ttd_strlcpy(item->info.hostname, host, lengthof(item->info.hostname));
+	item->online = false;
+
+	// Init the packet
+	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
+
+	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
+
+	free(p);
+
+	UpdateNetworkGameWindow(false);
+	return item;
+}
+
+/* Remove our advertise from the master-server */
+void NetworkUDPRemoveAdvertise(void)
+{
+	struct sockaddr_in out_addr;
+	Packet *p;
+
+	/* Check if we are advertising */
+	if (!_networking || !_network_server || !_network_udp_server) return;
+
+	/* check for socket */
+	if (_udp_master_socket == INVALID_SOCKET)
+		if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
+			return;
+
+	DEBUG(net, 1, "[udp] removing advertise from master server");
+
+	/* Find somewhere to send */
+	out_addr.sin_family = AF_INET;
+	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+	/* Send the packet */
+	p = NetworkSend_Init(PACKET_UDP_SERVER_UNREGISTER);
+	/* Packet is: Version, server_port */
+	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+	NetworkSend_uint16(p, _network_server_port);
+	NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
+
+	free(p);
+}
+
+/* Register us to the master server
+     This function checks if it needs to send an advertise */
+void NetworkUDPAdvertise(void)
+{
+	struct sockaddr_in out_addr;
+	Packet *p;
+
+	/* Check if we should send an advertise */
+	if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
+		return;
+
+	/* check for socket */
+	if (_udp_master_socket == INVALID_SOCKET)
+		if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
+			return;
+
+	if (_network_need_advertise) {
+		_network_need_advertise = false;
+		_network_advertise_retries = ADVERTISE_RETRY_TIMES;
+	} else {
+		/* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */
+		if (_network_advertise_retries == 0) {
+			if ((_network_last_advertise_frame + ADVERTISE_NORMAL_INTERVAL) > _frame_counter)
+				return;
+			_network_advertise_retries = ADVERTISE_RETRY_TIMES;
+		}
+
+		if ((_network_last_advertise_frame + ADVERTISE_RETRY_INTERVAL) > _frame_counter)
+			return;
+	}
+
+	_network_advertise_retries--;
+	_network_last_advertise_frame = _frame_counter;
+
+	/* Find somewhere to send */
+	out_addr.sin_family = AF_INET;
+	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
+	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
+
+	DEBUG(net, 1, "[udp] advertising to master server");
+
+	/* Send the packet */
+	p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
+	/* Packet is: WELCOME_MESSAGE, Version, server_port */
+	NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
+	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
+	NetworkSend_uint16(p, _network_server_port);
+	NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
+
+	free(p);
+}
+
+void NetworkUDPInitialize(void)
+{
+	_udp_client_socket = INVALID_SOCKET;
+	_udp_server_socket = INVALID_SOCKET;
+	_udp_master_socket = INVALID_SOCKET;
+
+	_network_udp_server = false;
+	_network_udp_broadcast = 0;
+}
+
+#endif /* ENABLE_NETWORK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network/network_udp.h	Tue Jan 02 17:34:03 2007 +0000
@@ -0,0 +1,17 @@
+/* $Id$ */
+
+#ifndef NETWORK_UDP_H
+#define NETWORK_UDP_H
+
+#ifdef ENABLE_NETWORK
+
+void NetworkUDPInitialize(void);
+void NetworkUDPSearchGame(void);
+void NetworkUDPQueryMasterServer(void);
+NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port);
+void NetworkUDPAdvertise(void);
+void NetworkUDPRemoveAdvertise(void);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_UDP_H */
--- a/network_client.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,818 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "debug.h"
-#include "string.h"
-#include "strings.h"
-#include "network_data.h"
-#include "date.h"
-#include "table/strings.h"
-#include "functions.h"
-#include "network_client.h"
-#include "network_gamelist.h"
-#include "network_gui.h"
-#include "saveload.h"
-#include "command.h"
-#include "window.h"
-#include "console.h"
-#include "variables.h"
-#include "ai/ai.h"
-
-
-// This file handles all the client-commands
-
-
-// So we don't make too much typos ;)
-#define MY_CLIENT DEREF_CLIENT(0)
-
-static uint32 last_ack_frame;
-
-// **********
-// Sending functions
-//   DEF_CLIENT_SEND_COMMAND has no parameters
-// **********
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)
-{
-	//
-	// Packet: CLIENT_COMPANY_INFO
-	// Function: Request company-info (in detail)
-	// Data:
-	//    <none>
-	//
-	Packet *p;
-	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
-	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-
-	p = NetworkSend_Init(PACKET_CLIENT_COMPANY_INFO);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
-{
-	//
-	// Packet: CLIENT_JOIN
-	// Function: Try to join the server
-	// Data:
-	//    String: OpenTTD Revision (norev000 if no revision)
-	//    String: Player Name (max NETWORK_NAME_LENGTH)
-	//    uint8:  Play as Player id (1..MAX_PLAYERS)
-	//    uint8:  Language ID
-	//    String: Unique id to find the player back in server-listing
-	//
-
-	extern const char _openttd_revision[];
-	Packet *p;
-	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
-	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-
-	p = NetworkSend_Init(PACKET_CLIENT_JOIN);
-	NetworkSend_string(p, _openttd_revision);
-	NetworkSend_string(p, _network_player_name); // Player name
-	NetworkSend_uint8(p, _network_playas); // PlayAs
-	NetworkSend_uint8(p, NETLANG_ANY); // Language
-	NetworkSend_string(p, _network_unique_id);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password)
-{
-	//
-	// Packet: CLIENT_PASSWORD
-	// Function: Send a password to the server to authorize
-	// Data:
-	//    uint8:  NetworkPasswordType
-	//    String: Password
-	//
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_PASSWORD);
-	NetworkSend_uint8(p, type);
-	NetworkSend_string(p, password);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GETMAP)
-{
-	//
-	// Packet: CLIENT_GETMAP
-	// Function: Request the map from the server
-	// Data:
-	//    <none>
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_GETMAP);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_MAP_OK)
-{
-	//
-	// Packet: CLIENT_MAP_OK
-	// Function: Tell the server that we are done receiving/loading the map
-	// Data:
-	//    <none>
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_MAP_OK);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK)
-{
-	//
-	// Packet: CLIENT_ACK
-	// Function: Tell the server we are done with this frame
-	// Data:
-	//    uint32: current FrameCounter of the client
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_ACK);
-
-	NetworkSend_uint32(p, _frame_counter);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-// Send a command packet to the server
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp)
-{
-	//
-	// Packet: CLIENT_COMMAND
-	// Function: Send a DoCommand to the Server
-	// Data:
-	//    uint8:  PlayerID (0..MAX_PLAYERS-1)
-	//    uint32: CommandID (see command.h)
-	//    uint32: P1 (free variables used in DoCommand)
-	//    uint32: P2
-	//    uint32: Tile
-	//    string: text
-	//    uint8:  CallBackID (see callback_table.c)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_COMMAND);
-
-	NetworkSend_uint8(p, cp->player);
-	NetworkSend_uint32(p, cp->cmd);
-	NetworkSend_uint32(p, cp->p1);
-	NetworkSend_uint32(p, cp->p2);
-	NetworkSend_uint32(p, (uint32)cp->tile);
-	NetworkSend_string(p, cp->text);
-	NetworkSend_uint8(p, cp->callback);
-
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-// Send a chat-packet over the network
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType type, int dest, const char *msg)
-{
-	//
-	// Packet: CLIENT_CHAT
-	// Function: Send a chat-packet to the serve
-	// Data:
-	//    uint8:  ActionID (see network_data.h, NetworkAction)
-	//    uint8:  Destination Type (see network_data.h, DestType);
-	//    uint8:  Destination Player (1..MAX_PLAYERS)
-	//    String: Message (max MAX_TEXT_MSG_LEN)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_CHAT);
-
-	NetworkSend_uint8(p, action);
-	NetworkSend_uint8(p, type);
-	NetworkSend_uint8(p, dest);
-	NetworkSend_string(p, msg);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-// Send an error-packet over the network
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno)
-{
-	//
-	// Packet: CLIENT_ERROR
-	// Function: The client made an error and is quiting the game
-	// Data:
-	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
-	//
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_ERROR);
-
-	NetworkSend_uint8(p, errorno);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password)
-{
-	//
-	// Packet: PACKET_CLIENT_SET_PASSWORD
-	// Function: Set the password for the clients current company
-	// Data:
-	//    String: Password
-	//
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_PASSWORD);
-
-	NetworkSend_string(p, password);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name)
-{
-	//
-	// Packet: PACKET_CLIENT_SET_NAME
-	// Function: Gives the player a new name
-	// Data:
-	//    String: Name
-	//
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_NAME);
-
-	NetworkSend_string(p, name);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-// Send an quit-packet over the network
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg)
-{
-	//
-	// Packet: CLIENT_QUIT
-	// Function: The client is quiting the game
-	// Data:
-	//    String: leave-message
-	//
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_QUIT);
-
-	NetworkSend_string(p, leavemsg);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command)
-{
-	Packet *p = NetworkSend_Init(PACKET_CLIENT_RCON);
-	NetworkSend_string(p, pass);
-	NetworkSend_string(p, command);
-	NetworkSend_Packet(p, MY_CLIENT);
-}
-
-
-// **********
-// Receiving functions
-//   DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
-// **********
-
-extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FULL)
-{
-	// We try to join a server which is full
-	_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
-	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-
-	return NETWORK_RECV_STATUS_SERVER_FULL;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_BANNED)
-{
-	// We try to join a server where we are banned
-	_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_BANNED;
-	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-
-	return NETWORK_RECV_STATUS_SERVER_BANNED;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO)
-{
-	byte company_info_version;
-	int i;
-
-	company_info_version = NetworkRecv_uint8(MY_CLIENT, p);
-
-	if (!MY_CLIENT->has_quit && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
-		byte total;
-		byte current;
-
-		total = NetworkRecv_uint8(MY_CLIENT, p);
-
-		// There is no data at all..
-		if (total == 0) return NETWORK_RECV_STATUS_CLOSE_QUERY;
-
-		current = NetworkRecv_uint8(MY_CLIENT, p);
-		if (!IsValidPlayer(current)) return NETWORK_RECV_STATUS_CLOSE_QUERY;
-
-		NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].company_name, sizeof(_network_player_info[current].company_name));
-		_network_player_info[current].inaugurated_year = NetworkRecv_uint32(MY_CLIENT, p);
-		_network_player_info[current].company_value = NetworkRecv_uint64(MY_CLIENT, p);
-		_network_player_info[current].money = NetworkRecv_uint64(MY_CLIENT, p);
-		_network_player_info[current].income = NetworkRecv_uint64(MY_CLIENT, p);
-		_network_player_info[current].performance = NetworkRecv_uint16(MY_CLIENT, p);
-		_network_player_info[current].use_password = NetworkRecv_uint8(MY_CLIENT, p);
-		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
-			_network_player_info[current].num_vehicle[i] = NetworkRecv_uint16(MY_CLIENT, p);
-		for (i = 0; i < NETWORK_STATION_TYPES; i++)
-			_network_player_info[current].num_station[i] = NetworkRecv_uint16(MY_CLIENT, p);
-
-		NetworkRecv_string(MY_CLIENT, p, _network_player_info[current].players, sizeof(_network_player_info[current].players));
-
-		InvalidateWindow(WC_NETWORK_WINDOW, 0);
-
-		return NETWORK_RECV_STATUS_OKAY;
-	}
-
-	return NETWORK_RECV_STATUS_CLOSE_QUERY;
-}
-
-// This packet contains info about the client (playas and name)
-//  as client we save this in NetworkClientInfo, linked via 'index'
-//  which is always an unique number on a server.
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
-{
-	NetworkClientInfo *ci;
-	uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
-	PlayerID playas = NetworkRecv_uint8(MY_CLIENT, p);
-	char name[NETWORK_NAME_LENGTH];
-	char unique_id[NETWORK_NAME_LENGTH];
-
-	NetworkRecv_string(MY_CLIENT, p, name, sizeof(name));
-	NetworkRecv_string(MY_CLIENT, p, unique_id, sizeof(unique_id));
-
-	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
-
-	/* Do we receive a change of data? Most likely we changed playas */
-	if (index == _network_own_client_index) _network_playas = playas;
-
-	ci = NetworkFindClientInfoFromIndex(index);
-	if (ci != NULL) {
-		if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
-			// Client name changed, display the change
-			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", name);
-		} else if (playas != ci->client_playas) {
-			// The player changed from client-player..
-			// Do not display that for now
-		}
-
-		ci->client_playas = playas;
-		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
-
-		InvalidateWindow(WC_CLIENT_LIST, 0);
-
-		return NETWORK_RECV_STATUS_OKAY;
-	}
-
-	// We don't have this index yet, find an empty index, and put the data there
-	ci = NetworkFindClientInfoFromIndex(NETWORK_EMPTY_INDEX);
-	if (ci != NULL) {
-		ci->client_index = index;
-		ci->client_playas = playas;
-
-		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
-		ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
-
-		InvalidateWindow(WC_CLIENT_LIST, 0);
-
-		return NETWORK_RECV_STATUS_OKAY;
-	}
-
-	// Here the program should never ever come.....
-	return NETWORK_RECV_STATUS_MALFORMED_PACKET;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
-{
-	NetworkErrorCode error = NetworkRecv_uint8(MY_CLIENT, p);
-
-	switch (error) {
-		/* We made an error in the protocol, and our connection is closed.... */
-		case NETWORK_ERROR_NOT_AUTHORIZED:
-		case NETWORK_ERROR_NOT_EXPECTED:
-		case NETWORK_ERROR_PLAYER_MISMATCH:
-			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_ERROR;
-			break;
-		case NETWORK_ERROR_FULL:
-			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
-			break;
-		case NETWORK_ERROR_WRONG_REVISION:
-			_switch_mode_errorstr = STR_NETWORK_ERR_WRONG_REVISION;
-			break;
-		case NETWORK_ERROR_WRONG_PASSWORD:
-			_switch_mode_errorstr = STR_NETWORK_ERR_WRONG_PASSWORD;
-			break;
-		case NETWORK_ERROR_KICKED:
-			_switch_mode_errorstr = STR_NETWORK_ERR_KICKED;
-			break;
-		case NETWORK_ERROR_CHEATER:
-			_switch_mode_errorstr = STR_NETWORK_ERR_CHEATER;
-			break;
-		default:
-			_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
-	}
-
-	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-
-	return NETWORK_RECV_STATUS_SERVER_ERROR;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD)
-{
-	NetworkPasswordType type = NetworkRecv_uint8(MY_CLIENT, p);
-
-	switch (type) {
-		case NETWORK_GAME_PASSWORD:
-		case NETWORK_COMPANY_PASSWORD:
-			ShowNetworkNeedPassword(type);
-			return NETWORK_RECV_STATUS_OKAY;
-
-		default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
-	}
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WELCOME)
-{
-	_network_own_client_index = NetworkRecv_uint16(MY_CLIENT, p);
-
-	// Start receiving the map
-	SEND_COMMAND(PACKET_CLIENT_GETMAP)();
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WAIT)
-{
-	_network_join_status = NETWORK_JOIN_STATUS_WAITING;
-	_network_join_waiting = NetworkRecv_uint8(MY_CLIENT, p);
-	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-
-	// We are put on hold for receiving the map.. we need GUI for this ;)
-	DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
-	DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
-{
-	static char filename[256];
-	static FILE *file_pointer;
-
-	byte maptype;
-
-	maptype = NetworkRecv_uint8(MY_CLIENT, p);
-
-	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
-
-	// First packet, init some stuff
-	if (maptype == MAP_PACKET_START) {
-		// The name for the temp-map
-		snprintf(filename, lengthof(filename), "%s%snetwork_client.tmp",  _paths.autosave_dir, PATHSEP);
-
-		file_pointer = fopen(filename, "wb");
-		if (file_pointer == NULL) {
-			_switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
-			return NETWORK_RECV_STATUS_SAVEGAME;
-		}
-
-		_frame_counter = _frame_counter_server = _frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
-
-		_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
-		_network_join_kbytes = 0;
-		_network_join_kbytes_total = NetworkRecv_uint32(MY_CLIENT, p) / 1024;
-		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-
-		// The first packet does not contain any more data
-		return NETWORK_RECV_STATUS_OKAY;
-	}
-
-	if (maptype == MAP_PACKET_NORMAL) {
-		// We are still receiving data, put it to the file
-		fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer);
-
-		_network_join_kbytes = ftell(file_pointer) / 1024;
-		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-	}
-
-	// Check if this was the last packet
-	if (maptype == MAP_PACKET_END) {
-		fclose(file_pointer);
-
-		_network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
-		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
-
-		/* The map is done downloading, load it */
-		if (!SafeSaveOrLoad(filename, SL_LOAD, GM_NORMAL)) {
-			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-			_switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
-			return NETWORK_RECV_STATUS_SAVEGAME;
-		}
-		/* If the savegame has successfully loaded, ALL windows have been removed,
-		 * only toolbar/statusbar and gamefield are visible */
-
-		_opt_ptr = &_opt; // during a network game you are always in-game
-
-		// Say we received the map and loaded it correctly!
-		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
-
-		/* New company/spectator (invalid player) or company we want to join is not active
-		 * Switch local player to spectator and await the server's judgement */
-		if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas) ||
-				!GetPlayer(_network_playas)->is_active) {
-
-			SetLocalPlayer(PLAYER_SPECTATOR);
-
-			if (_network_playas != PLAYER_SPECTATOR) {
-				/* We have arrived and ready to start playing; send a command to make a new player;
-				 * the server will give us a client-id and let us in */
-				_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
-				ShowJoinStatusWindow();
-				NetworkSend_Command(0, 0, 0, CMD_PLAYER_CTRL, NULL);
-			}
-		} else {
-			// take control over an existing company
-			SetLocalPlayer(_network_playas);
-		}
-	}
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_FRAME)
-{
-	_frame_counter_server = NetworkRecv_uint32(MY_CLIENT, p);
-	_frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
-#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
-	// Test if the server supports this option
-	//  and if we are at the frame the server is
-	if (p->pos < p->size) {
-		_sync_frame = _frame_counter_server;
-		_sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
-#ifdef NETWORK_SEND_DOUBLE_SEED
-		_sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
-#endif
-	}
-#endif
-	DEBUG(net, 5, "Received FRAME %d", _frame_counter_server);
-
-	// Let the server know that we received this frame correctly
-	//  We do this only once per day, to save some bandwidth ;)
-	if (!_network_first_time && last_ack_frame < _frame_counter) {
-		last_ack_frame = _frame_counter + DAY_TICKS;
-		DEBUG(net, 4, "Sent ACK at %d", _frame_counter);
-		SEND_COMMAND(PACKET_CLIENT_ACK)();
-	}
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SYNC)
-{
-	_sync_frame = NetworkRecv_uint32(MY_CLIENT, p);
-	_sync_seed_1 = NetworkRecv_uint32(MY_CLIENT, p);
-#ifdef NETWORK_SEND_DOUBLE_SEED
-	_sync_seed_2 = NetworkRecv_uint32(MY_CLIENT, p);
-#endif
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMMAND)
-{
-	CommandPacket *cp = malloc(sizeof(CommandPacket));
-	cp->player = NetworkRecv_uint8(MY_CLIENT, p);
-	cp->cmd = NetworkRecv_uint32(MY_CLIENT, p);
-	cp->p1 = NetworkRecv_uint32(MY_CLIENT, p);
-	cp->p2 = NetworkRecv_uint32(MY_CLIENT, p);
-	cp->tile = NetworkRecv_uint32(MY_CLIENT, p);
-	NetworkRecv_string(MY_CLIENT, p, cp->text, sizeof(cp->text));
-	cp->callback = NetworkRecv_uint8(MY_CLIENT, p);
-	cp->frame = NetworkRecv_uint32(MY_CLIENT, p);
-	cp->next = NULL;
-
-	// The server did send us this command..
-	//  queue it in our own queue, so we can handle it in the upcoming frame!
-
-	if (_local_command_queue == NULL) {
-		_local_command_queue = cp;
-	} else {
-		// Find last packet
-		CommandPacket *c = _local_command_queue;
-		while (c->next != NULL) c = c->next;
-		c->next = cp;
-	}
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CHAT)
-{
-	char name[NETWORK_NAME_LENGTH], msg[MAX_TEXT_MSG_LEN];
-	const NetworkClientInfo *ci = NULL, *ci_to;
-
-	NetworkAction action = NetworkRecv_uint8(MY_CLIENT, p);
-	uint16 index = NetworkRecv_uint16(MY_CLIENT, p);
-	bool self_send = NetworkRecv_uint8(MY_CLIENT, p);
-	NetworkRecv_string(MY_CLIENT, p, msg, MAX_TEXT_MSG_LEN);
-
-	ci_to = NetworkFindClientInfoFromIndex(index);
-	if (ci_to == NULL) return NETWORK_RECV_STATUS_OKAY;
-
-	/* Did we initiate the action locally? */
-	if (self_send) {
-		switch (action) {
-			case NETWORK_ACTION_CHAT_CLIENT:
-				/* For speaking to client we need the client-name */
-				snprintf(name, sizeof(name), "%s", ci_to->client_name);
-				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
-				break;
-
-			/* For speaking to company or giving money, we need the player-name */
-			case NETWORK_ACTION_GIVE_MONEY:
-				if (!IsValidPlayer(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
-				/* fallthrough */
-			case NETWORK_ACTION_CHAT_COMPANY: {
-				StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
-
-				GetString(name, str, lastof(name));
-				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
-			} break;
-
-			default: NOT_REACHED(); break;
-		}
-	} else {
-		/* Display message from somebody else */
-		snprintf(name, sizeof(name), "%s", ci_to->client_name);
-		ci = ci_to;
-	}
-
-	if (ci != NULL)
-		NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), self_send, name, "%s", msg);
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
-{
-	char str[100];
-	uint16 index;
-	NetworkClientInfo *ci;
-
-	index = NetworkRecv_uint16(MY_CLIENT, p);
-	GetNetworkErrorMsg(str, NetworkRecv_uint8(MY_CLIENT, p), lastof(str));
-
-	ci = NetworkFindClientInfoFromIndex(index);
-	if (ci != NULL) {
-		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
-
-		// The client is gone, give the NetworkClientInfo free
-		ci->client_index = NETWORK_EMPTY_INDEX;
-	}
-
-	InvalidateWindow(WC_CLIENT_LIST, 0);
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_QUIT)
-{
-	char str[100];
-	uint16 index;
-	NetworkClientInfo *ci;
-
-	index = NetworkRecv_uint16(MY_CLIENT, p);
-	NetworkRecv_string(MY_CLIENT, p, str, lengthof(str));
-
-	ci = NetworkFindClientInfoFromIndex(index);
-	if (ci != NULL) {
-		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, ci->client_name, "%s", str);
-
-		// The client is gone, give the NetworkClientInfo free
-		ci->client_index = NETWORK_EMPTY_INDEX;
-	} else {
-		DEBUG(net, 0, "Unknown client (%d) is leaving the game", index);
-	}
-
-	InvalidateWindow(WC_CLIENT_LIST, 0);
-
-	// If we come here it means we could not locate the client.. strange :s
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_JOIN)
-{
-	uint16 index;
-	NetworkClientInfo *ci;
-
-	index = NetworkRecv_uint16(MY_CLIENT, p);
-
-	ci = NetworkFindClientInfoFromIndex(index);
-	if (ci != NULL)
-		NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, ci->client_name, "");
-
-	InvalidateWindow(WC_CLIENT_LIST, 0);
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN)
-{
-	_switch_mode_errorstr = STR_NETWORK_SERVER_SHUTDOWN;
-
-	return NETWORK_RECV_STATUS_SERVER_ERROR;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
-{
-	// To trottle the reconnects a bit, every clients waits
-	//  his _local_player value before reconnecting
-	// PLAYER_SPECTATOR is currently 255, so to avoid long wait periods
-	//  set the max to 10.
-	_network_reconnect = min(_local_player + 1, 10);
-	_switch_mode_errorstr = STR_NETWORK_SERVER_REBOOT;
-
-	return NETWORK_RECV_STATUS_SERVER_ERROR;
-}
-
-DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_RCON)
-{
-	char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
-	uint16 color_code;
-
-	color_code = NetworkRecv_uint16(MY_CLIENT, p);
-	NetworkRecv_string(MY_CLIENT, p, rcon_out, sizeof(rcon_out));
-
-	IConsolePrint(color_code, rcon_out);
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-
-
-// The layout for the receive-functions by the client
-typedef NetworkRecvStatus NetworkClientPacket(Packet *p);
-
-// This array matches PacketType. At an incoming
-//  packet it is matches against this array
-//  and that way the right function to handle that
-//  packet is found.
-static NetworkClientPacket* const _network_client_packet[] = {
-	RECEIVE_COMMAND(PACKET_SERVER_FULL),
-	RECEIVE_COMMAND(PACKET_SERVER_BANNED),
-	NULL, /*PACKET_CLIENT_JOIN,*/
-	RECEIVE_COMMAND(PACKET_SERVER_ERROR),
-	NULL, /*PACKET_CLIENT_COMPANY_INFO,*/
-	RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO),
-	RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO),
-	RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD),
-	NULL, /*PACKET_CLIENT_PASSWORD,*/
-	RECEIVE_COMMAND(PACKET_SERVER_WELCOME),
-	NULL, /*PACKET_CLIENT_GETMAP,*/
-	RECEIVE_COMMAND(PACKET_SERVER_WAIT),
-	RECEIVE_COMMAND(PACKET_SERVER_MAP),
-	NULL, /*PACKET_CLIENT_MAP_OK,*/
-	RECEIVE_COMMAND(PACKET_SERVER_JOIN),
-	RECEIVE_COMMAND(PACKET_SERVER_FRAME),
-	RECEIVE_COMMAND(PACKET_SERVER_SYNC),
-	NULL, /*PACKET_CLIENT_ACK,*/
-	NULL, /*PACKET_CLIENT_COMMAND,*/
-	RECEIVE_COMMAND(PACKET_SERVER_COMMAND),
-	NULL, /*PACKET_CLIENT_CHAT,*/
-	RECEIVE_COMMAND(PACKET_SERVER_CHAT),
-	NULL, /*PACKET_CLIENT_SET_PASSWORD,*/
-	NULL, /*PACKET_CLIENT_SET_NAME,*/
-	NULL, /*PACKET_CLIENT_QUIT,*/
-	NULL, /*PACKET_CLIENT_ERROR,*/
-	RECEIVE_COMMAND(PACKET_SERVER_QUIT),
-	RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT),
-	RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN),
-	RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
-	RECEIVE_COMMAND(PACKET_SERVER_RCON),
-	NULL, /*PACKET_CLIENT_RCON,*/
-};
-
-// If this fails, check the array above with network_data.h
-assert_compile(lengthof(_network_client_packet) == PACKET_END);
-
-// Is called after a client is connected to the server
-void NetworkClient_Connected(void)
-{
-	// Set the frame-counter to 0 so nothing happens till we are ready
-	_frame_counter = 0;
-	_frame_counter_server = 0;
-	last_ack_frame = 0;
-	// Request the game-info
-	SEND_COMMAND(PACKET_CLIENT_JOIN)();
-}
-
-// Reads the packets from the socket-stream, if available
-NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs)
-{
-	Packet *p;
-	NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY;
-
-	while (res == NETWORK_RECV_STATUS_OKAY && (p = NetworkRecv_Packet(cs, &res)) != NULL) {
-		byte type = NetworkRecv_uint8(MY_CLIENT, p);
-		if (type < PACKET_END && _network_client_packet[type] != NULL && !MY_CLIENT->has_quit) {
-			res = _network_client_packet[type](p);
-		} else {
-			res = NETWORK_RECV_STATUS_MALFORMED_PACKET;
-			DEBUG(net, 0, "[client] received invalid packet type %d", type);
-		}
-
-		free(p);
-	}
-
-	return res;
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_client.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_CLIENT_H
-#define NETWORK_CLIENT_H
-
-#ifdef ENABLE_NETWORK
-
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_GAME_INFO);
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(CommandPacket *cp);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType desttype, int dest, const char *msg);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name);
-DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK);
-DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command);
-
-NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs);
-void NetworkClient_Connected(void);
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_CLIENT_H */
--- a/network_core.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_CORE_H
-#define NETWORK_CORE_H
-
-// Network stuff has many things that needs to be included
-//  by default. All those things are in this file.
-
-// =============================
-// Include standard stuff per OS
-
-#ifdef ENABLE_NETWORK
-
-#if defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_2)
-	// OSX 10.2 don't have socklen_t defined, so we will define it here
-	typedef int socklen_t;
-#endif
-
-// Windows stuff
-#if defined(WIN32) || defined(WIN64)
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <windows.h>
-
-#if !(defined(__MINGW32__) || defined(__CYGWIN__))
-	// Windows has some different names for some types..
-	typedef SSIZE_T ssize_t;
-	typedef int socklen_t;
-#endif
-
-#define GET_LAST_ERROR() WSAGetLastError()
-#define EWOULDBLOCK WSAEWOULDBLOCK
-// Windows has some different names for some types..
-typedef unsigned long in_addr_t;
-#endif // WIN32
-
-// UNIX stuff
-#if defined(UNIX)
-#	define SOCKET int
-#	define INVALID_SOCKET -1
-#	if !defined(__MORPHOS__) && !defined(__AMIGA__)
-#		define ioctlsocket ioctl
-#	if !defined(BEOS_NET_SERVER)
-#		define closesocket close
-#	endif
-#		define GET_LAST_ERROR() (errno)
-#	endif
-// Need this for FIONREAD on solaris
-#	define BSD_COMP
-
-// Includes needed for UNIX-like systems
-#	include <unistd.h>
-#	include <sys/ioctl.h>
-#	if defined(__BEOS__) && defined(BEOS_NET_SERVER)
-#		include <be/net/socket.h>
-#		include <be/kernel/OS.h> // snooze()
-#		include <be/net/netdb.h>
-		typedef unsigned long in_addr_t;
-#		define INADDR_NONE INADDR_BROADCAST
-#	else
-#		include <sys/socket.h>
-#		include <netinet/in.h>
-#		include <netinet/tcp.h>
-#		include <arpa/inet.h>
-#		include <net/if.h>
-// According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3.
-#		if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__INNOTEK_LIBC__) \
-		   && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__)
-// If for any reason ifaddrs.h does not exist on your system, comment out
-//   the following two lines and an alternative way will be used to fetch
-//   the list of IPs from the system.
-#			include <ifaddrs.h>
-#			define HAVE_GETIFADDRS
-#		endif
-#		if defined(SUNOS) || defined(__MORPHOS__) || defined(__BEOS__)
-#			define INADDR_NONE 0xffffffff
-#		endif
-#		if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
-			// needed on Zeta
-#			include <sys/sockio.h>
-#		endif
-#	endif // BEOS_NET_SERVER
-
-#	if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
-		typedef uint32_t in_addr_t;
-#	endif
-
-#	include <errno.h>
-#	include <sys/time.h>
-#	include <netdb.h>
-#endif // UNIX
-
-#ifdef __BEOS__
-	typedef int socklen_t;
-#endif
-
-// OS/2 stuff
-#if defined(__OS2__)
-#	define SOCKET int
-#	define INVALID_SOCKET -1
-#	define ioctlsocket ioctl
-#	define closesocket close
-#	define GET_LAST_ERROR() (sock_errno())
-
-// Includes needed for OS/2 systems
-#	include <types.h>
-#	include <unistd.h>
-#	include <sys/ioctl.h>
-#	include <sys/socket.h>
-#	include <netinet/in.h>
-#	include <netinet/tcp.h>
-#	include <arpa/inet.h>
-#	include <net/if.h>
-#	include <errno.h>
-#	include <sys/time.h>
-#	include <netdb.h>
-#	include <nerrno.h>
-#	define INADDR_NONE 0xffffffff
-
-typedef int socklen_t;
-#if !defined(__INNOTEK_LIBC__)
-typedef unsigned long in_addr_t;
-#endif /* __INNOTEK_LIBC__ */
-#endif // OS/2
-
-// MorphOS and Amiga stuff
-#if defined(__MORPHOS__) || defined(__AMIGA__)
-#	include <exec/types.h>
-#	include <proto/exec.h>		// required for Open/CloseLibrary()
-#	if defined(__MORPHOS__)
-#		include <sys/filio.h> 	// FIO* defines
-#		include <sys/sockio.h>  // SIO* defines
-#		include <netinet/in.h>
-#	else // __AMIGA__
-#		include	<proto/socket.h>
-#	endif
-
-// Make the names compatible
-#	define closesocket(s) CloseSocket(s)
-#	define GET_LAST_ERROR() Errno()
-#	define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status)
-#	define ioctl ioctlsocket
-
-	typedef unsigned int in_addr_t;
-	typedef long         socklen_t;
-	extern struct Library *SocketBase;
-
-#	ifdef __AMIGA__
-	// for usleep() implementation
-	extern struct Device      *TimerBase;
-	extern struct MsgPort     *TimerPort;
-	extern struct timerequest *TimerRequest;
-#	endif
-#endif // __MORPHOS__ || __AMIGA__
-
-static inline bool SetNonBlocking(int d)
-{
-	#ifdef WIN32
-	u_long nonblocking = 1;
-	#else
-	int nonblocking = 1;
-	#endif
-	#if defined(__BEOS__) && defined(BEOS_NET_SERVER)
-	return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
-	#else
-	return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
-	#endif
-}
-
-static inline bool SetNoDelay(int d)
-{
-	// XXX should this be done at all?
-	#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server
-	int b = 1;
-	// The (const char*) cast is needed for windows
-	return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
-	#else
-	return true;
-	#endif
-}
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_CORE_H */
--- a/network_data.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,473 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "debug.h"
-#include "network_data.h"
-#include "functions.h"
-#include "string.h"
-#include "table/strings.h"
-#include "network_client.h"
-#include "command.h"
-#include "callback_table.h"
-#include "variables.h"
-
-// This files handles the send/receive of all packets
-
-// Create a packet for sending
-Packet *NetworkSend_Init(PacketType type)
-{
-	Packet *packet = malloc(sizeof(Packet));
-	// An error is inplace here, because it simply means we ran out of memory.
-	if (packet == NULL) error("Failed to allocate Packet");
-
-	// Skip the size so we can write that in before sending the packet
-	packet->size = sizeof(packet->size);
-	packet->buffer[packet->size++] = type;
-	packet->pos = 0;
-
-	return packet;
-}
-
-// The next couple of functions make sure we can send
-//  uint8, uint16, uint32 and uint64 endian-safe
-//  over the network. The order it uses is:
-//
-//  1 2 3 4
-//
-
-void NetworkSend_uint8(Packet *packet, uint8 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = data;
-}
-
-void NetworkSend_uint16(Packet *packet, uint16 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data, 0, 8);
-	packet->buffer[packet->size++] = GB(data, 8, 8);
-}
-
-void NetworkSend_uint32(Packet *packet, uint32 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data,  0, 8);
-	packet->buffer[packet->size++] = GB(data,  8, 8);
-	packet->buffer[packet->size++] = GB(data, 16, 8);
-	packet->buffer[packet->size++] = GB(data, 24, 8);
-}
-
-void NetworkSend_uint64(Packet *packet, uint64 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data,  0, 8);
-	packet->buffer[packet->size++] = GB(data,  8, 8);
-	packet->buffer[packet->size++] = GB(data, 16, 8);
-	packet->buffer[packet->size++] = GB(data, 24, 8);
-	packet->buffer[packet->size++] = GB(data, 32, 8);
-	packet->buffer[packet->size++] = GB(data, 40, 8);
-	packet->buffer[packet->size++] = GB(data, 48, 8);
-	packet->buffer[packet->size++] = GB(data, 56, 8);
-}
-
-// Sends a string over the network. It sends out
-//  the string + '\0'. No size-byte or something.
-void NetworkSend_string(Packet *packet, const char* data)
-{
-	assert(data != NULL);
-	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
-	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
-}
-
-// If PacketSize changes of size, you have to change the 2 packet->size
-//   lines below matching the size of packet->size/PacketSize!
-// (line 'packet->buffer[0] = packet->size & 0xFF;'  and below)
-assert_compile(sizeof(PacketSize) == 2);
-
-// This function puts the packet in the send-queue and it is send
-//  as soon as possible
-// (that is: the next tick, or maybe one tick later if the
-//   OS-network-buffer is full)
-void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
-{
-	Packet *p;
-	assert(packet != NULL);
-
-	packet->pos = 0;
-	packet->next = NULL;
-
-	packet->buffer[0] = GB(packet->size, 0, 8);
-	packet->buffer[1] = GB(packet->size, 8, 8);
-
-	// Locate last packet buffered for the client
-	p = cs->packet_queue;
-	if (p == NULL) {
-		// No packets yet
-		cs->packet_queue = packet;
-	} else {
-		// Skip to the last packet
-		while (p->next != NULL) p = p->next;
-		p->next = packet;
-	}
-}
-
-// Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
-//  A socket can make errors. When that happens
-//  this handles what to do.
-// For clients: close connection and drop back to main-menu
-// For servers: close connection and that is it
-static NetworkRecvStatus CloseConnection(NetworkClientState *cs)
-{
-	NetworkCloseClient(cs);
-
-	// Clients drop back to the main menu
-	if (!_network_server && _networking) {
-		_switch_mode = SM_MENU;
-		_networking = false;
-		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
-
-		return NETWORK_RECV_STATUS_CONN_LOST;
-	}
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-// Sends all the buffered packets out for this client
-//  it stops when:
-//   1) all packets are send (queue is empty)
-//   2) the OS reports back that it can not send any more
-//        data right now (full network-buffer, it happens ;))
-//   3) sending took too long
-bool NetworkSend_Packets(NetworkClientState *cs)
-{
-	ssize_t res;
-	Packet *p;
-
-	// We can not write to this socket!!
-	if (!cs->writable) return false;
-	if (cs->socket == INVALID_SOCKET) return false;
-
-	p = cs->packet_queue;
-	while (p != NULL) {
-		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
-		if (res == -1) {
-			int err = GET_LAST_ERROR();
-			if (err != EWOULDBLOCK) { // Something went wrong.. close client!
-				DEBUG(net, 0, "send failed with error %d", err);
-				CloseConnection(cs);
-				return false;
-			}
-			return true;
-		}
-		if (res == 0) {
-			// Client/server has left us :(
-			CloseConnection(cs);
-			return false;
-		}
-
-		p->pos += res;
-
-		// Is this packet sent?
-		if (p->pos == p->size) {
-			// Go to the next packet
-			cs->packet_queue = p->next;
-			free(p);
-			p = cs->packet_queue;
-		} else {
-			return true;
-		}
-	}
-
-	return true;
-}
-
-
-// Receiving commands
-// Again, the next couple of functions are endian-safe
-//  see the comment around NetworkSend_uint8 for more info.
-uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
-{
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 1 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	return packet->buffer[packet->pos++];
-}
-
-uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
-{
-	uint16 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 2 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint16)packet->buffer[packet->pos++];
-	n += (uint16)packet->buffer[packet->pos++] << 8;
-	return n;
-}
-
-uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
-{
-	uint32 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 4 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint32)packet->buffer[packet->pos++];
-	n += (uint32)packet->buffer[packet->pos++] << 8;
-	n += (uint32)packet->buffer[packet->pos++] << 16;
-	n += (uint32)packet->buffer[packet->pos++] << 24;
-	return n;
-}
-
-uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
-{
-	uint64 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 8 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint64)packet->buffer[packet->pos++];
-	n += (uint64)packet->buffer[packet->pos++] << 8;
-	n += (uint64)packet->buffer[packet->pos++] << 16;
-	n += (uint64)packet->buffer[packet->pos++] << 24;
-	n += (uint64)packet->buffer[packet->pos++] << 32;
-	n += (uint64)packet->buffer[packet->pos++] << 40;
-	n += (uint64)packet->buffer[packet->pos++] << 48;
-	n += (uint64)packet->buffer[packet->pos++] << 56;
-	return n;
-}
-
-// Reads a string till it finds a '\0' in the stream
-void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
-{
-	PacketSize pos;
-	char *bufp = buffer;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return;
-
-	pos = p->pos;
-	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
-
-	if (size == 0 || pos == p->size) {
-		*buffer = '\0';
-		// If size was sooner to zero then the string in the stream
-		//  skip till the \0, so the packet can be read out correctly for the rest
-		while (pos < p->size && p->buffer[pos] != '\0') pos++;
-		pos++;
-	}
-	p->pos = pos;
-
-	str_validate(bufp);
-}
-
-// If PacketSize changes of size, you have to change the 2 packet->size
-//   lines below matching the size of packet->size/PacketSize!
-// (the line: 'p->size = (uint16)p->buffer[0];' and below)
-assert_compile(sizeof(PacketSize) == 2);
-
-Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
-{
-	ssize_t res;
-	Packet *p;
-
-	*status = NETWORK_RECV_STATUS_OKAY;
-
-	if (cs->socket == INVALID_SOCKET) return NULL;
-
-	if (cs->packet_recv == NULL) {
-		cs->packet_recv = malloc(sizeof(Packet));
-		if (cs->packet_recv == NULL) error("Failed to allocate packet");
-		// Set pos to zero!
-		cs->packet_recv->pos = 0;
-		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
-	}
-
-	p = cs->packet_recv;
-
-	// Read packet size
-	if (p->pos < sizeof(PacketSize)) {
-		while (p->pos < sizeof(PacketSize)) {
-			// Read the size of the packet
-			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
-			if (res == -1) {
-				int err = GET_LAST_ERROR();
-				if (err != EWOULDBLOCK) {
-					/* Something went wrong... (104 is connection reset by peer) */
-					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
-					*status = CloseConnection(cs);
-					return NULL;
-				}
-				// Connection would block, so stop for now
-				return NULL;
-			}
-			if (res == 0) {
-				// Client/server has left
-				*status = CloseConnection(cs);
-				return NULL;
-			}
-			p->pos += res;
-		}
-
-		p->size = (uint16)p->buffer[0];
-		p->size += (uint16)p->buffer[1] << 8;
-
-		if (p->size > SEND_MTU) {
-			*status = CloseConnection(cs);
-			return NULL;
-		}
-	}
-
-	// Read rest of packet
-	while (p->pos < p->size) {
-		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
-		if (res == -1) {
-			int err = GET_LAST_ERROR();
-			if (err != EWOULDBLOCK) {
-				/* Something went wrong... (104 is connection reset by peer) */
-				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
-				*status = CloseConnection(cs);
-				return NULL;
-			}
-			// Connection would block
-			return NULL;
-		}
-		if (res == 0) {
-			// Client/server has left
-			*status = CloseConnection(cs);
-			return NULL;
-		}
-
-		p->pos += res;
-	}
-
-	// We have a complete packet, return it!
-	p->pos = 2;
-	p->next = NULL; // Should not be needed, but who knows...
-
-	// Prepare for receiving a new packet
-	cs->packet_recv = NULL;
-
-	return p;
-}
-
-// Add a command to the local command queue
-void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
-{
-	CommandPacket* new_cp = malloc(sizeof(*new_cp));
-
-	*new_cp = *cp;
-
-	if (cs->command_queue == NULL) {
-		cs->command_queue = new_cp;
-	} else {
-		CommandPacket *c = cs->command_queue;
-		while (c->next != NULL) c = c->next;
-		c->next = new_cp;
-	}
-}
-
-// Prepare a DoCommand to be send over the network
-void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
-{
-	CommandPacket *c = malloc(sizeof(CommandPacket));
-	byte temp_callback;
-
-	c->player = _local_player;
-	c->next = NULL;
-	c->tile = tile;
-	c->p1 = p1;
-	c->p2 = p2;
-	c->cmd = cmd;
-	c->callback = 0;
-
-	temp_callback = 0;
-
-	while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
-		temp_callback++;
-	if (temp_callback == _callback_table_count) {
-		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
-		temp_callback = 0; /* _callback_table[0] == NULL */
-	}
-
-	if (_network_server) {
-		// We are the server, so set the command to be executed next possible frame
-		c->frame = _frame_counter_max + 1;
-	} else {
-		c->frame = 0; // The client can't tell which frame, so just make it 0
-	}
-
-	ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
-
-	if (_network_server) {
-		// If we are the server, we queue the command in our 'special' queue.
-		//   In theory, we could execute the command right away, but then the
-		//   client on the server can do everything 1 tick faster than others.
-		//   So to keep the game fair, we delay the command with 1 tick
-		//   which gives about the same speed as most clients.
-		NetworkClientState *cs;
-
-		// And we queue it for delivery to the clients
-		FOR_ALL_CLIENTS(cs) {
-			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
-		}
-
-		// Only the server gets the callback, because clients should not get them
-		c->callback = temp_callback;
-		if (_local_command_queue == NULL) {
-			_local_command_queue = c;
-		} else {
-			// Find last packet
-			CommandPacket *cp = _local_command_queue;
-			while (cp->next != NULL) cp = cp->next;
-			cp->next = c;
-		}
-
-		return;
-	}
-
-	// Clients send their command to the server and forget all about the packet
-	c->callback = temp_callback;
-	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
-}
-
-// Execute a DoCommand we received from the network
-void NetworkExecuteCommand(CommandPacket *cp)
-{
-	_current_player = cp->player;
-	_cmd_text = cp->text;
-	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
-	if (cp->callback > _callback_table_count) {
-		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
-		cp->callback = 0;
-	}
-	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_data.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_DATA_H
-#define NETWORK_DATA_H
-
-#include "openttd.h"
-#include "network.h"
-#include "network_core.h"
-
-// Is the network enabled?
-#ifdef ENABLE_NETWORK
-
-#define SEND_MTU 1460
-#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */
-
-// The client-info-server-index is always 1
-#define NETWORK_SERVER_INDEX 1
-#define NETWORK_EMPTY_INDEX 0
-
-// What version of game-info do we use?
-#define NETWORK_GAME_INFO_VERSION 4
-// What version of company info is this?
-#define NETWORK_COMPANY_INFO_VERSION 4
-// What version of master-server-protocol do we use?
-#define NETWORK_MASTER_SERVER_VERSION 1
-
-typedef uint16 PacketSize;
-
-typedef struct Packet {
-	struct Packet *next;
-	PacketSize size;
-	PacketSize pos;
-	byte buffer[SEND_MTU];
-} Packet;
-
-typedef struct CommandPacket {
-	struct CommandPacket *next;
-	PlayerID player; /// player that is executing the command
-	uint32 cmd;    /// command being executed
-	uint32 p1;     /// parameter p1
-	uint32 p2;     /// parameter p2
-	TileIndex tile; /// tile command being executed on
-	char text[80];
-	uint32 frame;  /// the frame in which this packet is executed
-	byte callback; /// any callback function executed upon successful completion of the command
-} CommandPacket;
-
-typedef enum {
-	STATUS_INACTIVE,
-	STATUS_AUTH, // This means that the client is authorized
-	STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map
-	STATUS_MAP,
-	STATUS_DONE_MAP,
-	STATUS_PRE_ACTIVE,
-	STATUS_ACTIVE,
-} ClientStatus;
-
-typedef enum {
-	MAP_PACKET_START,
-	MAP_PACKET_NORMAL,
-	MAP_PACKET_END,
-} MapPacket;
-
-typedef enum {
-	NETWORK_RECV_STATUS_OKAY,
-	NETWORK_RECV_STATUS_DESYNC,
-	NETWORK_RECV_STATUS_SAVEGAME,
-	NETWORK_RECV_STATUS_CONN_LOST,
-	NETWORK_RECV_STATUS_MALFORMED_PACKET,
-	NETWORK_RECV_STATUS_SERVER_ERROR, // The server told us we made an error
-	NETWORK_RECV_STATUS_SERVER_FULL,
-	NETWORK_RECV_STATUS_SERVER_BANNED,
-	NETWORK_RECV_STATUS_CLOSE_QUERY, // Done quering the server
-} NetworkRecvStatus;
-
-typedef enum {
-	NETWORK_ERROR_GENERAL, // Try to use thisone like never
-
-	// Signals from clients
-	NETWORK_ERROR_DESYNC,
-	NETWORK_ERROR_SAVEGAME_FAILED,
-	NETWORK_ERROR_CONNECTION_LOST,
-	NETWORK_ERROR_ILLEGAL_PACKET,
-
-	// Signals from servers
-	NETWORK_ERROR_NOT_AUTHORIZED,
-	NETWORK_ERROR_NOT_EXPECTED,
-	NETWORK_ERROR_WRONG_REVISION,
-	NETWORK_ERROR_NAME_IN_USE,
-	NETWORK_ERROR_WRONG_PASSWORD,
-	NETWORK_ERROR_PLAYER_MISMATCH, // Happens in CLIENT_COMMAND
-	NETWORK_ERROR_KICKED,
-	NETWORK_ERROR_CHEATER,
-	NETWORK_ERROR_FULL,
-} NetworkErrorCode;
-
-// Actions that can be used for NetworkTextMessage
-typedef enum {
-	NETWORK_ACTION_JOIN,
-	NETWORK_ACTION_LEAVE,
-	NETWORK_ACTION_SERVER_MESSAGE,
-	NETWORK_ACTION_CHAT,
-	NETWORK_ACTION_CHAT_COMPANY,
-	NETWORK_ACTION_CHAT_CLIENT,
-	NETWORK_ACTION_GIVE_MONEY,
-	NETWORK_ACTION_NAME_CHANGE,
-} NetworkAction;
-
-typedef enum {
-	NETWORK_GAME_PASSWORD,
-	NETWORK_COMPANY_PASSWORD,
-} NetworkPasswordType;
-
-// To keep the clients all together
-typedef struct NetworkClientState {
-	SOCKET socket;
-	uint16 index;
-	uint32 last_frame;
-	uint32 last_frame_server;
-	byte lag_test; // This byte is used for lag-testing the client
-
-	ClientStatus status;
-	bool writable; // is client ready to write to?
-	bool has_quit;
-
-	Packet *packet_queue; // Packets that are awaiting delivery
-	Packet *packet_recv; // Partially received packet
-
-	CommandPacket *command_queue; // The command-queue awaiting delivery
-} NetworkClientState;
-
-// What packet types are there
-// WARNING: The first 3 packets can NEVER change order again
-//   it protects old clients from joining newer servers (because SERVER_ERROR
-//   is the respond to a wrong revision)
-typedef enum {
-	PACKET_SERVER_FULL,
-	PACKET_SERVER_BANNED,
-	PACKET_CLIENT_JOIN,
-	PACKET_SERVER_ERROR,
-	PACKET_CLIENT_COMPANY_INFO,
-	PACKET_SERVER_COMPANY_INFO,
-	PACKET_SERVER_CLIENT_INFO,
-	PACKET_SERVER_NEED_PASSWORD,
-	PACKET_CLIENT_PASSWORD,
-	PACKET_SERVER_WELCOME,
-	PACKET_CLIENT_GETMAP,
-	PACKET_SERVER_WAIT,
-	PACKET_SERVER_MAP,
-	PACKET_CLIENT_MAP_OK,
-	PACKET_SERVER_JOIN,
-	PACKET_SERVER_FRAME,
-	PACKET_SERVER_SYNC,
-	PACKET_CLIENT_ACK,
-	PACKET_CLIENT_COMMAND,
-	PACKET_SERVER_COMMAND,
-	PACKET_CLIENT_CHAT,
-	PACKET_SERVER_CHAT,
-	PACKET_CLIENT_SET_PASSWORD,
-	PACKET_CLIENT_SET_NAME,
-	PACKET_CLIENT_QUIT,
-	PACKET_CLIENT_ERROR,
-	PACKET_SERVER_QUIT,
-	PACKET_SERVER_ERROR_QUIT,
-	PACKET_SERVER_SHUTDOWN,
-	PACKET_SERVER_NEWGAME,
-	PACKET_SERVER_RCON,
-	PACKET_CLIENT_RCON,
-	PACKET_END // Should ALWAYS be on the end of this list!! (period)
-} PacketType;
-
-typedef enum {
-	DESTTYPE_BROADCAST, ///< Send message/notice to all players (All)
-	DESTTYPE_TEAM,    ///< Send message/notice to everyone playing the same company (Team)
-	DESTTYPE_CLIENT,    ///< Send message/notice to only a certain player (Private)
-} DestType;
-
-CommandPacket *_local_command_queue;
-
-SOCKET _udp_client_socket; // udp client socket
-SOCKET _udp_server_socket; // udp server socket
-SOCKET _udp_master_socket; // udp master socket
-
-// Here we keep track of the clients
-//  (and the client uses [0] for his own communication)
-NetworkClientState _clients[MAX_CLIENTS];
-#define DEREF_CLIENT(i) (&_clients[i])
-// This returns the NetworkClientInfo from a NetworkClientState
-#define DEREF_CLIENT_INFO(cs) (&_network_client_info[cs - _clients])
-
-// Macros to make life a bit more easier
-#define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p)
-#define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(void)
-#define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
-#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkClientState *cs, Packet *p)
-#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkClientState *cs)
-#define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command
-
-#define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command
-#define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command
-
-#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->socket != INVALID_SOCKET; cs++)
-#define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX)
-
-Packet *NetworkSend_Init(PacketType type);
-void NetworkSend_uint8(Packet *packet, uint8 data);
-void NetworkSend_uint16(Packet *packet, uint16 data);
-void NetworkSend_uint32(Packet *packet, uint32 data);
-void NetworkSend_uint64(Packet *packet, uint64 data);
-void NetworkSend_string(Packet *packet, const char* data);
-void NetworkSend_Packet(Packet *packet, NetworkClientState *cs);
-
-uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet);
-uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet);
-uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet);
-uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet);
-void NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size);
-Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status);
-
-bool NetworkSend_Packets(NetworkClientState *cs);
-void NetworkExecuteCommand(CommandPacket *cp);
-void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp);
-
-// from network.c
-void NetworkCloseClient(NetworkClientState *cs);
-void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...);
-void NetworkGetClientName(char *clientname, size_t size, const NetworkClientState *cs);
-uint NetworkCalculateLag(const NetworkClientState *cs);
-byte NetworkGetCurrentLanguageIndex(void);
-NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index);
-NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip);
-NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index);
-unsigned long NetworkResolveHost(const char *hostname);
-char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last);
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_DATA_H */
--- a/network_gamelist.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "debug.h"
-#include "network_data.h"
-#include "newgrf_config.h"
-
-// This file handles the GameList
-// Also, it handles the request to a server for data about the server
-
-/** Add a new item to the linked gamelist. If the IP and Port match
- * return the existing item instead of adding it again
- * @param ip the IP-address (inet_addr) of the to-be added item
- * @param port the port the server is running on
- * @return a point to the newly added or already existing item */
-NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port)
-{
-	NetworkGameList *item, *prev_item;
-
-	prev_item = NULL;
-	for (item = _network_game_list; item != NULL; item = item->next) {
-		if (item->ip == ip && item->port == port) return item;
-		prev_item = item;
-	}
-
-	item = malloc(sizeof(*item));
-	memset(item, 0, sizeof(*item));
-	item->next = NULL;
-	item->ip = ip;
-	item->port = port;
-
-	if (prev_item == NULL) {
-		_network_game_list = item;
-	} else {
-		prev_item->next = item;
-	}
-	DEBUG(net, 4, "[gamelist] added server to list");
-
-	UpdateNetworkGameWindow(false);
-
-	return item;
-}
-
-/** Remove an item from the gamelist linked list
- * @param remove pointer to the item to be removed */
-void NetworkGameListRemoveItem(NetworkGameList *remove)
-{
-	NetworkGameList *item, *prev_item;
-
-	prev_item = NULL;
-	for (item = _network_game_list; item != NULL; item = item->next) {
-		if (remove == item) {
-			if (prev_item == NULL) {
-				_network_game_list = remove->next;
-			} else {
-				prev_item->next = remove->next;
-			}
-
-			/* Remove GRFConfig information */
-			ClearGRFConfigList(&remove->info.grfconfig);
-			free(remove);
-			remove = NULL;
-
-			DEBUG(net, 4, "[gamelist] removed server from list");
-			UpdateNetworkGameWindow(false);
-			return;
-		}
-		prev_item = item;
-	}
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_gamelist.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_GAMELIST_H
-#define NETWORK_GAMELIST_H
-
-void NetworkGameListClear(void);
-NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port);
-void NetworkGameListRemoveItem(NetworkGameList *remove);
-void NetworkGameListAddQueriedItem(const NetworkGameInfo *info, bool server_online);
-
-#endif /* NETWORK_GAMELIST_H */
--- a/network_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1706 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-#include "stdafx.h"
-#include "openttd.h"
-#include "string.h"
-#include "strings.h"
-#include "table/sprites.h"
-#include "network.h"
-#include "date.h"
-
-#include "fios.h"
-#include "table/strings.h"
-#include "functions.h"
-#include "network_data.h"
-#include "network_client.h"
-#include "network_gui.h"
-#include "network_gamelist.h"
-#include "window.h"
-#include "gui.h"
-#include "gfx.h"
-#include "command.h"
-#include "variables.h"
-#include "network_server.h"
-#include "network_udp.h"
-#include "settings.h"
-#include "string.h"
-#include "town.h"
-#include "newgrf.h"
-
-#define BGC 5
-#define BTC 15
-
-typedef struct network_d {
-	PlayerID company;        // select company in network lobby
-	byte field;              // select text-field in start-server and game-listing
-	NetworkGameList *server; // selected server in lobby and game-listing
-	FiosItem *map;           // selected map in start-server
-} network_d;
-assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
-
-typedef struct network_ql_d {
-	network_d n;                 // see above; general stuff
-	querystr_d q;                // text-input in start-server and game-listing
-	NetworkGameList **sort_list; // list of games (sorted)
-	list_d l;                    // accompanying list-administration
-} network_ql_d;
-assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_ql_d));
-
-/* Global to remember sorting after window has been closed */
-static Listing _ng_sorting;
-
-static char _edit_str_buf[150];
-static bool _chat_tab_completion_active;
-
-static void ShowNetworkStartServerWindow(void);
-static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
-extern void SwitchMode(int new_mode);
-
-static const StringID _connection_types_dropdown[] = {
-	STR_NETWORK_LAN_INTERNET,
-	STR_NETWORK_INTERNET_ADVERTISE,
-	INVALID_STRING_ID
-};
-
-static const StringID _lan_internet_types_dropdown[] = {
-	STR_NETWORK_LAN,
-	STR_NETWORK_INTERNET,
-	INVALID_STRING_ID
-};
-
-static const StringID _players_dropdown[] = {
-	STR_NETWORK_0_PLAYERS,
-	STR_NETWORK_1_PLAYERS,
-	STR_NETWORK_2_PLAYERS,
-	STR_NETWORK_3_PLAYERS,
-	STR_NETWORK_4_PLAYERS,
-	STR_NETWORK_5_PLAYERS,
-	STR_NETWORK_6_PLAYERS,
-	STR_NETWORK_7_PLAYERS,
-	STR_NETWORK_8_PLAYERS,
-	STR_NETWORK_9_PLAYERS,
-	STR_NETWORK_10_PLAYERS,
-	INVALID_STRING_ID
-};
-
-static const StringID _language_dropdown[] = {
-	STR_NETWORK_LANG_ANY,
-	STR_NETWORK_LANG_ENGLISH,
-	STR_NETWORK_LANG_GERMAN,
-	STR_NETWORK_LANG_FRENCH,
-	INVALID_STRING_ID
-};
-
-enum {
-	NET_PRC__OFFSET_TOP_WIDGET          = 54,
-	NET_PRC__OFFSET_TOP_WIDGET_COMPANY  = 52,
-	NET_PRC__SIZE_OF_ROW                = 14,
-};
-
-/** Update the network new window because a new server is
- * found on the network.
- * @param unselect unselect the currently selected item */
-void UpdateNetworkGameWindow(bool unselect)
-{
-	SendWindowMessage(WC_NETWORK_WINDOW, 0, unselect, 0, 0);
-}
-
-static bool _internal_sort_order; // Used for Qsort order-flipping
-typedef int CDECL NGameNameSortFunction(const void*, const void*);
-
-/** Qsort function to sort by name. */
-static int CDECL NGameNameSorter(const void *a, const void *b)
-{
-	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
-	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
-	int r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
-
-	return _internal_sort_order ? -r : r;
-}
-
-/** Qsort function to sort by the amount of clients online on a
- * server. If the two servers have the same amount, the one with the
- * higher maximum is preferred. */
-static int CDECL NGameClientSorter(const void *a, const void *b)
-{
-	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
-	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
-	/* Reverse as per default we are interested in most-clients first */
-	int r = cmp1->info.clients_on - cmp2->info.clients_on;
-
-	if (r == 0) r = cmp1->info.clients_max - cmp2->info.clients_max;
-	if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
-
-	return _internal_sort_order ? -r : r;
-}
-
-/** Qsort function to sort by joinability. If both servers are the
- * same, prefer the non-passworded server first. */
-static int CDECL NGameAllowedSorter(const void *a, const void *b)
-{
-	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
-	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
-	/* Reverse default as we are interested in compatible clients first */
-	int r = cmp2->info.compatible - cmp1->info.compatible;
-
-	if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
-	if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
-
-	return _internal_sort_order ? -r : r;
-}
-
-/** (Re)build the network game list as its amount has changed because
- * an item has been added or deleted for example
- * @param ngl list_d struct that contains all necessary information for sorting */
-static void BuildNetworkGameList(network_ql_d *nqld)
-{
-	NetworkGameList *ngl_temp;
-	uint n = 0;
-
-	if (!(nqld->l.flags & VL_REBUILD)) return;
-
-	/* Count the number of games in the list */
-	for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
-	if (n == 0) return;
-
-	/* Create temporary array of games to use for listing */
-	free(nqld->sort_list);
-	nqld->sort_list = malloc(n * sizeof(nqld->sort_list[0]));
-	if (nqld->sort_list == NULL) error("Could not allocate memory for the network-game-sorting-list");
-	nqld->l.list_length = n;
-
-	for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
-		nqld->sort_list[n++] = ngl_temp;
-	}
-
-	/* Force resort */
-	nqld->l.flags &= ~VL_REBUILD;
-	nqld->l.flags |= VL_RESORT;
-}
-
-static void SortNetworkGameList(network_ql_d *nqld)
-{
-	static NGameNameSortFunction * const ngame_sorter[] = {
-		&NGameNameSorter,
-		&NGameClientSorter,
-		&NGameAllowedSorter
-	};
-
-	NetworkGameList *item;
-	uint i;
-
-	if (!(nqld->l.flags & VL_RESORT)) return;
-	if (nqld->l.list_length == 0) return;
-
-	_internal_sort_order = !!(nqld->l.flags & VL_DESC);
-	qsort(nqld->sort_list, nqld->l.list_length, sizeof(nqld->sort_list[0]), ngame_sorter[nqld->l.sort_type]);
-
-	/* After sorting ngl->sort_list contains the sorted items. Put these back
-	 * into the original list. Basically nothing has changed, we are only
-	 * shuffling the ->next pointers */
-	_network_game_list = nqld->sort_list[0];
-	for (item = _network_game_list, i = 1; i != nqld->l.list_length; i++) {
-		item->next = nqld->sort_list[i];
-		item = item->next;
-	}
-	item->next = NULL;
-
-	nqld->l.flags &= ~VL_RESORT;
-}
-
-/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
-static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
-{
-	network_d *nd = &WP(w, network_ql_d).n;
-	list_d *ld = &WP(w, network_ql_d).l;
-
-	switch (e->event) {
-	case WE_CREATE: /* Focus input box */
-		nd->field = 3;
-		nd->server = NULL;
-
-		WP(w, network_ql_d).sort_list = NULL;
-		ld->flags = VL_REBUILD | (_ng_sorting.order << (VL_DESC - 1));
-		ld->sort_type = _ng_sorting.criteria;
-		break;
-
-	case WE_PAINT: {
-		const NetworkGameList *sel = nd->server;
-		const char *arrow = (ld->flags & VL_DESC) ? DOWNARROW : UPARROW;
-
-		if (ld->flags & VL_REBUILD) {
-			BuildNetworkGameList(&WP(w, network_ql_d));
-			SetVScrollCount(w, ld->list_length);
-		}
-		if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
-
-		SetWindowWidgetDisabledState(w, 17, sel == NULL);
-		/* Join Button disabling conditions */
-		SetWindowWidgetDisabledState(w, 16, sel == NULL || // no Selected Server
-				!sel->online || // Server offline
-				sel->info.clients_on >= sel->info.clients_max || // Server full
-				!sel->info.compatible); // Revision mismatch
-
-		SetWindowWidgetHiddenState(w, 18, sel == NULL ||
-				!sel->online ||
-				sel->info.grfconfig == NULL);
-
-		SetDParam(0, 0x00);
-		SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
-		DrawWindowWidgets(w);
-
-		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
-
-		DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
-		DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
-
-		/* Sort based on widgets: name, clients, compatibility */
-		switch (ld->sort_type) {
-			case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, 0x10); break;
-			case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, 0x10); break;
-			case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, 0x10); break;
-		}
-
-		{ // draw list of games
-			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
-			int32 n = 0;
-			int32 pos = w->vscroll.pos;
-			uint max_name_width = w->widget[6].right - w->widget[6].left - 5;
-			const NetworkGameList *cur_item = _network_game_list;
-
-			while (pos > 0 && cur_item != NULL) {
-				pos--;
-				cur_item = cur_item->next;
-			}
-
-			while (cur_item != NULL) {
-				// show highlighted item with a different colour
-				if (cur_item == sel) GfxFillRect(w->widget[6].left + 1, y - 2, w->widget[8].right - 1, y + 9, 10);
-
-				SetDParamStr(0, cur_item->info.server_name);
-				DrawStringTruncated(w->widget[6].left + 5, y, STR_02BD, 16, max_name_width);
-
-				SetDParam(0, cur_item->info.clients_on);
-				SetDParam(1, cur_item->info.clients_max);
-				SetDParam(2, cur_item->info.companies_on);
-				SetDParam(3, cur_item->info.companies_max);
-				DrawStringCentered(210, y, STR_NETWORK_GENERAL_ONLINE, 2);
-
-				// only draw icons if the server is online
-				if (cur_item->online) {
-					// draw a lock if the server is password protected.
-					if (cur_item->info.use_password) DrawSprite(SPR_LOCK, w->widget[8].left + 5, y - 1);
-
-					// draw red or green icon, depending on compatibility with server.
-					DrawSprite(SPR_BLOT | (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[8].left + 15, y);
-
-					// draw flag according to server language
-					DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, w->widget[8].left + 25, y);
-				}
-
-				cur_item = cur_item->next;
-				y += NET_PRC__SIZE_OF_ROW;
-				if (++n == w->vscroll.cap) break; // max number of games in the window
-			}
-		}
-
-		/* Draw the right menu */
-		GfxFillRect(311, 43, 539, 92, 157);
-		if (sel == NULL) {
-			DrawStringCentered(425, 58, STR_NETWORK_GAME_INFO, 0);
-		} else if (!sel->online) {
-			SetDParamStr(0, sel->info.server_name);
-			DrawStringCentered(425, 68, STR_ORANGE, 0); // game name
-
-			DrawStringCentered(425, 132, STR_NETWORK_SERVER_OFFLINE, 0); // server offline
-		} else { // show game info
-			uint16 y = 100;
-			const uint16 x = w->widget[15].left + 5;
-
-			DrawStringCentered(425, 48, STR_NETWORK_GAME_INFO, 0);
-
-
-			SetDParamStr(0, sel->info.server_name);
-			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 62, STR_ORANGE, 16); // game name
-
-			SetDParamStr(0, sel->info.map_name);
-			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 74, STR_02BD, 16); // map name
-
-			SetDParam(0, sel->info.clients_on);
-			SetDParam(1, sel->info.clients_max);
-			SetDParam(2, sel->info.companies_on);
-			SetDParam(3, sel->info.companies_max);
-			DrawString(x, y, STR_NETWORK_CLIENTS, 2);
-			y += 10;
-
-			SetDParam(0, _language_dropdown[sel->info.server_lang]);
-			DrawString(x, y, STR_NETWORK_LANGUAGE, 2); // server language
-			y += 10;
-
-			SetDParam(0, STR_TEMPERATE_LANDSCAPE + sel->info.map_set);
-			DrawString(x, y, STR_NETWORK_TILESET, 2); // tileset
-			y += 10;
-
-			SetDParam(0, sel->info.map_width);
-			SetDParam(1, sel->info.map_height);
-			DrawString(x, y, STR_NETWORK_MAP_SIZE, 2); // map size
-			y += 10;
-
-			SetDParamStr(0, sel->info.server_revision);
-			DrawString(x, y, STR_NETWORK_SERVER_VERSION, 2); // server version
-			y += 10;
-
-			SetDParamStr(0, sel->info.hostname);
-			SetDParam(1, sel->port);
-			DrawString(x, y, STR_NETWORK_SERVER_ADDRESS, 2); // server address
-			y += 10;
-
-			SetDParam(0, sel->info.start_date);
-			DrawString(x, y, STR_NETWORK_START_DATE, 2); // start date
-			y += 10;
-
-			SetDParam(0, sel->info.game_date);
-			DrawString(x, y, STR_NETWORK_CURRENT_DATE, 2); // current date
-			y += 10;
-
-			y += 2;
-
-			if (!sel->info.compatible) {
-				DrawStringCentered(425, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, 0); // server mismatch
-			} else if (sel->info.clients_on == sel->info.clients_max) {
-				// Show: server full, when clients_on == clients_max
-				DrawStringCentered(425, y, STR_NETWORK_SERVER_FULL, 0); // server full
-			} else if (sel->info.use_password) {
-				DrawStringCentered(425, y, STR_NETWORK_PASSWORD, 0); // password warning
-			}
-
-			y += 10;
-		}
-	}	break;
-
-	case WE_CLICK:
-		nd->field = e->we.click.widget;
-		switch (e->we.click.widget) {
-		case 0: case 14: /* Close 'X' | Cancel button */
-			DeleteWindowById(WC_NETWORK_WINDOW, 0);
-			break;
-		case 4: case 5:
-			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
-			break;
-		case 6: /* Sort by name */
-		case 7: /* Sort by connected clients */
-		case 8: /* Connectivity (green dot) */
-			if (ld->sort_type == e->we.click.widget - 6) ld->flags ^= VL_DESC;
-			ld->flags |= VL_RESORT;
-			ld->sort_type = e->we.click.widget - 6;
-
-			_ng_sorting.order = !!(ld->flags & VL_DESC);
-			_ng_sorting.criteria = ld->sort_type;
-			SetWindowDirty(w);
-			break;
-		case 9: { /* Matrix to show networkgames */
-			NetworkGameList *cur_item;
-			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
-
-			if (id_v >= w->vscroll.cap) return; // click out of bounds
-			id_v += w->vscroll.pos;
-
-			cur_item = _network_game_list;
-			for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
-
-			nd->server = cur_item;
-			SetWindowDirty(w);
-		} break;
-		case 11: /* Find server automatically */
-			switch (_network_lan_internet) {
-				case 0: NetworkUDPSearchGame(); break;
-				case 1: NetworkUDPQueryMasterServer(); break;
-			}
-			break;
-		case 12: { // Add a server
-				ShowQueryString(
-				BindCString(_network_default_ip),
-				STR_NETWORK_ENTER_IP,
-				31 | 0x1000,  // maximum number of characters OR
-				250, // characters up to this width pixels, whichever is satisfied first
-				w, CS_ALPHANUMERAL);
-		} break;
-		case 13: /* Start server */
-			ShowNetworkStartServerWindow();
-			break;
-		case 16: /* Join Game */
-			if (nd->server != NULL) {
-				snprintf(_network_last_host, sizeof(_network_last_host), "%s", inet_ntoa(*(struct in_addr *)&nd->server->ip));
-				_network_last_port = nd->server->port;
-				ShowNetworkLobbyWindow(nd->server);
-			}
-			break;
-		case 17: // Refresh
-			if (nd->server != NULL)
-				NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
-			break;
-		case 18: // NewGRF Settings
-			if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
-			break;
-
-	}	break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		switch (e->we.dropdown.button) {
-			case 5:
-				_network_lan_internet = e->we.dropdown.index;
-				break;
-		}
-
-		SetWindowDirty(w);
-		break;
-
-	case WE_MOUSELOOP:
-		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
-		break;
-
-	case WE_MESSAGE:
-		if (e->we.message.msg != 0) nd->server = NULL;
-		ld->flags |= VL_REBUILD;
-		SetWindowDirty(w);
-		break;
-
-	case WE_KEYPRESS:
-		if (nd->field != 3) {
-			if (nd->server != NULL) {
-				if (e->we.keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
-					NetworkGameListRemoveItem(nd->server);
-					NetworkRebuildHostList();
-					nd->server = NULL;
-				}
-			}
-			break;
-		}
-
-		if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
-
-		// The name is only allowed when it starts with a letter!
-		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
-			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
-		} else {
-			ttd_strlcpy(_network_player_name, "Player", lengthof(_network_player_name));
-		}
-
-		break;
-
-	case WE_ON_EDIT_TEXT:
-		NetworkAddServer(e->we.edittext.str);
-		NetworkRebuildHostList();
-		break;
-
-	case WE_DESTROY: /* Nicely clean up the sort-list */
-		free(WP(w, network_ql_d).sort_list);
-		break;
-	}
-}
-
-static const Widget _network_game_window_widgets[] = {
-{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
-{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   549,     0,    13, STR_NETWORK_MULTIPLAYER,     STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   549,    14,   263, 0x0,                         STR_NULL},
-
-/* LEFT SIDE */
-{      WWT_PANEL,   RESIZE_NONE,   BGC,   310,   461,    22,    33, 0x0,                         STR_NETWORK_ENTER_NAME_TIP},
-
-{      WWT_INSET,   RESIZE_NONE,   BGC,    90,   181,    22,    33, STR_NETWORK_COMBO1,          STR_NETWORK_CONNECTION_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   170,   180,    23,    32, STR_0225,                    STR_NETWORK_CONNECTION_TIP},
-
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   170,    42,    53, STR_NETWORK_GAME_NAME,       STR_NETWORK_GAME_NAME_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   171,   250,    42,    53, STR_NETWORK_CLIENTS_CAPTION, STR_NETWORK_CLIENTS_CAPTION_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   251,   290,    42,    53, STR_EMPTY,                   STR_NETWORK_INFO_ICONS_TIP},
-
-{     WWT_MATRIX,   RESIZE_NONE,   BGC,    10,   290,    54,   236, (13 << 8) + 1,               STR_NETWORK_CLICK_GAME_TO_SELECT},
-{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   291,   302,    42,   236, STR_NULL,                    STR_0190_SCROLL_BAR_SCROLLS_LIST},
-
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    30,   130,   246,   257, STR_NETWORK_FIND_SERVER,     STR_NETWORK_FIND_SERVER_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   180,   280,   246,   257, STR_NETWORK_ADD_SERVER,      STR_NETWORK_ADD_SERVER_TIP},
-
-/* RIGHT SIDE */
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   315,   415,   246,   257, STR_NETWORK_START_SERVER,    STR_NETWORK_START_SERVER_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   246,   257, STR_012E_CANCEL,             STR_NULL},
-
-{      WWT_PANEL,   RESIZE_NONE,   BGC,   310,   540,    42,   236, 0x0,                         STR_NULL},
-
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   315,   415,   215,   226, STR_NETWORK_JOIN_GAME,       STR_NULL},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   215,   226, STR_NETWORK_REFRESH,         STR_NETWORK_REFRESH_TIP},
-
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   430,   535,   197,   208, STR_NEWGRF_SETTINGS_BUTTON,  STR_NULL},
-
-{   WIDGETS_END},
-};
-
-static const WindowDesc _network_game_window_desc = {
-	WDP_CENTER, WDP_CENTER, 550, 264,
-	WC_NETWORK_WINDOW,0,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
-	_network_game_window_widgets,
-	NetworkGameWindowWndProc,
-};
-
-void ShowNetworkGameWindow(void)
-{
-	static bool first = true;
-	Window *w;
-	DeleteWindowById(WC_NETWORK_WINDOW, 0);
-
-	/* Only show once */
-	if (first) {
-		char* const *srv;
-
-		first = false;
-		// add all servers from the config file to our list
-		for (srv = &_network_host_list[0]; srv != endof(_network_host_list) && *srv != NULL; srv++) {
-			NetworkAddServer(*srv);
-		}
-
-		_ng_sorting.criteria = 2; // sort default by collectivity (green-dots on top)
-		_ng_sorting.order = 0;    // sort ascending by default
-	}
-
-	w = AllocateWindowDesc(&_network_game_window_desc);
-	if (w != NULL) {
-		querystr_d *querystr = &WP(w, network_ql_d).q;
-
-		ttd_strlcpy(_edit_str_buf, _network_player_name, lengthof(_edit_str_buf));
-		w->vscroll.cap = 13;
-
-		querystr->afilter = CS_ALPHANUMERAL;
-		InitializeTextBuffer(&querystr->text, _edit_str_buf, lengthof(_edit_str_buf), 120);
-
-		UpdateNetworkGameWindow(true);
-	}
-}
-
-enum {
-	NSSWND_START = 64,
-	NSSWND_ROWSIZE = 12
-};
-
-/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
-static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
-{
-	network_d *nd = &WP(w, network_ql_d).n;
-
-	switch (e->event) {
-	case WE_CREATE: /* focus input box */
-		nd->field = 3;
-		_network_game_info.use_password = (_network_server_password[0] != '\0');
-		break;
-
-	case WE_PAINT: {
-		int y = NSSWND_START, pos;
-		const FiosItem *item;
-
-		SetDParam( 7, _connection_types_dropdown[_network_advertise]);
-		SetDParam( 9, _players_dropdown[_network_game_info.clients_max]);
-		SetDParam(11, _players_dropdown[_network_game_info.companies_max]);
-		SetDParam(13, _players_dropdown[_network_game_info.spectators_max]);
-		SetDParam(15, _language_dropdown[_network_game_info.server_lang]);
-		DrawWindowWidgets(w);
-
-		GfxFillRect(11, 63, 258, 215, 0xD7);
-		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
-
-		DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
-
-		DrawString(10, 43, STR_NETWORK_SELECT_MAP, 2);
-
-		DrawString(280,  63, STR_NETWORK_CONNECTION, 2);
-		DrawString(280,  95, STR_NETWORK_NUMBER_OF_CLIENTS, 2);
-		DrawString(280, 127, STR_NETWORK_NUMBER_OF_COMPANIES, 2);
-		DrawString(280, 159, STR_NETWORK_NUMBER_OF_SPECTATORS, 2);
-		DrawString(280, 191, STR_NETWORK_LANGUAGE_SPOKEN, 2);
-
-		if (_network_game_info.use_password) DoDrawString("*", 408, 23, 3);
-
-		// draw list of maps
-		pos = w->vscroll.pos;
-		while (pos < _fios_num + 1) {
-			item = _fios_list + pos - 1;
-			if (item == nd->map || (pos == 0 && nd->map == NULL))
-				GfxFillRect(11, y - 1, 258, y + 10, 155); // show highlighted item with a different colour
-
-			if (pos == 0) {
-				DrawString(14, y, STR_4010_GENERATE_RANDOM_NEW_GAME, 9);
-			} else {
-				DoDrawString(item->title, 14, y, _fios_colors[item->type] );
-			}
-			pos++;
-			y += NSSWND_ROWSIZE;
-
-			if (y >= w->vscroll.cap * NSSWND_ROWSIZE + NSSWND_START) break;
-		}
-	}	break;
-
-	case WE_CLICK:
-		nd->field = e->we.click.widget;
-		switch (e->we.click.widget) {
-		case 0: /* Close 'X' */
-		case 19: /* Cancel button */
-			ShowNetworkGameWindow();
-			break;
-
-		case 4: /* Set password button */
-			ShowQueryString(BindCString(_network_server_password), STR_NETWORK_SET_PASSWORD, 20, 250, w, CS_ALPHANUMERAL);
-			break;
-
-		case 5: { /* Select map */
-			int y = (e->we.click.pt.y - NSSWND_START) / NSSWND_ROWSIZE;
-
-			y += w->vscroll.pos;
-			if (y >= w->vscroll.count) return;
-
-			nd->map = (y == 0) ? NULL : _fios_list + y - 1;
-			SetWindowDirty(w);
-			} break;
-		case 7: case 8: /* Connection type */
-			ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8
-			break;
-		case 9: case 10: /* Number of Players (hide 0 and 1 players) */
-			ShowDropDownMenu(w, _players_dropdown, _network_game_info.clients_max, 10, 0, 3);
-			break;
-		case 11: case 12: /* Number of Companies (hide 0, 9 and 10 companies; max is 8) */
-			ShowDropDownMenu(w, _players_dropdown, _network_game_info.companies_max, 12, 0, 1537);
-			break;
-		case 13: case 14: /* Number of Spectators */
-			ShowDropDownMenu(w, _players_dropdown, _network_game_info.spectators_max, 14, 0, 0);
-			break;
-		case 15: case 16: /* Language */
-			ShowDropDownMenu(w, _language_dropdown, _network_game_info.server_lang, 16, 0, 0);
-			break;
-		case 17: /* Start game */
-			_is_network_server = true;
-
-			if (nd->map == NULL) { // start random new game
-				ShowGenerateLandscape();
-			} else { // load a scenario
-				char *name = FiosBrowseTo(nd->map);
-				if (name != NULL) {
-					SetFiosType(nd->map->type);
-					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
-					ttd_strlcpy(_file_to_saveload.title, nd->map->title, sizeof(_file_to_saveload.title));
-
-					DeleteWindow(w);
-					SwitchMode(SM_START_SCENARIO);
-				}
-			}
-			break;
-		case 18: /* Load game */
-			_is_network_server = true;
-			/* XXX - WC_NETWORK_WINDOW should stay, but if it stays, it gets
-			 * copied all the elements of 'load game' and upon closing that, it segfaults */
-			DeleteWindowById(WC_NETWORK_WINDOW, 0);
-			ShowSaveLoadDialog(SLD_LOAD_GAME);
-			break;
-		}
-		break;
-
-	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
-		switch (e->we.dropdown.button) {
-			case  8: _network_advertise                = (e->we.dropdown.index != 0); break;
-			case 10: _network_game_info.clients_max    = e->we.dropdown.index;        break;
-			case 12: _network_game_info.companies_max  = e->we.dropdown.index;        break;
-			case 14: _network_game_info.spectators_max = e->we.dropdown.index;        break;
-			case 16: _network_game_info.server_lang    = e->we.dropdown.index;        break;
-		}
-
-		SetWindowDirty(w);
-		break;
-
-	case WE_MOUSELOOP:
-		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
-		break;
-
-	case WE_KEYPRESS:
-		if (nd->field == 3) {
-			if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
-
-			ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
-			UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
-		}
-		break;
-
-	case WE_ON_EDIT_TEXT: {
-		ttd_strlcpy(_network_server_password, e->we.edittext.str, lengthof(_network_server_password));
-		_network_game_info.use_password = (_network_server_password[0] != '\0');
-		SetWindowDirty(w);
-	} break;
-	}
-}
-
-static const Widget _network_start_server_window_widgets[] = {
-{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                      STR_018B_CLOSE_WINDOW },
-{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   419,     0,    13, STR_NETWORK_START_GAME_WINDOW, STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   419,    14,   243, 0x0,                           STR_NULL},
-
-{      WWT_PANEL,   RESIZE_NONE,   BGC,   100,   272,    22,    33, 0x0,                           STR_NETWORK_NEW_GAME_NAME_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   285,   405,    22,    33, STR_NETWORK_SET_PASSWORD,      STR_NETWORK_PASSWORD_TIP},
-
-{      WWT_INSET,   RESIZE_NONE,   BGC,    10,   271,    62,   216, 0x0,                           STR_NETWORK_SELECT_MAP_TIP},
-{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   259,   270,    63,   215, 0x0,                           STR_0190_SCROLL_BAR_SCROLLS_LIST},
-/* Combo boxes to control Connection Type / Max Clients / Max Companies / Max Observers / Language */
-{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,    77,    88, STR_NETWORK_COMBO1,            STR_NETWORK_CONNECTION_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,    78,    87, STR_0225,                      STR_NETWORK_CONNECTION_TIP},
-{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   109,   120, STR_NETWORK_COMBO2,            STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   110,   119, STR_0225,                      STR_NETWORK_NUMBER_OF_CLIENTS_TIP},
-{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   141,   152, STR_NETWORK_COMBO3,            STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   142,   151, STR_0225,                      STR_NETWORK_NUMBER_OF_COMPANIES_TIP},
-{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   173,   184, STR_NETWORK_COMBO4,            STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   174,   183, STR_0225,                      STR_NETWORK_NUMBER_OF_SPECTATORS_TIP},
-{      WWT_INSET,   RESIZE_NONE,   BGC,   280,   410,   205,   216, STR_NETWORK_COMBO5,            STR_NETWORK_LANGUAGE_TIP},
-{    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   399,   409,   206,   215, STR_0225,                      STR_NETWORK_LANGUAGE_TIP},
-
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    40,   140,   224,   235, STR_NETWORK_START_GAME,        STR_NETWORK_START_GAME_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   150,   250,   224,   235, STR_NETWORK_LOAD_GAME,         STR_NETWORK_LOAD_GAME_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   260,   360,   224,   235, STR_012E_CANCEL,               STR_NULL},
-{   WIDGETS_END},
-};
-
-static const WindowDesc _network_start_server_window_desc = {
-	WDP_CENTER, WDP_CENTER, 420, 244,
-	WC_NETWORK_WINDOW,0,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
-	_network_start_server_window_widgets,
-	NetworkStartServerWindowWndProc,
-};
-
-static void ShowNetworkStartServerWindow(void)
-{
-	Window *w;
-	DeleteWindowById(WC_NETWORK_WINDOW, 0);
-
-	w = AllocateWindowDesc(&_network_start_server_window_desc);
-	ttd_strlcpy(_edit_str_buf, _network_server_name, lengthof(_edit_str_buf));
-
-	_saveload_mode = SLD_NEW_GAME;
-	BuildFileList();
-	w->vscroll.cap = 12;
-	w->vscroll.count = _fios_num+1;
-
-	WP(w, network_ql_d).q.afilter = CS_ALPHANUMERAL;
-	InitializeTextBuffer(&WP(w, network_ql_d).q.text, _edit_str_buf, lengthof(_edit_str_buf), 160);
-}
-
-static byte NetworkLobbyFindCompanyIndex(byte pos)
-{
-	byte i;
-
-	/* Scroll through all _network_player_info and get the 'pos' item
-	    that is not empty */
-	for (i = 0; i < MAX_PLAYERS; i++) {
-		if (_network_player_info[i].company_name[0] != '\0') {
-			if (pos-- == 0) return i;
-		}
-	}
-
-	return 0;
-}
-
-/* uses network_d WP macro */
-static void NetworkLobbyWindowWndProc(Window *w, WindowEvent *e)
-{
-	network_d *nd = &WP(w, network_d);
-
-	switch (e->event) {
-	case WE_CREATE:
-		nd->company = (byte)-1;
-		break;
-
-	case WE_PAINT: {
-		const NetworkGameInfo *gi = &nd->server->info;
-		int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY, pos;
-
-		SetWindowWidgetDisabledState(w, 7, nd->company == (byte)-1);
-		SetWindowWidgetDisabledState(w, 8, gi->companies_on >= gi->companies_max);
-		/* You can not join a server as spectator when it has no companies active..
-		 * it causes some nasty crashes */
-		SetWindowWidgetDisabledState(w, 9, gi->spectators_on >= gi->spectators_max ||
-				gi->companies_on == 0);
-
-		DrawWindowWidgets(w);
-
-		SetDParamStr(0, gi->server_name);
-		DrawString(10, 22, STR_NETWORK_PREPARE_TO_JOIN, 2);
-
-		/* Draw company list */
-		pos = w->vscroll.pos;
-		while (pos < gi->companies_on) {
-			byte company = NetworkLobbyFindCompanyIndex(pos);
-			bool income = false;
-			if (nd->company == company)
-				GfxFillRect(11, y - 1, 154, y + 10, 10); // show highlighted item with a different colour
-
-			DoDrawStringTruncated(_network_player_info[company].company_name, 13, y, 16, 135 - 13);
-			if (_network_player_info[company].use_password != 0) DrawSprite(SPR_LOCK, 135, y);
-
-			/* If the company's income was positive puts a green dot else a red dot */
-			if (_network_player_info[company].income >= 0) income = true;
-			DrawSprite(SPR_BLOT | (income ? PALETTE_TO_GREEN : PALETTE_TO_RED), 145, y);
-
-			pos++;
-			y += NET_PRC__SIZE_OF_ROW;
-			if (pos >= w->vscroll.cap) break;
-		}
-
-		/* Draw info about selected company when it is selected in the left window */
-		GfxFillRect(174, 39, 403, 75, 157);
-		DrawStringCentered(290, 50, STR_NETWORK_COMPANY_INFO, 0);
-		if (nd->company != (byte)-1) {
-			const uint x = 183;
-			const uint trunc_width = w->widget[6].right - x;
-			y = 80;
-
-			SetDParam(0, nd->server->info.clients_on);
-			SetDParam(1, nd->server->info.clients_max);
-			SetDParam(2, nd->server->info.companies_on);
-			SetDParam(3, nd->server->info.companies_max);
-			DrawString(x, y, STR_NETWORK_CLIENTS, 2);
-			y += 10;
-
-			SetDParamStr(0, _network_player_info[nd->company].company_name);
-			DrawStringTruncated(x, y, STR_NETWORK_COMPANY_NAME, 2, trunc_width);
-			y += 10;
-
-			SetDParam(0, _network_player_info[nd->company].inaugurated_year);
-			DrawString(x, y, STR_NETWORK_INAUGURATION_YEAR, 2); // inauguration year
-			y += 10;
-
-			SetDParam64(0, _network_player_info[nd->company].company_value);
-			DrawString(x, y, STR_NETWORK_VALUE, 2); // company value
-			y += 10;
-
-			SetDParam64(0, _network_player_info[nd->company].money);
-			DrawString(x, y, STR_NETWORK_CURRENT_BALANCE, 2); // current balance
-			y += 10;
-
-			SetDParam64(0, _network_player_info[nd->company].income);
-			DrawString(x, y, STR_NETWORK_LAST_YEARS_INCOME, 2); // last year's income
-			y += 10;
-
-			SetDParam(0, _network_player_info[nd->company].performance);
-			DrawString(x, y, STR_NETWORK_PERFORMANCE, 2); // performance
-			y += 10;
-
-			SetDParam(0, _network_player_info[nd->company].num_vehicle[0]);
-			SetDParam(1, _network_player_info[nd->company].num_vehicle[1]);
-			SetDParam(2, _network_player_info[nd->company].num_vehicle[2]);
-			SetDParam(3, _network_player_info[nd->company].num_vehicle[3]);
-			SetDParam(4, _network_player_info[nd->company].num_vehicle[4]);
-			DrawString(x, y, STR_NETWORK_VEHICLES, 2); // vehicles
-			y += 10;
-
-			SetDParam(0, _network_player_info[nd->company].num_station[0]);
-			SetDParam(1, _network_player_info[nd->company].num_station[1]);
-			SetDParam(2, _network_player_info[nd->company].num_station[2]);
-			SetDParam(3, _network_player_info[nd->company].num_station[3]);
-			SetDParam(4, _network_player_info[nd->company].num_station[4]);
-			DrawString(x, y, STR_NETWORK_STATIONS, 2); // stations
-			y += 10;
-
-			SetDParamStr(0, _network_player_info[nd->company].players);
-			DrawStringTruncated(x, y, STR_NETWORK_PLAYERS, 2, trunc_width); // players
-		}
-	}	break;
-
-	case WE_CLICK:
-		switch (e->we.click.widget) {
-		case 0: case 11: /* Close 'X' | Cancel button */
-			ShowNetworkGameWindow();
-			break;
-		case 4: { /* Company list */
-			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET_COMPANY) / NET_PRC__SIZE_OF_ROW;
-
-			if (id_v >= w->vscroll.cap) return;
-
-			id_v += w->vscroll.pos;
-			nd->company = (id_v >= nd->server->info.companies_on) ? (byte)-1 : NetworkLobbyFindCompanyIndex(id_v);
-			SetWindowDirty(w);
-		}	break;
-		case 7: /* Join company */
-			if (nd->company != (byte)-1) {
-				_network_playas = nd->company;
-				NetworkClientConnectGame(_network_last_host, _network_last_port);
-			}
-			break;
-		case 8: /* New company */
-			_network_playas = PLAYER_NEW_COMPANY;
-			NetworkClientConnectGame(_network_last_host, _network_last_port);
-			break;
-		case 9: /* Spectate game */
-			_network_playas = PLAYER_SPECTATOR;
-			NetworkClientConnectGame(_network_last_host, _network_last_port);
-			break;
-		case 10: /* Refresh */
-			NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
-			NetworkUDPQueryServer(_network_last_host, _network_last_port);     // general data
-			break;
-		}	break;
-
-	case WE_MESSAGE:
-		SetWindowDirty(w);
-		break;
-	}
-}
-
-static const Widget _network_lobby_window_widgets[] = {
-{   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                  STR_018B_CLOSE_WINDOW },
-{    WWT_CAPTION,   RESIZE_NONE,   BGC,    11,   419,     0,    13, STR_NETWORK_GAME_LOBBY,    STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,   BGC,     0,   419,    14,   234, 0x0,                       STR_NULL},
-
-// company list
-{      WWT_PANEL,   RESIZE_NONE,   BTC,    10,   155,    38,    49, 0x0,                       STR_NULL},
-{     WWT_MATRIX,   RESIZE_NONE,   BGC,    10,   155,    50,   190, (10 << 8) + 1,             STR_NETWORK_COMPANY_LIST_TIP},
-{  WWT_SCROLLBAR,   RESIZE_NONE,   BGC,   156,   167,    38,   190, STR_NULL,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
-
-// company/player info
-{      WWT_PANEL,   RESIZE_NONE,   BGC,   173,   404,    38,   190, 0x0,                       STR_NULL},
-
-// buttons
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   151,   200,   211, STR_NETWORK_JOIN_COMPANY,  STR_NETWORK_JOIN_COMPANY_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    10,   151,   215,   226, STR_NETWORK_NEW_COMPANY,   STR_NETWORK_NEW_COMPANY_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   158,   268,   200,   211, STR_NETWORK_SPECTATE_GAME, STR_NETWORK_SPECTATE_GAME_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   158,   268,   215,   226, STR_NETWORK_REFRESH,       STR_NETWORK_REFRESH_TIP},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,   278,   388,   200,   211, STR_012E_CANCEL,           STR_NULL},
-
-{   WIDGETS_END},
-};
-
-static const WindowDesc _network_lobby_window_desc = {
-	WDP_CENTER, WDP_CENTER, 420, 235,
-	WC_NETWORK_WINDOW,0,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
-	_network_lobby_window_widgets,
-	NetworkLobbyWindowWndProc,
-};
-
-/* Show the networklobbywindow with the selected server
- * @param ngl Selected game pointer which is passed to the new window */
-static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
-{
-	Window *w;
-	DeleteWindowById(WC_NETWORK_WINDOW, 0);
-
-	NetworkQueryServer(_network_last_host, _network_last_port, false); // company info
-	NetworkUDPQueryServer(_network_last_host, _network_last_port);     // general data
-
-	w = AllocateWindowDesc(&_network_lobby_window_desc);
-	if (w != NULL) {
-		WP(w, network_ql_d).n.server = ngl;
-		strcpy(_edit_str_buf, "");
-		w->vscroll.cap = 10;
-	}
-}
-
-// The window below gives information about the connected clients
-//  and also makes able to give money to them, kick them (if server)
-//  and stuff like that.
-
-extern void DrawPlayerIcon(PlayerID pid, int x, int y);
-
-// Every action must be of this form
-typedef void ClientList_Action_Proc(byte client_no);
-
-// Max 10 actions per client
-#define MAX_CLIENTLIST_ACTION 10
-
-// Some standard bullshit.. defines variables ;)
-static void ClientListWndProc(Window *w, WindowEvent *e);
-static void ClientListPopupWndProc(Window *w, WindowEvent *e);
-static byte _selected_clientlist_item = 255;
-static byte _selected_clientlist_y = 0;
-static char _clientlist_action[MAX_CLIENTLIST_ACTION][50];
-static ClientList_Action_Proc *_clientlist_proc[MAX_CLIENTLIST_ACTION];
-
-enum {
-	CLNWND_OFFSET = 16,
-	CLNWND_ROWSIZE = 10
-};
-
-static const Widget _client_list_widgets[] = {
-{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                 STR_018B_CLOSE_WINDOW},
-{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   249,     0,    13, STR_NETWORK_CLIENT_LIST,  STR_018C_WINDOW_TITLE_DRAG_THIS},
-
-{      WWT_PANEL,   RESIZE_NONE,    14,     0,   249,    14,    14 + CLNWND_ROWSIZE + 1, 0x0, STR_NULL},
-{   WIDGETS_END},
-};
-
-static const Widget _client_list_popup_widgets[] = {
-{      WWT_PANEL,   RESIZE_NONE,    14,     0,   99,     0,     0,     0, STR_NULL},
-{   WIDGETS_END},
-};
-
-static WindowDesc _client_list_desc = {
-	WDP_AUTO, WDP_AUTO, 250, 1,
-	WC_CLIENT_LIST,0,
-	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
-	_client_list_widgets,
-	ClientListWndProc
-};
-
-// Finds the Xth client-info that is active
-static const NetworkClientInfo *NetworkFindClientInfo(byte client_no)
-{
-	const NetworkClientInfo *ci;
-
-	FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
-		if (client_no == 0) return ci;
-		client_no--;
-	}
-
-	return NULL;
-}
-
-// Here we start to define the options out of the menu
-static void ClientList_Kick(byte client_no)
-{
-	if (client_no < MAX_PLAYERS)
-		SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
-}
-
-static void ClientList_Ban(byte client_no)
-{
-	uint i;
-	uint32 ip = NetworkFindClientInfo(client_no)->client_ip;
-
-	for (i = 0; i < lengthof(_network_ban_list); i++) {
-		if (_network_ban_list[i] == NULL) {
-			_network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ip));
-			break;
-		}
-	}
-
-	if (client_no < MAX_PLAYERS)
-		SEND_COMMAND(PACKET_SERVER_ERROR)(DEREF_CLIENT(client_no), NETWORK_ERROR_KICKED);
-}
-
-static void ClientList_GiveMoney(byte client_no)
-{
-	if (NetworkFindClientInfo(client_no) != NULL)
-		ShowNetworkGiveMoneyWindow(NetworkFindClientInfo(client_no)->client_playas);
-}
-
-static void ClientList_SpeakToClient(byte client_no)
-{
-	if (NetworkFindClientInfo(client_no) != NULL)
-		ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, NetworkFindClientInfo(client_no)->client_index);
-}
-
-static void ClientList_SpeakToCompany(byte client_no)
-{
-	if (NetworkFindClientInfo(client_no) != NULL)
-		ShowNetworkChatQueryWindow(DESTTYPE_TEAM, NetworkFindClientInfo(client_no)->client_playas);
-}
-
-static void ClientList_SpeakToAll(byte client_no)
-{
-	ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
-}
-
-static void ClientList_None(byte client_no)
-{
-	// No action ;)
-}
-
-
-
-// Help, a action is clicked! What do we do?
-static void HandleClientListPopupClick(byte index, byte clientno) {
-	// A click on the Popup of the ClientList.. handle the command
-	if (index < MAX_CLIENTLIST_ACTION && _clientlist_proc[index] != NULL) {
-		_clientlist_proc[index](clientno);
-	}
-}
-
-// Finds the amount of clients and set the height correct
-static bool CheckClientListHeight(Window *w)
-{
-	int num = 0;
-	const NetworkClientInfo *ci;
-
-	// Should be replaced with a loop through all clients
-	FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
-		num++;
-	}
-
-	num *= CLNWND_ROWSIZE;
-
-	// If height is changed
-	if (w->height != CLNWND_OFFSET + num + 1) {
-		// XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1)
-		SetWindowDirty(w);
-		w->widget[2].bottom = w->widget[2].top + num + 2;
-		w->height = CLNWND_OFFSET + num + 1;
-		SetWindowDirty(w);
-		return false;
-	}
-	return true;
-}
-
-// Finds the amount of actions in the popup and set the height correct
-static uint ClientListPopupHeigth(void) {
-	int i, num = 0;
-
-	// Find the amount of actions
-	for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
-		if (_clientlist_action[i][0] == '\0') continue;
-		if (_clientlist_proc[i] == NULL) continue;
-		num++;
-	}
-
-	num *= CLNWND_ROWSIZE;
-
-	return num + 1;
-}
-
-// Show the popup (action list)
-static Window *PopupClientList(Window *w, int client_no, int x, int y)
-{
-	int i, h;
-	const NetworkClientInfo *ci;
-	DeleteWindowById(WC_TOOLBAR_MENU, 0);
-
-	// Clean the current actions
-	for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) {
-		_clientlist_action[i][0] = '\0';
-		_clientlist_proc[i] = NULL;
-	}
-
-	// Fill the actions this client has
-	// Watch is, max 50 chars long!
-
-	ci = NetworkFindClientInfo(client_no);
-	if (ci == NULL) return NULL;
-
-	i = 0;
-	if (_network_own_client_index != ci->client_index) {
-		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(_clientlist_action[i]));
-		_clientlist_proc[i++] = &ClientList_SpeakToClient;
-	}
-
-	if (IsValidPlayer(ci->client_playas) || ci->client_playas == PLAYER_SPECTATOR) {
-		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(_clientlist_action[i]));
-		_clientlist_proc[i++] = &ClientList_SpeakToCompany;
-	}
-	GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(_clientlist_action[i]));
-	_clientlist_proc[i++] = &ClientList_SpeakToAll;
-
-	if (_network_own_client_index != ci->client_index) {
-		/* We are no spectator and the player we want to give money to is no spectator */
-		if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas)) {
-			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i]));
-			_clientlist_proc[i++] = &ClientList_GiveMoney;
-		}
-	}
-
-	// A server can kick clients (but not himself)
-	if (_network_server && _network_own_client_index != ci->client_index) {
-		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(_clientlist_action[i]));
-		_clientlist_proc[i++] = &ClientList_Kick;
-
-		sprintf(_clientlist_action[i],"Ban"); // XXX GetString?
-		_clientlist_proc[i++] = &ClientList_Ban;
-	}
-
-	if (i == 0) {
-		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i]));
-		_clientlist_proc[i++] = &ClientList_None;
-	}
-
-	/* Calculate the height */
-	h = ClientListPopupHeigth();
-
-	// Allocate the popup
-	w = AllocateWindow(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets);
-	w->widget[0].bottom = w->widget[0].top + h;
-	w->widget[0].right = w->widget[0].left + 150;
-
-	w->flags4 &= ~WF_WHITE_BORDER_MASK;
-	WP(w,menu_d).item_count = 0;
-	// Save our client
-	WP(w,menu_d).main_button = client_no;
-	WP(w,menu_d).sel_index = 0;
-	// We are a popup
-	_popup_menu_active = true;
-
-	return w;
-}
-
-/** Main handle for the client popup list
- * uses menu_d WP macro */
-static void ClientListPopupWndProc(Window *w, WindowEvent *e)
-{
-	switch (e->event) {
-	case WE_PAINT: {
-		int i, y, sel;
-		byte colour;
-		DrawWindowWidgets(w);
-
-		// Draw the actions
-		sel = WP(w,menu_d).sel_index;
-		y = 1;
-		for (i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += CLNWND_ROWSIZE) {
-			if (_clientlist_action[i][0] == '\0') continue;
-			if (_clientlist_proc[i] == NULL) continue;
-
-			if (sel-- == 0) { // Selected item, highlight it
-				GfxFillRect(1, y, 150 - 2, y + CLNWND_ROWSIZE - 1, 0);
-				colour = 0xC;
-			} else {
-				colour = 0x10;
-			}
-
-			DoDrawString(_clientlist_action[i], 4, y, colour);
-		}
-	}	break;
-
-	case WE_POPUPMENU_SELECT: {
-		// We selected an action
-		int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
-
-		if (index >= 0 && e->we.popupmenu.pt.y >= w->top)
-			HandleClientListPopupClick(index, WP(w,menu_d).main_button);
-
-		DeleteWindowById(WC_TOOLBAR_MENU, 0);
-	}	break;
-
-	case WE_POPUPMENU_OVER: {
-		// Our mouse hoovers over an action? Select it!
-		int index = (e->we.popupmenu.pt.y - w->top) / CLNWND_ROWSIZE;
-
-		if (index == -1 || index == WP(w,menu_d).sel_index) return;
-
-		WP(w,menu_d).sel_index = index;
-		SetWindowDirty(w);
-	} break;
-
-	}
-}
-
-// Main handle for clientlist
-static void ClientListWndProc(Window *w, WindowEvent *e)
-{
-	switch (e->event) {
-	case WE_PAINT: {
-		NetworkClientInfo *ci;
-		int y, i = 0;
-		byte colour;
-
-		// Check if we need to reset the height
-		if (!CheckClientListHeight(w)) break;
-
-		DrawWindowWidgets(w);
-
-		y = CLNWND_OFFSET;
-
-		FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
-			if (_selected_clientlist_item == i++) { // Selected item, highlight it
-				GfxFillRect(1, y, 248, y + CLNWND_ROWSIZE - 1, 0);
-				colour = 0xC;
-			} else {
-				colour = 0x10;
-			}
-
-			if (ci->client_index == NETWORK_SERVER_INDEX) {
-				DrawString(4, y, STR_NETWORK_SERVER, colour);
-			} else {
-				DrawString(4, y, STR_NETWORK_CLIENT, colour);
-			}
-
-			// Filter out spectators
-			if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1);
-
-			DoDrawString(ci->client_name, 81, y, colour);
-
-			y += CLNWND_ROWSIZE;
-		}
-	}	break;
-
-	case WE_CLICK:
-		// Show the popup with option
-		if (_selected_clientlist_item != 255) {
-			PopupClientList(w, _selected_clientlist_item, e->we.click.pt.x + w->left, e->we.click.pt.y + w->top);
-		}
-
-		break;
-
-	case WE_MOUSEOVER:
-		// -1 means we left the current window
-		if (e->we.mouseover.pt.y == -1) {
-			_selected_clientlist_y = 0;
-			_selected_clientlist_item = 255;
-			SetWindowDirty(w);
-			break;
-		}
-		// It did not change.. no update!
-		if (e->we.mouseover.pt.y == _selected_clientlist_y) break;
-
-		// Find the new selected item (if any)
-		_selected_clientlist_y = e->we.mouseover.pt.y;
-		if (e->we.mouseover.pt.y > CLNWND_OFFSET) {
-			_selected_clientlist_item = (e->we.mouseover.pt.y - CLNWND_OFFSET) / CLNWND_ROWSIZE;
-		} else {
-			_selected_clientlist_item = 255;
-		}
-
-		// Repaint
-		SetWindowDirty(w);
-		break;
-
-	case WE_DESTROY: case WE_CREATE:
-		// When created or destroyed, data is reset
-		_selected_clientlist_item = 255;
-		_selected_clientlist_y = 0;
-		break;
-	}
-}
-
-void ShowClientList(void)
-{
-	AllocateWindowDescFront(&_client_list_desc, 0);
-}
-
-
-static NetworkPasswordType pw_type;
-
-
-void ShowNetworkNeedPassword(NetworkPasswordType npt)
-{
-	StringID caption;
-
-	pw_type = npt;
-	switch (npt) {
-		default: NOT_REACHED();
-		case NETWORK_GAME_PASSWORD:    caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break;
-		case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break;
-	}
-	ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL);
-}
-
-
-static void NetworkJoinStatusWindowWndProc(Window *w, WindowEvent *e)
-{
-	switch (e->event) {
-	case WE_PAINT: {
-		uint8 progress; // used for progress bar
-		DrawWindowWidgets(w);
-
-		DrawStringCentered(125, 35, STR_NETWORK_CONNECTING_1 + _network_join_status, 14);
-		switch (_network_join_status) {
-			case NETWORK_JOIN_STATUS_CONNECTING: case NETWORK_JOIN_STATUS_AUTHORIZING:
-			case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO:
-				progress = 10; // first two stages 10%
-				break;
-			case NETWORK_JOIN_STATUS_WAITING:
-				SetDParam(0, _network_join_waiting);
-				DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_WAITING, 14);
-				progress = 15; // third stage is 15%
-				break;
-			case NETWORK_JOIN_STATUS_DOWNLOADING:
-				SetDParam(0, _network_join_kbytes);
-				SetDParam(1, _network_join_kbytes_total);
-				DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_DOWNLOADING, 14);
-				/* Fallthrough */
-			default: /* Waiting is 15%, so the resting receivement of map is maximum 70% */
-				progress = 15 + _network_join_kbytes * (100 - 15) / _network_join_kbytes_total;
-		}
-
-		/* Draw nice progress bar :) */
-		DrawFrameRect(20, 18, (int)((w->width - 20) * progress / 100), 28, 10, 0);
-	}	break;
-
-	case WE_CLICK:
-		switch (e->we.click.widget) {
-			case 2: /* Disconnect button */
-				NetworkDisconnect();
-				DeleteWindow(w);
-				SwitchMode(SM_MENU);
-				ShowNetworkGameWindow();
-				break;
-		}
-		break;
-
-		/* If the server asks for a password, we need to fill it in */
-		case WE_ON_EDIT_TEXT_CANCEL:
-			NetworkDisconnect();
-			ShowNetworkGameWindow();
-			break;
-
-		case WE_ON_EDIT_TEXT:
-			SEND_COMMAND(PACKET_CLIENT_PASSWORD)(pw_type, e->we.edittext.str);
-			break;
-	}
-}
-
-static const Widget _network_join_status_window_widget[] = {
-{    WWT_CAPTION,   RESIZE_NONE,    14,     0,   249,     0,    13, STR_NETWORK_CONNECTING, STR_018C_WINDOW_TITLE_DRAG_THIS},
-{      WWT_PANEL,   RESIZE_NONE,    14,     0,   249,    14,    84, 0x0,                    STR_NULL},
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,   BTC,    75,   175,    69,    80, STR_NETWORK_DISCONNECT, STR_NULL},
-{   WIDGETS_END},
-};
-
-static const WindowDesc _network_join_status_window_desc = {
-	WDP_CENTER, WDP_CENTER, 250, 85,
-	WC_NETWORK_STATUS_WINDOW, 0,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_MODAL,
-	_network_join_status_window_widget,
-	NetworkJoinStatusWindowWndProc,
-};
-
-void ShowJoinStatusWindow(void)
-{
-	Window *w;
-	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
-	w = AllocateWindowDesc(&_network_join_status_window_desc);
-	/* Parent the status window to the lobby */
-	if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0);
-}
-
-static void SendChat(const char *buf, DestType type, byte dest)
-{
-	if (buf[0] == '\0') return;
-	if (!_network_server) {
-		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT + type, type, dest, buf);
-	} else {
-		NetworkServer_HandleChat(NETWORK_ACTION_CHAT + type, type, dest, buf, NETWORK_SERVER_INDEX);
-	}
-}
-
-/**
- * Find the next item of the list of things that can be auto-completed.
- * @param item The current indexed item to return. This function can, and most
- *     likely will, alter item, to skip empty items in the arrays.
- * @return Returns the char that matched to the index.
- */
-static const char *ChatTabCompletionNextItem(uint *item)
-{
-	static char chat_tab_temp_buffer[64];
-
-	/* First, try clients */
-	if (*item < MAX_CLIENT_INFO) {
-		/* Skip inactive clients */
-		while (_network_client_info[*item].client_index == NETWORK_EMPTY_INDEX && *item < MAX_CLIENT_INFO) (*item)++;
-		if (*item < MAX_CLIENT_INFO) return _network_client_info[*item].client_name;
-	}
-
-	/* Then, try townnames */
-	/* Not that the following assumes all town indices are adjacent, ie no
-	 * towns have been deleted. */
-	if (*item <= (uint)MAX_CLIENT_INFO + GetMaxTownIndex()) {
-		const Town *t;
-
-		FOR_ALL_TOWNS_FROM(t, *item - MAX_CLIENT_INFO) {
-			/* Get the town-name via the string-system */
-			SetDParam(0, t->townnameparts);
-			GetString(chat_tab_temp_buffer, t->townnametype, lastof(chat_tab_temp_buffer));
-			return &chat_tab_temp_buffer[0];
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * Find what text to complete. It scans for a space from the left and marks
- *  the word right from that as to complete. It also writes a \0 at the
- *  position of the space (if any). If nothing found, buf is returned.
- */
-static char *ChatTabCompletionFindText(char *buf)
-{
-	char *p = strrchr(buf, ' ');
-	if (p == NULL) return buf;
-
-	*p = '\0';
-	return p + 1;
-}
-
-/**
- * See if we can auto-complete the current text of the user.
- */
-static void ChatTabCompletion(Window *w)
-{
-	static char _chat_tab_completion_buf[lengthof(_edit_str_buf)];
-	Textbuf *tb = &WP(w, querystr_d).text;
-	uint len, tb_len;
-	uint item;
-	char *tb_buf, *pre_buf;
-	const char *cur_name;
-	bool second_scan = false;
-
-	item = 0;
-
-	/* Copy the buffer so we can modify it without damaging the real data */
-	pre_buf = (_chat_tab_completion_active) ? strdup(_chat_tab_completion_buf) : strdup(tb->buf);
-
-	tb_buf  = ChatTabCompletionFindText(pre_buf);
-	tb_len  = strlen(tb_buf);
-
-	while ((cur_name = ChatTabCompletionNextItem(&item)) != NULL) {
-		item++;
-
-		if (_chat_tab_completion_active) {
-			/* We are pressing TAB again on the same name, is there an other name
-			 *  that starts with this? */
-			if (!second_scan) {
-				uint offset;
-				uint length;
-
-				/* If we are completing at the begin of the line, skip the ': ' we added */
-				if (tb_buf == pre_buf) {
-					offset = 0;
-					length = tb->length - 2;
-				} else {
-					/* Else, find the place we are completing at */
-					offset = strlen(pre_buf) + 1;
-					length = tb->length - offset;
-				}
-
-				/* Compare if we have a match */
-				if (strlen(cur_name) == length && strncmp(cur_name, tb->buf + offset, length) == 0) second_scan = true;
-
-				continue;
-			}
-
-			/* Now any match we make on _chat_tab_completion_buf after this, is perfect */
-		}
-
-		len = strlen(cur_name);
-		if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
-			/* Save the data it was before completion */
-			if (!second_scan) snprintf(_chat_tab_completion_buf, lengthof(_chat_tab_completion_buf), "%s", tb->buf);
-			_chat_tab_completion_active = true;
-
-			/* Change to the found name. Add ': ' if we are at the start of the line (pretty) */
-			if (pre_buf == tb_buf) {
-				snprintf(tb->buf, lengthof(_edit_str_buf), "%s: ", cur_name);
-			} else {
-				snprintf(tb->buf, lengthof(_edit_str_buf), "%s %s", pre_buf, cur_name);
-			}
-
-			/* Update the textbuffer */
-			UpdateTextBufferSize(&WP(w, querystr_d).text);
-
-			SetWindowDirty(w);
-			free(pre_buf);
-			return;
-		}
-	}
-
-	if (second_scan) {
-		/* We walked all posibilities, and the user presses tab again.. revert to original text */
-		strcpy(tb->buf, _chat_tab_completion_buf);
-		_chat_tab_completion_active = false;
-
-		/* Update the textbuffer */
-		UpdateTextBufferSize(&WP(w, querystr_d).text);
-
-		SetWindowDirty(w);
-	}
-	free(pre_buf);
-}
-
-/* uses querystr_d WP macro
- * uses querystr_d->caption to store
- * - type of chat message (Private/Team/All) in bytes 0-7
- * - destination of chat message in the case of Team/Private in bytes 8-15 */
-static void ChatWindowWndProc(Window *w, WindowEvent *e)
-{
-	switch (e->event) {
-	case WE_CREATE:
-		SendWindowMessage(WC_NEWS_WINDOW, 0, WE_CREATE, w->height, 0);
-		SETBIT(_no_scroll, SCROLL_CHAT); // do not scroll the game with the arrow-keys
-		break;
-
-	case WE_PAINT: {
-		static const StringID chat_captions[] = {
-			STR_NETWORK_CHAT_ALL_CAPTION,
-			STR_NETWORK_CHAT_COMPANY_CAPTION,
-			STR_NETWORK_CHAT_CLIENT_CAPTION
-		};
-		StringID msg;
-
-		DrawWindowWidgets(w);
-
-		assert(GB(WP(w, querystr_d).caption, 0, 8) < lengthof(chat_captions));
-		msg = chat_captions[GB(WP(w, querystr_d).caption, 0, 8)];
-		DrawStringRightAligned(w->widget[2].left - 2, w->widget[2].top + 1, msg, 16);
-		DrawEditBox(w, &WP(w, querystr_d), 2);
-	} break;
-
-	case WE_CLICK:
-		switch (e->we.click.widget) {
-			case 3: { /* Send */
-				DestType type = GB(WP(w, querystr_d).caption, 0, 8);
-				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
-				SendChat(WP(w, querystr_d).text.buf, type, dest);
-			} /* FALLTHROUGH */
-			case 0: /* Cancel */ DeleteWindow(w); break;
-		}
-		break;
-
-	case WE_MOUSELOOP:
-		HandleEditBox(w, &WP(w, querystr_d), 2);
-		break;
-
-	case WE_KEYPRESS:
-		if (e->we.keypress.keycode == WKC_TAB) {
-			ChatTabCompletion(w);
-		} else {
-			_chat_tab_completion_active = false;
-			switch (HandleEditBoxKey(w, &WP(w, querystr_d), 2, e)) {
-				case 1: { /* Return */
-				DestType type = GB(WP(w, querystr_d).caption, 0, 8);
-				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
-				SendChat(WP(w, querystr_d).text.buf, type, dest);
-			} /* FALLTHROUGH */
-				case 2: /* Escape */ DeleteWindow(w); break;
-			}
-		}
-		break;
-
-	case WE_DESTROY:
-		SendWindowMessage(WC_NEWS_WINDOW, 0, WE_DESTROY, 0, 0);
-		CLRBIT(_no_scroll, SCROLL_CHAT);
-		break;
-	}
-}
-
-static const Widget _chat_window_widgets[] = {
-{   WWT_CLOSEBOX, RESIZE_NONE, 14,   0,  10,  0, 13, STR_00C5,         STR_018B_CLOSE_WINDOW},
-{      WWT_PANEL, RESIZE_NONE, 14,  11, 639,  0, 13, 0x0,              STR_NULL}, // background
-{      WWT_PANEL, RESIZE_NONE, 14,  75, 577,  1, 12, 0x0,              STR_NULL}, // text box
-{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 578, 639,  1, 12, STR_NETWORK_SEND, STR_NULL}, // send button
-{   WIDGETS_END},
-};
-
-static const WindowDesc _chat_window_desc = {
-	WDP_CENTER, -26, 640, 14, // x, y, width, height
-	WC_SEND_NETWORK_MSG,0,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET,
-	_chat_window_widgets,
-	ChatWindowWndProc
-};
-
-void ShowNetworkChatQueryWindow(DestType type, byte dest)
-{
-	Window *w;
-
-	DeleteWindowById(WC_SEND_NETWORK_MSG, 0);
-
-	_edit_str_buf[0] = '\0';
-	_chat_tab_completion_active = false;
-
-	w = AllocateWindowDesc(&_chat_window_desc);
-
-	LowerWindowWidget(w, 2);
-	WP(w, querystr_d).caption = GB(type, 0, 8) | (dest << 8); // Misuse of caption
-	WP(w, querystr_d).afilter = CS_ALPHANUMERAL;
-	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_gui.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_GUI_H
-#define NETWORK_GUI_H
-
-#ifdef ENABLE_NETWORK
-
-#include "network_data.h"
-
-void ShowNetworkNeedPassword(NetworkPasswordType npt);
-void ShowNetworkGiveMoneyWindow(byte player); // PlayerID
-void ShowNetworkChatQueryWindow(DestType type, byte dest);
-void ShowJoinStatusWindow(void);
-void ShowNetworkGameWindow(void);
-void ShowClientList(void);
-
-#else /* ENABLE_NETWORK */
-/* Network function stubs when networking is disabled */
-
-static inline void ShowNetworkChatQueryWindow(byte desttype, byte dest) {}
-static inline void ShowClientList(void) {}
-static inline void ShowNetworkGameWindow(void) {}
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_GUI_H */
--- a/network_server.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1527 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "openttd.h" // XXX StringID
-#include "debug.h"
-#include "string.h"
-#include "strings.h"
-#include "network_data.h"
-#include "train.h"
-#include "date.h"
-#include "table/strings.h"
-#include "functions.h"
-#include "network_server.h"
-#include "network_udp.h"
-#include "console.h"
-#include "command.h"
-#include "saveload.h"
-#include "vehicle.h"
-#include "station.h"
-#include "variables.h"
-#include "genworld.h"
-
-// This file handles all the server-commands
-
-static void NetworkHandleCommandQueue(NetworkClientState* cs);
-
-// **********
-// Sending functions
-//   DEF_SERVER_SEND_COMMAND has parameter: NetworkClientState *cs
-// **********
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkClientState *cs, NetworkClientInfo *ci)
-{
-	//
-	// Packet: SERVER_CLIENT_INFO
-	// Function: Sends info about a client
-	// Data:
-	//    uint16:  The index of the client (always unique on a server. 1 = server)
-	//    uint8:  As which player the client is playing
-	//    String: The name of the client
-	//    String: The unique id of the client
-	//
-
-	if (ci->client_index != NETWORK_EMPTY_INDEX) {
-		Packet *p = NetworkSend_Init(PACKET_SERVER_CLIENT_INFO);
-		NetworkSend_uint16(p, ci->client_index);
-		NetworkSend_uint8 (p, ci->client_playas);
-		NetworkSend_string(p, ci->client_name);
-		NetworkSend_string(p, ci->unique_id);
-
-		NetworkSend_Packet(p, cs);
-	}
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)
-{
-//
-	// Packet: SERVER_COMPANY_INFO
-	// Function: Sends info about the companies
-	// Data:
-	//
-
-	int i;
-
-	Player *player;
-	Packet *p;
-
-	byte active = ActivePlayerCount();
-
-	if (active == 0) {
-		p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
-
-		NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
-		NetworkSend_uint8 (p, active);
-
-		NetworkSend_Packet(p, cs);
-		return;
-	}
-
-	NetworkPopulateCompanyInfo();
-
-	FOR_ALL_PLAYERS(player) {
-		if (!player->is_active) continue;
-
-		p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
-
-		NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
-		NetworkSend_uint8 (p, active);
-		NetworkSend_uint8 (p, player->index);
-
-		NetworkSend_string(p, _network_player_info[player->index].company_name);
-		NetworkSend_uint32(p, _network_player_info[player->index].inaugurated_year);
-		NetworkSend_uint64(p, _network_player_info[player->index].company_value);
-		NetworkSend_uint64(p, _network_player_info[player->index].money);
-		NetworkSend_uint64(p, _network_player_info[player->index].income);
-		NetworkSend_uint16(p, _network_player_info[player->index].performance);
-
-		/* Send 1 if there is a passord for the company else send 0 */
-		if (_network_player_info[player->index].password[0] != '\0') {
-			NetworkSend_uint8(p, 1);
-		} else {
-			NetworkSend_uint8(p, 0);
-		}
-
-		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
-			NetworkSend_uint16(p, _network_player_info[player->index].num_vehicle[i]);
-		}
-
-		for (i = 0; i < NETWORK_STATION_TYPES; i++) {
-			NetworkSend_uint16(p, _network_player_info[player->index].num_station[i]);
-		}
-
-		if (_network_player_info[player->index].players[0] == '\0') {
-			NetworkSend_string(p, "<none>");
-		} else {
-			NetworkSend_string(p, _network_player_info[player->index].players);
-		}
-
-		NetworkSend_Packet(p, cs);
-	}
-
-	p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
-
-	NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
-	NetworkSend_uint8 (p, 0);
-
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error)
-{
-	//
-	// Packet: SERVER_ERROR
-	// Function: The client made an error
-	// Data:
-	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
-	//
-
-	char str[100];
-	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR);
-
-	NetworkSend_uint8(p, error);
-	NetworkSend_Packet(p, cs);
-
-	GetNetworkErrorMsg(str, error, lastof(str));
-
-	// Only send when the current client was in game
-	if (cs->status > STATUS_AUTH) {
-		NetworkClientState *new_cs;
-		char client_name[NETWORK_CLIENT_NAME_LENGTH];
-
-		NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-		DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
-
-		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
-
-		FOR_ALL_CLIENTS(new_cs) {
-			if (new_cs->status > STATUS_AUTH && new_cs != cs) {
-				// Some errors we filter to a more general error. Clients don't have to know the real
-				//  reason a joining failed.
-				if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION)
-					error = NETWORK_ERROR_ILLEGAL_PACKET;
-
-				SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, error);
-			}
-		}
-	} else {
-		DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", cs->index, str);
-	}
-
-	cs->has_quit = true;
-
-	// Make sure the data get's there before we close the connection
-	NetworkSend_Packets(cs);
-
-	// The client made a mistake, so drop his connection now!
-	NetworkCloseClient(cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientState *cs, NetworkPasswordType type)
-{
-	//
-	// Packet: SERVER_NEED_PASSWORD
-	// Function: Indication to the client that the server needs a password
-	// Data:
-	//    uint8:  Type of password
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
-	NetworkSend_uint8(p, type);
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
-{
-	//
-	// Packet: SERVER_WELCOME
-	// Function: The client is joined and ready to receive his map
-	// Data:
-	//    uint16:  Own ClientID
-	//
-
-	Packet *p;
-	const NetworkClientState *new_cs;
-
-	// Invalid packet when status is AUTH or higher
-	if (cs->status >= STATUS_AUTH) return;
-
-	cs->status = STATUS_AUTH;
-	_network_game_info.clients_on++;
-
-	p = NetworkSend_Init(PACKET_SERVER_WELCOME);
-	NetworkSend_uint16(p, cs->index);
-	NetworkSend_Packet(p, cs);
-
-		// Transmit info about all the active clients
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs != cs && new_cs->status > STATUS_AUTH)
-			SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, DEREF_CLIENT_INFO(new_cs));
-	}
-	// Also send the info of the server
-	SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX));
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WAIT)
-{
-	//
-	// Packet: PACKET_SERVER_WAIT
-	// Function: The client can not receive the map at the moment because
-	//             someone else is already receiving the map
-	// Data:
-	//    uint8:  Clients awaiting map
-	//
-	int waiting = 0;
-	NetworkClientState *new_cs;
-	Packet *p;
-
-	// Count how many players are waiting in the queue
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs->status == STATUS_MAP_WAIT) waiting++;
-	}
-
-	p = NetworkSend_Init(PACKET_SERVER_WAIT);
-	NetworkSend_uint8(p, waiting);
-	NetworkSend_Packet(p, cs);
-}
-
-// This sends the map to the client
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP)
-{
-	//
-	// Packet: SERVER_MAP
-	// Function: Sends the map to the client, or a part of it (it is splitted in
-	//   a lot of multiple packets)
-	// Data:
-	//    uint8:  packet-type (MAP_PACKET_START, MAP_PACKET_NORMAL and MAP_PACKET_END)
-	//  if MAP_PACKET_START:
-	//    uint32: The current FrameCounter
-	//  if MAP_PACKET_NORMAL:
-	//    piece of the map (till max-size of packet)
-	//  if MAP_PACKET_END:
-	//    uint32: seed0 of player
-	//    uint32: seed1 of player
-	//      last 2 are repeated MAX_PLAYERS time
-	//
-
-	static FILE *file_pointer;
-	static uint sent_packets; // How many packets we did send succecfully last time
-
-	if (cs->status < STATUS_AUTH) {
-		// Illegal call, return error and ignore the packet
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
-		return;
-	}
-
-	if (cs->status == STATUS_AUTH) {
-		char filename[256];
-		Packet *p;
-
-		// Make a dump of the current game
-		snprintf(filename, lengthof(filename), "%s%snetwork_server.tmp",  _paths.autosave_dir, PATHSEP);
-		if (SaveOrLoad(filename, SL_SAVE) != SL_OK) error("network savedump failed");
-
-		file_pointer = fopen(filename, "rb");
-		fseek(file_pointer, 0, SEEK_END);
-
-		// Now send the _frame_counter and how many packets are coming
-		p = NetworkSend_Init(PACKET_SERVER_MAP);
-		NetworkSend_uint8(p, MAP_PACKET_START);
-		NetworkSend_uint32(p, _frame_counter);
-		NetworkSend_uint32(p, ftell(file_pointer));
-		NetworkSend_Packet(p, cs);
-
-		fseek(file_pointer, 0, SEEK_SET);
-
-		sent_packets = 4; // We start with trying 4 packets
-
-		cs->status = STATUS_MAP;
-		/* Mark the start of download */
-		cs->last_frame = _frame_counter;
-		cs->last_frame_server = _frame_counter;
-	}
-
-	if (cs->status == STATUS_MAP) {
-		uint i;
-		int res;
-		for (i = 0; i < sent_packets; i++) {
-			Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
-			NetworkSend_uint8(p, MAP_PACKET_NORMAL);
-			res = (int)fread(p->buffer + p->size, 1, SEND_MTU - p->size, file_pointer);
-
-			if (ferror(file_pointer)) error("Error reading temporary network savegame!");
-
-			p->size += res;
-			NetworkSend_Packet(p, cs);
-			if (feof(file_pointer)) {
-				// Done reading!
-				Packet *p = NetworkSend_Init(PACKET_SERVER_MAP);
-				NetworkSend_uint8(p, MAP_PACKET_END);
-				NetworkSend_Packet(p, cs);
-
-				// Set the status to DONE_MAP, no we will wait for the client
-				//  to send it is ready (maybe that happens like never ;))
-				cs->status = STATUS_DONE_MAP;
-				fclose(file_pointer);
-
-				{
-					NetworkClientState *new_cs;
-					bool new_map_client = false;
-					// Check if there is a client waiting for receiving the map
-					//  and start sending him the map
-					FOR_ALL_CLIENTS(new_cs) {
-						if (new_cs->status == STATUS_MAP_WAIT) {
-							// Check if we already have a new client to send the map to
-							if (!new_map_client) {
-								// If not, this client will get the map
-								new_cs->status = STATUS_AUTH;
-								new_map_client = true;
-								SEND_COMMAND(PACKET_SERVER_MAP)(new_cs);
-							} else {
-								// Else, send the other clients how many clients are in front of them
-								SEND_COMMAND(PACKET_SERVER_WAIT)(new_cs);
-							}
-						}
-					}
-				}
-
-				// There is no more data, so break the for
-				break;
-			}
-		}
-
-		// Send all packets (forced) and check if we have send it all
-		NetworkSend_Packets(cs);
-		if (cs->packet_queue == NULL) {
-			// All are sent, increase the sent_packets
-			sent_packets *= 2;
-		} else {
-			// Not everything is sent, decrease the sent_packets
-			if (sent_packets > 1) sent_packets /= 2;
-		}
-	}
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkClientState *cs, uint16 client_index)
-{
-	//
-	// Packet: SERVER_JOIN
-	// Function: A client is joined (all active clients receive this after a
-	//     PACKET_CLIENT_MAP_OK) Mostly what directly follows is a
-	//     PACKET_SERVER_CLIENT_INFO
-	// Data:
-	//    uint16:  Client-Index
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_JOIN);
-
-	NetworkSend_uint16(p, client_index);
-
-	NetworkSend_Packet(p, cs);
-}
-
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_FRAME)
-{
-	//
-	// Packet: SERVER_FRAME
-	// Function: Sends the current frame-counter to the client
-	// Data:
-	//    uint32: Frame Counter
-	//    uint32: Frame Counter Max (how far may the client walk before the server?)
-	//    [uint32: general-seed-1]
-	//    [uint32: general-seed-2]
-	//      (last two depends on compile-settings, and are not default settings)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_FRAME);
-	NetworkSend_uint32(p, _frame_counter);
-	NetworkSend_uint32(p, _frame_counter_max);
-#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
-	NetworkSend_uint32(p, _sync_seed_1);
-#ifdef NETWORK_SEND_DOUBLE_SEED
-	NetworkSend_uint32(p, _sync_seed_2);
-#endif
-#endif
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SYNC)
-{
-	//
-	// Packet: SERVER_SYNC
-	// Function: Sends a sync-check to the client
-	// Data:
-	//    uint32: Frame Counter
-	//    uint32: General-seed-1
-	//    [uint32: general-seed-2]
-	//      (last one depends on compile-settings, and are not default settings)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_SYNC);
-	NetworkSend_uint32(p, _frame_counter);
-	NetworkSend_uint32(p, _sync_seed_1);
-
-#ifdef NETWORK_SEND_DOUBLE_SEED
-	NetworkSend_uint32(p, _sync_seed_2);
-#endif
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientState *cs, CommandPacket *cp)
-{
-	//
-	// Packet: SERVER_COMMAND
-	// Function: Sends a DoCommand to the client
-	// Data:
-	//    uint8:  PlayerID (0..MAX_PLAYERS-1)
-	//    uint32: CommandID (see command.h)
-	//    uint32: P1 (free variables used in DoCommand)
-	//    uint32: P2
-	//    uint32: Tile
-	//    string: text
-	//    uint8:  CallBackID (see callback_table.c)
-	//    uint32: Frame of execution
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_COMMAND);
-
-	NetworkSend_uint8(p, cp->player);
-	NetworkSend_uint32(p, cp->cmd);
-	NetworkSend_uint32(p, cp->p1);
-	NetworkSend_uint32(p, cp->p2);
-	NetworkSend_uint32(p, cp->tile);
-	NetworkSend_string(p, cp->text);
-	NetworkSend_uint8(p, cp->callback);
-	NetworkSend_uint32(p, cp->frame);
-
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
-{
-	//
-	// Packet: SERVER_CHAT
-	// Function: Sends a chat-packet to the client
-	// Data:
-	//    uint8:  ActionID (see network_data.h, NetworkAction)
-	//    uint16:  Client-index
-	//    String: Message (max MAX_TEXT_MSG_LEN)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_CHAT);
-
-	NetworkSend_uint8(p, action);
-	NetworkSend_uint16(p, client_index);
-	NetworkSend_uint8(p, self_send);
-	NetworkSend_string(p, msg);
-
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno)
-{
-	//
-	// Packet: SERVER_ERROR_QUIT
-	// Function: One of the clients made an error and is quiting the game
-	//      This packet informs the other clients of that.
-	// Data:
-	//    uint16:  Client-index
-	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR_QUIT);
-
-	NetworkSend_uint16(p, client_index);
-	NetworkSend_uint8(p, errorno);
-
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkClientState *cs, uint16 client_index, const char *leavemsg)
-{
-	//
-	// Packet: SERVER_ERROR_QUIT
-	// Function: A client left the game, and this packets informs the other clients
-	//      of that.
-	// Data:
-	//    uint16:  Client-index
-	//    String: leave-message
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_QUIT);
-
-	NetworkSend_uint16(p, client_index);
-	NetworkSend_string(p, leavemsg);
-
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN)
-{
-	//
-	// Packet: SERVER_SHUTDOWN
-	// Function: Let the clients know that the server is closing
-	// Data:
-	//     <none>
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_SHUTDOWN);
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
-{
-	//
-	// Packet: PACKET_SERVER_NEWGAME
-	// Function: Let the clients know that the server is loading a new map
-	// Data:
-	//     <none>
-	//
-
-	Packet *p = NetworkSend_Init(PACKET_SERVER_NEWGAME);
-	NetworkSend_Packet(p, cs);
-}
-
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command)
-{
-	Packet *p = NetworkSend_Init(PACKET_SERVER_RCON);
-
-	NetworkSend_uint16(p, color);
-	NetworkSend_string(p, command);
-	NetworkSend_Packet(p, cs);
-}
-
-// **********
-// Receiving functions
-//   DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p
-// **********
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO)
-{
-	SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)(cs);
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
-{
-	char name[NETWORK_CLIENT_NAME_LENGTH];
-	char unique_id[NETWORK_NAME_LENGTH];
-	NetworkClientInfo *ci;
-	byte playas;
-	NetworkLanguage client_lang;
-	char client_revision[NETWORK_REVISION_LENGTH];
-
-	NetworkRecv_string(cs, p, client_revision, sizeof(client_revision));
-
-#if defined(WITH_REV) || defined(WITH_REV_HACK)
-	// Check if the client has revision control enabled
-	if (strcmp(NOREV_STRING, client_revision) != 0 &&
-			strcmp(_network_game_info.server_revision, client_revision) != 0) {
-		// Different revisions!!
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
-		return;
-	}
-#endif
-
-	NetworkRecv_string(cs, p, name, sizeof(name));
-	playas = NetworkRecv_uint8(cs, p);
-	client_lang = NetworkRecv_uint8(cs, p);
-	NetworkRecv_string(cs, p, unique_id, sizeof(unique_id));
-
-	if (cs->has_quit) return;
-
-	// join another company does not affect these values
-	switch (playas) {
-		case PLAYER_NEW_COMPANY: /* New company */
-			if (ActivePlayerCount() >= _network_game_info.companies_max) {
-				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
-				return;
-			}
-			break;
-		case PLAYER_SPECTATOR: /* Spectator */
-			if (NetworkSpectatorCount() >= _network_game_info.spectators_max) {
-				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
-				return;
-			}
-			break;
-		default: /* Join another company (companies 1-8 (index 0-7)) */
-			if (!IsValidPlayer(playas)) {
-				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
-				return;
-			}
-			break;
-	}
-
-	// We need a valid name.. make it Player
-	if (*name == '\0') ttd_strlcpy(name, "Player", sizeof(name));
-
-	if (!NetworkFindName(name)) { // Change name if duplicate
-		// We could not create a name for this player
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NAME_IN_USE);
-		return;
-	}
-
-	ci = DEREF_CLIENT_INFO(cs);
-
-	ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
-	ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
-	ci->client_playas = playas;
-	ci->client_lang = client_lang;
-
-	// We now want a password from the client
-	//  else we do not allow him in!
-	if (_network_game_info.use_password) {
-		SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
-	} else {
-		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
-			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
-		} else {
-			SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
-		}
-	}
-
-	/* Make sure companies to which people try to join are not autocleaned */
-	if (IsValidPlayer(playas)) _network_player_info[playas].months_empty = 0;
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
-{
-	NetworkPasswordType type;
-	char password[NETWORK_PASSWORD_LENGTH];
-	const NetworkClientInfo *ci;
-
-	type = NetworkRecv_uint8(cs, p);
-	NetworkRecv_string(cs, p, password, sizeof(password));
-
-	if (cs->status == STATUS_INACTIVE && type == NETWORK_GAME_PASSWORD) {
-		// Check game-password
-		if (strcmp(password, _network_game_info.server_password) != 0) {
-			// Password is invalid
-			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
-			return;
-		}
-
-		ci = DEREF_CLIENT_INFO(cs);
-
-		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
-			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
-			return;
-		}
-
-		// Valid password, allow user
-		SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
-		return;
-	} else if (cs->status == STATUS_INACTIVE && type == NETWORK_COMPANY_PASSWORD) {
-		ci = DEREF_CLIENT_INFO(cs);
-
-		if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
-			// Password is invalid
-			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
-			return;
-		}
-
-		SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
-		return;
-	}
-
-
-	SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
-	return;
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP)
-{
-	const NetworkClientState *new_cs;
-
-	// The client was never joined.. so this is impossible, right?
-	//  Ignore the packet, give the client a warning, and close his connection
-	if (cs->status < STATUS_AUTH || cs->has_quit) {
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
-		return;
-	}
-
-	// Check if someone else is receiving the map
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs->status == STATUS_MAP) {
-			// Tell the new client to wait
-			cs->status = STATUS_MAP_WAIT;
-			SEND_COMMAND(PACKET_SERVER_WAIT)(cs);
-			return;
-		}
-	}
-
-	// We receive a request to upload the map.. give it to the client!
-	SEND_COMMAND(PACKET_SERVER_MAP)(cs);
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
-{
-	// Client has the map, now start syncing
-	if (cs->status == STATUS_DONE_MAP && !cs->has_quit) {
-		char client_name[NETWORK_CLIENT_NAME_LENGTH];
-		NetworkClientState *new_cs;
-
-		NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-		NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, client_name, "");
-
-		// Mark the client as pre-active, and wait for an ACK
-		//  so we know he is done loading and in sync with us
-		cs->status = STATUS_PRE_ACTIVE;
-		NetworkHandleCommandQueue(cs);
-		SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
-		SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
-
-		// This is the frame the client receives
-		//  we need it later on to make sure the client is not too slow
-		cs->last_frame = _frame_counter;
-		cs->last_frame_server = _frame_counter;
-
-		FOR_ALL_CLIENTS(new_cs) {
-			if (new_cs->status > STATUS_AUTH) {
-				SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, DEREF_CLIENT_INFO(cs));
-				SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->index);
-			}
-		}
-
-		if (_network_pause_on_join) {
-			/* Now pause the game till the client is in sync */
-			DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
-
-			NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (incoming client)", NETWORK_SERVER_INDEX);
-		}
-	} else {
-		// Wrong status for this packet, give a warning to client, and close connection
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
-	}
-}
-
-/** Enforce the command flags.
- * Eg a server-only command can only be executed by a server, etc.
- * @param *cp the commandpacket that is going to be checked
- * @param *ci client information for debugging output to console
- */
-static bool CheckCommandFlags(const CommandPacket *cp, const NetworkClientInfo *ci)
-{
-	byte flags = GetCommandFlags(cp->cmd);
-
-	if (flags & CMD_SERVER && ci->client_index != NETWORK_SERVER_INDEX) {
-		IConsolePrintF(_icolour_err, "WARNING: server only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
-		return false;
-	}
-
-	if (flags & CMD_OFFLINE) {
-		IConsolePrintF(_icolour_err, "WARNING: offline only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
-		return false;
-	}
-
-	return true;
-}
-
-/** The client has done a command and wants us to handle it
- * @param *cs the connected client that has sent the command
- * @param *p the packet in which the command was sent
- */
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
-{
-	NetworkClientState *new_cs;
-	const NetworkClientInfo *ci;
-	byte callback;
-
-	CommandPacket *cp = malloc(sizeof(CommandPacket));
-
-	// The client was never joined.. so this is impossible, right?
-	//  Ignore the packet, give the client a warning, and close his connection
-	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
-		return;
-	}
-
-	cp->player = NetworkRecv_uint8(cs, p);
-	cp->cmd    = NetworkRecv_uint32(cs, p);
-	cp->p1     = NetworkRecv_uint32(cs, p);
-	cp->p2     = NetworkRecv_uint32(cs, p);
-	cp->tile   = NetworkRecv_uint32(cs, p);
-	NetworkRecv_string(cs, p, cp->text, lengthof(cp->text));
-
-	callback = NetworkRecv_uint8(cs, p);
-
-	if (cs->has_quit) return;
-
-	ci = DEREF_CLIENT_INFO(cs);
-
-	/* Check if cp->cmd is valid */
-	if (!IsValidCommand(cp->cmd)) {
-		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
-		return;
-	}
-
-	if (!CheckCommandFlags(cp, ci)) {
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
-		return;
-	}
-
-	/** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
-	 * to match the player in the packet. If it doesn't, the client has done
-	 * something pretty naughty (or a bug), and will be kicked
-	 */
-	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
-		IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
-		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
-		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
-		return;
-	}
-
-	/** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
-	 * player the correct ID, the server injects p2 and executes the command. Any other p1
-	 * is prohibited. Pretty ugly and should be redone together with its function.
-	 * @see CmdPlayerCtrl() players.c:655
-	 */
-	if (cp->cmd == CMD_PLAYER_CTRL) {
-		if (cp->p1 != 0) {
-			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
-			return;
-		}
-
-		/* XXX - Execute the command as a valid player. Normally this would be done by a
-		 * spectator, but that is not allowed any commands. So do an impersonation. The drawback
-		 * of this is that the first company's last_built_tile is also updated... */
-		cp->player = 0;
-		cp->p2 = cs - _clients; // XXX - UGLY! p2 is mis-used to get the client-id in CmdPlayerCtrl
-	}
-
-	// The frame can be executed in the same frame as the next frame-packet
-	//  That frame just before that frame is saved in _frame_counter_max
-	cp->frame = _frame_counter_max + 1;
-	cp->next  = NULL;
-
-	// Queue the command for the clients (are send at the end of the frame
-	//   if they can handle it ;))
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs->status >= STATUS_MAP) {
-			// Callbacks are only send back to the client who sent them in the
-			//  first place. This filters that out.
-			cp->callback = (new_cs != cs) ? 0 : callback;
-			NetworkAddCommandQueue(new_cs, cp);
-		}
-	}
-
-	cp->callback = 0;
-	// Queue the command on the server
-	if (_local_command_queue == NULL) {
-		_local_command_queue = cp;
-	} else {
-		// Find last packet
-		CommandPacket *c = _local_command_queue;
-		while (c->next != NULL) c = c->next;
-		c->next = cp;
-	}
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR)
-{
-	// This packets means a client noticed an error and is reporting this
-	//  to us. Display the error and report it to the other clients
-	NetworkClientState *new_cs;
-	char str[100];
-	char client_name[NETWORK_CLIENT_NAME_LENGTH];
-	NetworkErrorCode errorno = NetworkRecv_uint8(cs, p);
-
-	// The client was never joined.. thank the client for the packet, but ignore it
-	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
-		cs->has_quit = true;
-		return;
-	}
-
-	NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-	GetNetworkErrorMsg(str, errorno, lastof(str));
-
-	DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
-
-	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
-
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs->status > STATUS_AUTH) {
-			SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
-		}
-	}
-
-	cs->has_quit = true;
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
-{
-	// The client wants to leave. Display this and report it to the other
-	//  clients.
-	NetworkClientState *new_cs;
-	char str[100];
-	char client_name[NETWORK_CLIENT_NAME_LENGTH];
-
-	// The client was never joined.. thank the client for the packet, but ignore it
-	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
-		cs->has_quit = true;
-		return;
-	}
-
-	NetworkRecv_string(cs, p, str, lengthof(str));
-
-	NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
-
-	FOR_ALL_CLIENTS(new_cs) {
-		if (new_cs->status > STATUS_AUTH) {
-			SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str);
-		}
-	}
-
-	cs->has_quit = true;
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK)
-{
-	uint32 frame = NetworkRecv_uint32(cs, p);
-
-	/* The client is trying to catch up with the server */
-	if (cs->status == STATUS_PRE_ACTIVE) {
-		/* The client is not yet catched up? */
-		if (frame + DAY_TICKS < _frame_counter) return;
-
-		/* Now he is! Unpause the game */
-		cs->status = STATUS_ACTIVE;
-
-		if (_network_pause_on_join) {
-			DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
-			NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (client connected)", NETWORK_SERVER_INDEX);
-		}
-
-		CheckMinPlayers();
-
-		/* Execute script for, e.g. MOTD */
-		IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
-	}
-
-	// The client received the frame, make note of it
-	cs->last_frame = frame;
-	// With those 2 values we can calculate the lag realtime
-	cs->last_frame_server = _frame_counter;
-}
-
-
-
-void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index)
-{
-	NetworkClientState *cs;
-	const NetworkClientInfo *ci, *ci_own, *ci_to;
-
-	switch (desttype) {
-	case DESTTYPE_CLIENT:
-		/* Are we sending to the server? */
-		if (dest == NETWORK_SERVER_INDEX) {
-			ci = NetworkFindClientInfoFromIndex(from_index);
-			/* Display the text locally, and that is it */
-			if (ci != NULL)
-				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
-		} else {
-			/* Else find the client to send the message to */
-			FOR_ALL_CLIENTS(cs) {
-				if (cs->index == dest) {
-					SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
-					break;
-				}
-			}
-		}
-
-		// Display the message locally (so you know you have sent it)
-		if (from_index != dest) {
-			if (from_index == NETWORK_SERVER_INDEX) {
-				ci = NetworkFindClientInfoFromIndex(from_index);
-				ci_to = NetworkFindClientInfoFromIndex(dest);
-				if (ci != NULL && ci_to != NULL)
-					NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), true, ci_to->client_name, "%s", msg);
-			} else {
-				FOR_ALL_CLIENTS(cs) {
-					if (cs->index == from_index) {
-						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, dest, true, msg);
-						break;
-					}
-				}
-			}
-		}
-		break;
-	case DESTTYPE_TEAM: {
-		bool show_local = true; // If this is false, the message is already displayed
-														// on the client who did sent it.
-		/* Find all clients that belong to this player */
-		ci_to = NULL;
-		FOR_ALL_CLIENTS(cs) {
-			ci = DEREF_CLIENT_INFO(cs);
-			if (ci->client_playas == dest) {
-				SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
-				if (cs->index == from_index) show_local = false;
-				ci_to = ci; // Remember a client that is in the company for company-name
-			}
-		}
-
-		ci = NetworkFindClientInfoFromIndex(from_index);
-		ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
-			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
-			if (from_index == NETWORK_SERVER_INDEX) show_local = false;
-			ci_to = ci_own;
-		}
-
-		/* There is no such player */
-		if (ci_to == NULL) break;
-
-		// Display the message locally (so you know you have sent it)
-		if (ci != NULL && show_local) {
-			if (from_index == NETWORK_SERVER_INDEX) {
-				char name[NETWORK_NAME_LENGTH];
-				StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : STR_NETWORK_SPECTATORS;
-				GetString(name, str, lastof(name));
-				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
-			} else {
-				FOR_ALL_CLIENTS(cs) {
-					if (cs->index == from_index) {
-						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, ci_to->client_index, true, msg);
-					}
-				}
-			}
-		}
-		}
-		break;
-	default:
-		DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
-		/* fall-through to next case */
-	case DESTTYPE_BROADCAST:
-		FOR_ALL_CLIENTS(cs) {
-			SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
-		}
-		ci = NetworkFindClientInfoFromIndex(from_index);
-		if (ci != NULL)
-			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
-		break;
-	}
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
-{
-	NetworkAction action = NetworkRecv_uint8(cs, p);
-	DestType desttype = NetworkRecv_uint8(cs, p);
-	int dest = NetworkRecv_uint8(cs, p);
-	char msg[MAX_TEXT_MSG_LEN];
-
-	NetworkRecv_string(cs, p, msg, MAX_TEXT_MSG_LEN);
-
-	NetworkServer_HandleChat(action, desttype, dest, msg, cs->index);
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD)
-{
-	char password[NETWORK_PASSWORD_LENGTH];
-	const NetworkClientInfo *ci;
-
-	NetworkRecv_string(cs, p, password, sizeof(password));
-	ci = DEREF_CLIENT_INFO(cs);
-
-	if (IsValidPlayer(ci->client_playas)) {
-		ttd_strlcpy(_network_player_info[ci->client_playas].password, password, sizeof(_network_player_info[0].password));
-	}
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
-{
-	char client_name[NETWORK_CLIENT_NAME_LENGTH];
-	NetworkClientInfo *ci;
-
-	NetworkRecv_string(cs, p, client_name, sizeof(client_name));
-	ci = DEREF_CLIENT_INFO(cs);
-
-	if (cs->has_quit) return;
-
-	if (ci != NULL) {
-		// Display change
-		if (NetworkFindName(client_name)) {
-			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", client_name);
-			ttd_strlcpy(ci->client_name, client_name, sizeof(ci->client_name));
-			NetworkUpdateClientInfo(ci->client_index);
-		}
-	}
-}
-
-DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
-{
-	char pass[NETWORK_PASSWORD_LENGTH];
-	char command[NETWORK_RCONCOMMAND_LENGTH];
-
-	if (_network_game_info.rcon_password[0] == '\0') return;
-
-	NetworkRecv_string(cs, p, pass, sizeof(pass));
-	NetworkRecv_string(cs, p, command, sizeof(command));
-
-	if (strcmp(pass, _network_game_info.rcon_password) != 0) {
-		DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->index);
-		return;
-	}
-
-	DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", cs->index, command);
-
-	_redirect_console_to_client = cs->index;
-	IConsoleCmdExec(command);
-	_redirect_console_to_client = 0;
-	return;
-}
-
-// The layout for the receive-functions by the server
-typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p);
-
-
-// This array matches PacketType. At an incoming
-//  packet it is matches against this array
-//  and that way the right function to handle that
-//  packet is found.
-static NetworkServerPacket* const _network_server_packet[] = {
-	NULL, /*PACKET_SERVER_FULL,*/
-	NULL, /*PACKET_SERVER_BANNED,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
-	NULL, /*PACKET_SERVER_ERROR,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
-	NULL, /*PACKET_SERVER_COMPANY_INFO,*/
-	NULL, /*PACKET_SERVER_CLIENT_INFO,*/
-	NULL, /*PACKET_SERVER_NEED_PASSWORD,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD),
-	NULL, /*PACKET_SERVER_WELCOME,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_GETMAP),
-	NULL, /*PACKET_SERVER_WAIT,*/
-	NULL, /*PACKET_SERVER_MAP,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK),
-	NULL, /*PACKET_SERVER_JOIN,*/
-	NULL, /*PACKET_SERVER_FRAME,*/
-	NULL, /*PACKET_SERVER_SYNC,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_ACK),
-	RECEIVE_COMMAND(PACKET_CLIENT_COMMAND),
-	NULL, /*PACKET_SERVER_COMMAND,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_CHAT),
-	NULL, /*PACKET_SERVER_CHAT,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD),
-	RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME),
-	RECEIVE_COMMAND(PACKET_CLIENT_QUIT),
-	RECEIVE_COMMAND(PACKET_CLIENT_ERROR),
-	NULL, /*PACKET_SERVER_QUIT,*/
-	NULL, /*PACKET_SERVER_ERROR_QUIT,*/
-	NULL, /*PACKET_SERVER_SHUTDOWN,*/
-	NULL, /*PACKET_SERVER_NEWGAME,*/
-	NULL, /*PACKET_SERVER_RCON,*/
-	RECEIVE_COMMAND(PACKET_CLIENT_RCON),
-};
-
-// If this fails, check the array above with network_data.h
-assert_compile(lengthof(_network_server_packet) == PACKET_END);
-
-// This update the company_info-stuff
-void NetworkPopulateCompanyInfo(void)
-{
-	char password[NETWORK_PASSWORD_LENGTH];
-	const Player *p;
-	const Vehicle *v;
-	const Station *s;
-	const NetworkClientState *cs;
-	const NetworkClientInfo *ci;
-	uint i;
-	uint16 months_empty;
-
-	FOR_ALL_PLAYERS(p) {
-		if (!p->is_active) {
-			memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
-			continue;
-		}
-
-		// Clean the info but not the password
-		ttd_strlcpy(password, _network_player_info[p->index].password, sizeof(password));
-		months_empty = _network_player_info[p->index].months_empty;
-		memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
-		_network_player_info[p->index].months_empty = months_empty;
-		ttd_strlcpy(_network_player_info[p->index].password, password, sizeof(_network_player_info[p->index].password));
-
-		// Grap the company name
-		SetDParam(0, p->name_1);
-		SetDParam(1, p->name_2);
-		GetString(_network_player_info[p->index].company_name, STR_JUST_STRING, lastof(_network_player_info[p->index].company_name));
-
-		// Check the income
-		if (_cur_year - 1 == p->inaugurated_year) {
-			// The player is here just 1 year, so display [2], else display[1]
-			for (i = 0; i < lengthof(p->yearly_expenses[2]); i++) {
-				_network_player_info[p->index].income -= p->yearly_expenses[2][i];
-			}
-		} else {
-			for (i = 0; i < lengthof(p->yearly_expenses[1]); i++) {
-				_network_player_info[p->index].income -= p->yearly_expenses[1][i];
-			}
-		}
-
-		// Set some general stuff
-		_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
-		_network_player_info[p->index].company_value = p->old_economy[0].company_value;
-		_network_player_info[p->index].money = p->money64;
-		_network_player_info[p->index].performance = p->old_economy[0].performance_history;
-	}
-
-	// Go through all vehicles and count the type of vehicles
-	FOR_ALL_VEHICLES(v) {
-		if (!IsValidPlayer(v->owner)) continue;
-
-		switch (v->type) {
-			case VEH_Train:
-				if (IsFrontEngine(v)) _network_player_info[v->owner].num_vehicle[0]++;
-				break;
-
-			case VEH_Road:
-				if (v->cargo_type != CT_PASSENGERS) {
-					_network_player_info[v->owner].num_vehicle[1]++;
-				} else {
-					_network_player_info[v->owner].num_vehicle[2]++;
-				}
-				break;
-
-			case VEH_Aircraft:
-				if (v->subtype <= 2) _network_player_info[v->owner].num_vehicle[3]++;
-				break;
-
-			case VEH_Ship:
-				_network_player_info[v->owner].num_vehicle[4]++;
-				break;
-
-			case VEH_Special:
-			case VEH_Disaster:
-				break;
-		}
-	}
-
-	// Go through all stations and count the types of stations
-	FOR_ALL_STATIONS(s) {
-		if (IsValidPlayer(s->owner)) {
-			NetworkPlayerInfo *npi = &_network_player_info[s->owner];
-
-			if (s->facilities & FACIL_TRAIN)      npi->num_station[0]++;
-			if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
-			if (s->facilities & FACIL_BUS_STOP)   npi->num_station[2]++;
-			if (s->facilities & FACIL_AIRPORT)    npi->num_station[3]++;
-			if (s->facilities & FACIL_DOCK)       npi->num_station[4]++;
-		}
-	}
-
-	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-	// Register local player (if not dedicated)
-	if (ci != NULL && IsValidPlayer(ci->client_playas))
-		ttd_strlcpy(_network_player_info[ci->client_playas].players, ci->client_name, sizeof(_network_player_info[0].players));
-
-	FOR_ALL_CLIENTS(cs) {
-		char client_name[NETWORK_CLIENT_NAME_LENGTH];
-
-		NetworkGetClientName(client_name, sizeof(client_name), cs);
-
-		ci = DEREF_CLIENT_INFO(cs);
-		if (ci != NULL && IsValidPlayer(ci->client_playas)) {
-			if (strlen(_network_player_info[ci->client_playas].players) != 0)
-				ttd_strlcat(_network_player_info[ci->client_playas].players, ", ", lengthof(_network_player_info[0].players));
-
-			ttd_strlcat(_network_player_info[ci->client_playas].players, client_name, lengthof(_network_player_info[0].players));
-		}
-	}
-}
-
-// Send a packet to all clients with updated info about this client_index
-void NetworkUpdateClientInfo(uint16 client_index)
-{
-	NetworkClientState *cs;
-	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(client_index);
-
-	if (ci == NULL) return;
-
-	FOR_ALL_CLIENTS(cs) {
-		SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
-	}
-}
-
-/* Check if we want to restart the map */
-static void NetworkCheckRestartMap(void)
-{
-	if (_network_restart_game_year != 0 && _cur_year >= _network_restart_game_year) {
-		DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
-
-		StartNewGameWithoutGUI(GENERATE_NEW_SEED);
-	}
-}
-
-/* Check if the server has autoclean_companies activated
-    Two things happen:
-      1) If a company is not protected, it is closed after 1 year (for example)
-      2) If a company is protected, protection is disabled after 3 years (for example)
-           (and item 1. happens a year later) */
-static void NetworkAutoCleanCompanies(void)
-{
-	const NetworkClientState *cs;
-	const NetworkClientInfo *ci;
-	const Player *p;
-	bool clients_in_company[MAX_PLAYERS];
-
-	if (!_network_autoclean_companies) return;
-
-	memset(clients_in_company, 0, sizeof(clients_in_company));
-
-	/* Detect the active companies */
-	FOR_ALL_CLIENTS(cs) {
-		ci = DEREF_CLIENT_INFO(cs);
-		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
-	}
-
-	if (!_network_dedicated) {
-		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
-	}
-
-	/* Go through all the comapnies */
-	FOR_ALL_PLAYERS(p) {
-		/* Skip the non-active once */
-		if (!p->is_active || p->is_ai) continue;
-
-		if (!clients_in_company[p->index]) {
-			/* The company is empty for one month more */
-			_network_player_info[p->index].months_empty++;
-
-			/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
-			if (_network_player_info[p->index].months_empty > _network_autoclean_unprotected && _network_player_info[p->index].password[0] == '\0') {
-				/* Shut the company down */
-				DoCommandP(0, 2, p->index, NULL, CMD_PLAYER_CTRL);
-				IConsolePrintF(_icolour_def, "Auto-cleaned company #%d", p->index + 1);
-			}
-			/* Is the compnay empty for autoclean_protected-months, and there is a protection? */
-			if (_network_player_info[p->index].months_empty > _network_autoclean_protected && _network_player_info[p->index].password[0] != '\0') {
-				/* Unprotect the company */
-				_network_player_info[p->index].password[0] = '\0';
-				IConsolePrintF(_icolour_def, "Auto-removed protection from company #%d", p->index+1);
-				_network_player_info[p->index].months_empty = 0;
-			}
-		} else {
-			/* It is not empty, reset the date */
-			_network_player_info[p->index].months_empty = 0;
-		}
-	}
-}
-
-// This function changes new_name to a name that is unique (by adding #1 ...)
-//  and it returns true if that succeeded.
-bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
-{
-	NetworkClientState *new_cs;
-	bool found_name = false;
-	byte number = 0;
-	char original_name[NETWORK_CLIENT_NAME_LENGTH];
-
-	// We use NETWORK_CLIENT_NAME_LENGTH in here, because new_name is really a pointer
-	ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
-
-	while (!found_name) {
-		const NetworkClientInfo *ci;
-
-		found_name = true;
-		FOR_ALL_CLIENTS(new_cs) {
-			ci = DEREF_CLIENT_INFO(new_cs);
-			if (strcmp(ci->client_name, new_name) == 0) {
-				// Name already in use
-				found_name = false;
-				break;
-			}
-		}
-		// Check if it is the same as the server-name
-		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (ci != NULL) {
-			if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use
-		}
-
-		if (!found_name) {
-			// Try a new name (<name> #1, <name> #2, and so on)
-
-			// Stop if we tried for more than 50 times..
-			if (number++ > 50) break;
-			snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
-		}
-	}
-
-	return found_name;
-}
-
-// Reads a packet from the stream
-bool NetworkServer_ReadPackets(NetworkClientState *cs)
-{
-	Packet *p;
-	NetworkRecvStatus res;
-	while ((p = NetworkRecv_Packet(cs, &res)) != NULL) {
-		byte type = NetworkRecv_uint8(cs, p);
-		if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->has_quit) {
-			_network_server_packet[type](cs, p);
-		} else {
-			DEBUG(net, 0, "[server] received invalid packet type %d", type);
-		}
-		free(p);
-	}
-
-	return true;
-}
-
-// Handle the local command-queue
-static void NetworkHandleCommandQueue(NetworkClientState* cs)
-{
-	CommandPacket *cp;
-
-	while ( (cp = cs->command_queue) != NULL) {
-		SEND_COMMAND(PACKET_SERVER_COMMAND)(cs, cp);
-
-		cs->command_queue = cp->next;
-		free(cp);
-	}
-}
-
-// This is called every tick if this is a _network_server
-void NetworkServer_Tick(bool send_frame)
-{
-	NetworkClientState *cs;
-#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
-	bool send_sync = false;
-#endif
-
-#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
-	if (_frame_counter >= _last_sync_frame + _network_sync_freq) {
-		_last_sync_frame = _frame_counter;
-		send_sync = true;
-	}
-#endif
-
-	// Now we are done with the frame, inform the clients that they can
-	//  do their frame!
-	FOR_ALL_CLIENTS(cs) {
-		// Check if the speed of the client is what we can expect from a client
-		if (cs->status == STATUS_ACTIVE) {
-			// 1 lag-point per day
-			int lag = NetworkCalculateLag(cs) / DAY_TICKS;
-			if (lag > 0) {
-				if (lag > 3) {
-					// Client did still not report in after 4 game-day, drop him
-					//  (that is, the 3 of above, + 1 before any lag is counted)
-					IConsolePrintF(_icolour_err,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->index);
-					NetworkCloseClient(cs);
-					continue;
-				}
-
-				// Report once per time we detect the lag
-				if (cs->lag_test == 0) {
-					IConsolePrintF(_icolour_warn,"[%d] Client #%d is slow, try increasing *net_frame_freq to a higher value!", _frame_counter, cs->index);
-					cs->lag_test = 1;
-				}
-			} else {
-				cs->lag_test = 0;
-			}
-		} else if (cs->status == STATUS_PRE_ACTIVE) {
-			int lag = NetworkCalculateLag(cs);
-			if (lag > _network_max_join_time) {
-				IConsolePrintF(_icolour_err,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->index, _network_max_join_time);
-				NetworkCloseClient(cs);
-			}
-		}
-
-		if (cs->status >= STATUS_PRE_ACTIVE) {
-			// Check if we can send command, and if we have anything in the queue
-			NetworkHandleCommandQueue(cs);
-
-			// Send an updated _frame_counter_max to the client
-			if (send_frame) SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
-
-#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
-			// Send a sync-check packet
-			if (send_sync) SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
-#endif
-		}
-	}
-
-	/* See if we need to advertise */
-	NetworkUDPAdvertise();
-}
-
-void NetworkServerYearlyLoop(void)
-{
-	NetworkCheckRestartMap();
-}
-
-void NetworkServerMonthlyLoop(void)
-{
-	NetworkAutoCleanCompanies();
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_server.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_SERVER_H
-#define NETWORK_SERVER_H
-
-#ifdef ENABLE_NETWORK
-
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP);
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno);
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error);
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN);
-DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME);
-DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command);
-
-bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]);
-void NetworkServer_HandleChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index);
-
-bool NetworkServer_ReadPackets(NetworkClientState *cs);
-void NetworkServer_Tick(bool send_frame);
-void NetworkServerMonthlyLoop(void);
-void NetworkServerYearlyLoop(void);
-
-static inline const char* GetPlayerIP(const NetworkClientInfo* ci)
-{
-	struct in_addr addr;
-
-	addr.s_addr = ci->client_ip;
-	return inet_ntoa(addr);
-}
-
-#else /* ENABLE_NETWORK */
-/* Network function stubs when networking is disabled */
-
-static inline void NetworkServerMonthlyLoop(void) {}
-static inline void NetworkServerYearlyLoop(void) {}
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_SERVER_H */
--- a/network_udp.c	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,892 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "debug.h"
-#include "string.h"
-#include "network_data.h"
-#include "date.h"
-#include "map.h"
-#include "network_gamelist.h"
-#include "network_udp.h"
-#include "variables.h"
-#include "newgrf_config.h"
-
-//
-// This file handles all the LAN-stuff
-// Stuff like:
-//   - UDP search over the network
-//
-
-typedef enum {
-	PACKET_UDP_CLIENT_FIND_SERVER,
-	PACKET_UDP_SERVER_RESPONSE,
-	PACKET_UDP_CLIENT_DETAIL_INFO,
-	PACKET_UDP_SERVER_DETAIL_INFO,   // Is not used in OpenTTD itself, only for external querying
-	PACKET_UDP_SERVER_REGISTER,      // Packet to register itself to the master server
-	PACKET_UDP_MASTER_ACK_REGISTER,  // Packet indicating registration has succedeed
-	PACKET_UDP_CLIENT_GET_LIST,      // Request for serverlist from master server
-	PACKET_UDP_MASTER_RESPONSE_LIST, // Response from master server with server ip's + port's
-	PACKET_UDP_SERVER_UNREGISTER,    // Request to be removed from the server-list
-	PACKET_UDP_CLIENT_GET_NEWGRFS,   // Requests the name for a list of GRFs (GRF_ID and MD5)
-	PACKET_UDP_SERVER_NEWGRFS,       // Sends the list of NewGRF's requested.
-	PACKET_UDP_END
-} PacketUDPType;
-
-enum {
-	ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
-	ADVERTISE_RETRY_INTERVAL  =   300, // readvertise when no response after this many ticks (9 seconds)
-	ADVERTISE_RETRY_TIMES     =     3  // give up readvertising after this much failed retries
-};
-
-#define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
-static void NetworkSendUDP_Packet(SOCKET udp, Packet* p, struct sockaddr_in* recv);
-
-static NetworkClientState _udp_cs;
-
-/**
- * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
- * @param p the packet to write the data to
- * @param c the configuration to write the GRF ID and MD5 checksum from
- */
-static void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c)
-{
-	uint j;
-	NetworkSend_uint32(p, c->grfid);
-	for (j = 0; j < sizeof(c->md5sum); j++) {
-		NetworkSend_uint8 (p, c->md5sum[j]);
-	}
-}
-
-/**
- * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
- * @param p the packet to read the data from
- * @param c the configuration to write the GRF ID and MD5 checksum to
- */
-static void NetworkRecv_GRFIdentifier(Packet *p, GRFConfig *c)
-{
-	uint j;
-	c->grfid = NetworkRecv_uint32(&_udp_cs, p);
-	for (j = 0; j < sizeof(c->md5sum); j++) {
-		c->md5sum[j] = NetworkRecv_uint8(&_udp_cs, p);
-	}
-}
-
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
-{
-	Packet *packet;
-	// Just a fail-safe.. should never happen
-	if (!_network_udp_server)
-		return;
-
-	packet = NetworkSend_Init(PACKET_UDP_SERVER_RESPONSE);
-
-	// Update some game_info
-	_network_game_info.game_date = _date;
-	_network_game_info.map_width = MapSizeX();
-	_network_game_info.map_height = MapSizeY();
-	_network_game_info.map_set = _opt.landscape;
-
-	NetworkSend_uint8 (packet, NETWORK_GAME_INFO_VERSION);
-
-	/* NETWORK_GAME_INFO_VERSION = 4 */
-	{
-		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
-		 * the GRFs that are needed, i.e. the ones that the server has
-		 * selected in the NewGRF GUI and not the ones that are used due
-		 * to the fact that they are in [newgrf-static] in openttd.cfg */
-		const GRFConfig *c;
-		uint i = 0;
-
-		/* Count number of GRFs to send information about */
-		for (c = _grfconfig; c != NULL; c = c->next) {
-			if (!HASBIT(c->flags, GCF_STATIC)) i++;
-		}
-		NetworkSend_uint8 (packet, i); // Send number of GRFs
-
-		/* Send actual GRF Identifications */
-		for (c = _grfconfig; c != NULL; c = c->next) {
-			if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(packet, c);
-		}
-	}
-
-	/* NETWORK_GAME_INFO_VERSION = 3 */
-	NetworkSend_uint32(packet, _network_game_info.game_date);
-	NetworkSend_uint32(packet, _network_game_info.start_date);
-
-	/* NETWORK_GAME_INFO_VERSION = 2 */
-	NetworkSend_uint8 (packet, _network_game_info.companies_max);
-	NetworkSend_uint8 (packet, ActivePlayerCount());
-	NetworkSend_uint8 (packet, _network_game_info.spectators_max);
-
-	/* NETWORK_GAME_INFO_VERSION = 1 */
-	NetworkSend_string(packet, _network_game_info.server_name);
-	NetworkSend_string(packet, _network_game_info.server_revision);
-	NetworkSend_uint8 (packet, _network_game_info.server_lang);
-	NetworkSend_uint8 (packet, _network_game_info.use_password);
-	NetworkSend_uint8 (packet, _network_game_info.clients_max);
-	NetworkSend_uint8 (packet, _network_game_info.clients_on);
-	NetworkSend_uint8 (packet, NetworkSpectatorCount());
-	NetworkSend_string(packet, _network_game_info.map_name);
-	NetworkSend_uint16(packet, _network_game_info.map_width);
-	NetworkSend_uint16(packet, _network_game_info.map_height);
-	NetworkSend_uint8 (packet, _network_game_info.map_set);
-	NetworkSend_uint8 (packet, _network_game_info.dedicated);
-
-	// Let the client know that we are here
-	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
-
-	free(packet);
-
-	DEBUG(net, 2, "[udp] queried from '%s'", inet_ntoa(client_addr->sin_addr));
-}
-
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
-{
-	extern const char _openttd_revision[];
-	NetworkGameList *item;
-	byte game_info_version;
-
-	// Just a fail-safe.. should never happen
-	if (_network_udp_server)
-		return;
-
-	game_info_version = NetworkRecv_uint8(&_udp_cs, p);
-
-	if (_udp_cs.has_quit) return;
-
-	DEBUG(net, 4, "[udp] server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
-
-	// Find next item
-	item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
-
-	item->info.compatible = true;
-	/* Please observer the order. In the order in which packets are sent
-	 * they are to be received */
-	switch (game_info_version) {
-		case 4: {
-			GRFConfig *c, **dst = &item->info.grfconfig;
-			const GRFConfig *f;
-			uint i;
-			uint num_grfs = NetworkRecv_uint8(&_udp_cs, p);
-
-			for (i = 0; i < num_grfs; i++) {
-				c = calloc(1, sizeof(*c));
-				NetworkRecv_GRFIdentifier(p, c);
-
-				/* Find the matching GRF file */
-				f = FindGRFConfig(c->grfid, c->md5sum);
-				if (f == NULL) {
-					/* Don't know the GRF, so mark game incompatible and the (possibly)
-					 * already resolved name for this GRF (another server has sent the
-					 * name of the GRF already */
-					item->info.compatible = false;
-					c->name     = FindUnknownGRFName(c->grfid, c->md5sum, true);
-					SETBIT(c->flags, GCF_NOT_FOUND);
-				} else {
-					c->filename = f->filename;
-					c->name     = f->name;
-					c->info     = f->info;
-				}
-				SETBIT(c->flags, GCF_COPY);
-
-				/* Append GRFConfig to the list */
-				*dst = c;
-				dst = &c->next;
-			}
-		} /* Fallthrough */
-		case 3:
-			item->info.game_date     = NetworkRecv_uint32(&_udp_cs, p);
-			item->info.start_date    = NetworkRecv_uint32(&_udp_cs, p);
-			/* Fallthrough */
-		case 2:
-			item->info.companies_max = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.companies_on = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.spectators_max = NetworkRecv_uint8(&_udp_cs, p);
-			/* Fallthrough */
-		case 1:
-			NetworkRecv_string(&_udp_cs, p, item->info.server_name, sizeof(item->info.server_name));
-			NetworkRecv_string(&_udp_cs, p, item->info.server_revision, sizeof(item->info.server_revision));
-			item->info.server_lang   = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.use_password  = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.clients_max   = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.clients_on    = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.spectators_on = NetworkRecv_uint8(&_udp_cs, p);
-			if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
-				item->info.game_date     = NetworkRecv_uint16(&_udp_cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
-				item->info.start_date    = NetworkRecv_uint16(&_udp_cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
-			}
-			NetworkRecv_string(&_udp_cs, p, item->info.map_name, sizeof(item->info.map_name));
-			item->info.map_width     = NetworkRecv_uint16(&_udp_cs, p);
-			item->info.map_height    = NetworkRecv_uint16(&_udp_cs, p);
-			item->info.map_set       = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.dedicated     = NetworkRecv_uint8(&_udp_cs, p);
-
-			if (item->info.server_lang >= NETWORK_NUM_LANGUAGES) item->info.server_lang = 0;
-			if (item->info.map_set >= NUM_LANDSCAPE ) item->info.map_set = 0;
-
-			if (item->info.hostname[0] == '\0')
-				snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
-
-			/* Check if we are allowed on this server based on the revision-match */
-			item->info.version_compatible =
-				strcmp(item->info.server_revision, _openttd_revision) == 0 ||
-				strcmp(item->info.server_revision, NOREV_STRING) == 0;
-			item->info.compatible &= item->info.version_compatible; // Already contains match for GRFs
-			break;
-	}
-
-	{
-		/* Checks whether there needs to be a request for names of GRFs and makes
-		 * the request if necessary. GRFs that need to be requested are the GRFs
-		 * that do not exist on the clients system and we do not have the name
-		 * resolved of, i.e. the name is still UNKNOWN_GRF_NAME_PLACEHOLDER.
-		 * The in_request array and in_request_count are used so there is no need
-		 * to do a second loop over the GRF list, which can be relatively expensive
-		 * due to the string comparisons. */
-		const GRFConfig *in_request[NETWORK_MAX_GRF_COUNT];
-		const GRFConfig *c;
-		uint in_request_count = 0;
-		struct sockaddr_in out_addr;
-
-		for (c = item->info.grfconfig; c != NULL; c = c->next) {
-			if (!HASBIT(c->flags, GCF_NOT_FOUND) || strcmp(c->name, UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
-			in_request[in_request_count] = c;
-			in_request_count++;
-		}
-
-		if (in_request_count > 0) {
-			/* There are 'unknown' GRFs, now send a request for them */
-			uint i;
-			Packet *packet = NetworkSend_Init(PACKET_UDP_CLIENT_GET_NEWGRFS);
-
-			NetworkSend_uint8 (packet, in_request_count);
-			for (i = 0; i < in_request_count; i++) {
-				NetworkSend_GRFIdentifier(packet, in_request[i]);
-			}
-
-			out_addr.sin_family      = AF_INET;
-			out_addr.sin_port        = htons(item->port);
-			out_addr.sin_addr.s_addr = item->ip;
-			NetworkSendUDP_Packet(_udp_client_socket, packet, &out_addr);
-			free(packet);
-		}
-	}
-
-	item->online = true;
-
-	UpdateNetworkGameWindow(false);
-}
-
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
-{
-	NetworkClientState *cs;
-	NetworkClientInfo *ci;
-	Packet *packet;
-	Player *player;
-	byte current = 0;
-	int i;
-
-	// Just a fail-safe.. should never happen
-	if (!_network_udp_server) return;
-
-	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
-
-	/* Send the amount of active companies */
-	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
-	NetworkSend_uint8 (packet, ActivePlayerCount());
-
-	/* Fetch the latest version of everything */
-	NetworkPopulateCompanyInfo();
-
-	/* Go through all the players */
-	FOR_ALL_PLAYERS(player) {
-		/* Skip non-active players */
-		if (!player->is_active) continue;
-
-		current++;
-
-		/* Send the information */
-		NetworkSend_uint8(packet, current);
-
-		NetworkSend_string(packet, _network_player_info[player->index].company_name);
-		NetworkSend_uint32(packet, _network_player_info[player->index].inaugurated_year);
-		NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
-		NetworkSend_uint64(packet, _network_player_info[player->index].money);
-		NetworkSend_uint64(packet, _network_player_info[player->index].income);
-		NetworkSend_uint16(packet, _network_player_info[player->index].performance);
-
-		/* Send 1 if there is a passord for the company else send 0 */
-		if (_network_player_info[player->index].password[0] != '\0') {
-			NetworkSend_uint8(packet, 1);
-		} else {
-			NetworkSend_uint8(packet, 0);
-		}
-
-		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
-			NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
-
-		for (i = 0; i < NETWORK_STATION_TYPES; i++)
-			NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
-
-		/* Find the clients that are connected to this player */
-		FOR_ALL_CLIENTS(cs) {
-			ci = DEREF_CLIENT_INFO(cs);
-			if (ci->client_playas == player->index) {
-				/* The uint8 == 1 indicates that a client is following */
-				NetworkSend_uint8(packet, 1);
-				NetworkSend_string(packet, ci->client_name);
-				NetworkSend_string(packet, ci->unique_id);
-				NetworkSend_uint32(packet, ci->join_date);
-			}
-		}
-		/* Also check for the server itself */
-		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (ci->client_playas == player->index) {
-			/* The uint8 == 1 indicates that a client is following */
-			NetworkSend_uint8(packet, 1);
-			NetworkSend_string(packet, ci->client_name);
-			NetworkSend_string(packet, ci->unique_id);
-			NetworkSend_uint32(packet, ci->join_date);
-		}
-
-		/* Indicates end of client list */
-		NetworkSend_uint8(packet, 0);
-	}
-
-	/* And check if we have any spectators */
-	FOR_ALL_CLIENTS(cs) {
-		ci = DEREF_CLIENT_INFO(cs);
-		if (!IsValidPlayer(ci->client_playas)) {
-			/* The uint8 == 1 indicates that a client is following */
-			NetworkSend_uint8(packet, 1);
-			NetworkSend_string(packet, ci->client_name);
-			NetworkSend_string(packet, ci->unique_id);
-			NetworkSend_uint32(packet, ci->join_date);
-		}
-	}
-
-	/* Also check for the server itself */
-	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-	if (!IsValidPlayer(ci->client_playas)) {
-		/* The uint8 == 1 indicates that a client is following */
-		NetworkSend_uint8(packet, 1);
-		NetworkSend_string(packet, ci->client_name);
-		NetworkSend_string(packet, ci->unique_id);
-		NetworkSend_uint32(packet, ci->join_date);
-	}
-
-	/* Indicates end of client list */
-	NetworkSend_uint8(packet, 0);
-
-	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
-
-	free(packet);
-}
-
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST)
-{
-	int i;
-	struct in_addr ip;
-	uint16 port;
-	uint8 ver;
-
-	/* packet begins with the protocol version (uint8)
-	 * then an uint16 which indicates how many
-	 * ip:port pairs are in this packet, after that
-	 * an uint32 (ip) and an uint16 (port) for each pair
-	 */
-
-	ver = NetworkRecv_uint8(&_udp_cs, p);
-
-	if (_udp_cs.has_quit) return;
-
-	if (ver == 1) {
-		for (i = NetworkRecv_uint16(&_udp_cs, p); i != 0 ; i--) {
-			ip.s_addr = TO_LE32(NetworkRecv_uint32(&_udp_cs, p));
-			port = NetworkRecv_uint16(&_udp_cs, p);
-			NetworkUDPQueryServer(inet_ntoa(ip), port);
-		}
-	}
-}
-
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER)
-{
-	_network_advertise_retries = 0;
-	DEBUG(net, 2, "[udp] advertising on master server successfull");
-
-	/* We are advertised, but we don't want to! */
-	if (!_network_advertise) NetworkUDPRemoveAdvertise();
-}
-
-/**
- * A client has requested the names of some NewGRFs.
- *
- * Replying this can be tricky as we have a limit of SEND_MTU bytes
- * in the reply packet and we can send up to 100 bytes per NewGRF
- * (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name).
- * As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
- * could be that a packet overflows. To stop this we only reply
- * with the first N NewGRFs so that if the first N + 1 NewGRFs
- * would be sent, the packet overflows.
- * in_reply and in_reply_count are used to keep a list of GRFs to
- * send in the reply.
- */
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS)
-{
-	uint8 num_grfs;
-	uint i;
-
-	const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT];
-	Packet *packet;
-	uint8 in_reply_count = 0;
-	uint packet_len = 0;
-
-	/* Just a fail-safe.. should never happen */
-	if (_udp_cs.has_quit) return;
-
-	DEBUG(net, 6, "[udp] newgrf data request from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));
-
-	num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
-	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
-
-	for (i = 0; i < num_grfs; i++) {
-		GRFConfig c;
-		const GRFConfig *f;
-
-		NetworkRecv_GRFIdentifier(p, &c);
-
-		/* Find the matching GRF file */
-		f = FindGRFConfig(c.grfid, c.md5sum);
-		if (f == NULL) continue; // The GRF is unknown to this server
-
-		/* If the reply might exceed the size of the packet, only reply
-		 * the current list and do not send the other data.
-		 * The name could be an empty string, if so take the filename. */
-		packet_len += sizeof(c.grfid) + sizeof(c.md5sum) +
-				min(strlen((f->name != NULL && strlen(f->name) > 0) ? f->name : f->filename) + 1, NETWORK_GRF_NAME_LENGTH);
-		if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply
-			break;
-		}
-		in_reply[in_reply_count] = f;
-		in_reply_count++;
-	}
-
-	if (in_reply_count == 0) return;
-
-	packet = NetworkSend_Init(PACKET_UDP_SERVER_NEWGRFS);
-	NetworkSend_uint8 (packet, in_reply_count);
-	for (i = 0; i < in_reply_count; i++) {
-		char name[NETWORK_GRF_NAME_LENGTH];
-
-		/* The name could be an empty string, if so take the filename */
-		ttd_strlcpy(name, (in_reply[i]->name != NULL && strlen(in_reply[i]->name) > 0) ?
-				in_reply[i]->name : in_reply[i]->filename, sizeof(name));
-	 	NetworkSend_GRFIdentifier(packet, in_reply[i]);
-		NetworkSend_string(packet, name);
-	}
-
-	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
-	free(packet);
-}
-
-/** The return of the client's request of the names of some NewGRFs */
-DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS)
-{
-	uint8 num_grfs;
-	uint i;
-
-	/* Just a fail-safe.. should never happen */
-	if (_udp_cs.has_quit) return;
-
-	DEBUG(net, 6, "[udp] newgrf data reply from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
-
-	num_grfs = NetworkRecv_uint8 (&_udp_cs, p);
-	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
-
-	for (i = 0; i < num_grfs; i++) {
-		char *unknown_name;
-		char name[NETWORK_GRF_NAME_LENGTH];
-		GRFConfig c;
-
-		NetworkRecv_GRFIdentifier(p, &c);
-		NetworkRecv_string(&_udp_cs, p, name, sizeof(name));
-
-		/* An empty name is not possible under normal circumstances
-		 * and causes problems when showing the NewGRF list. */
-		if (strlen(name) == 0) continue;
-
-		/* Finds the fake GRFConfig for the just read GRF ID and MD5sum tuple.
-		 * If it exists and not resolved yet, then name of the fake GRF is
-		 * overwritten with the name from the reply. */
-		unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
-		if (unknown_name != NULL && strcmp(unknown_name, UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
-			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
-		}
-	}
-}
-
-
-// The layout for the receive-functions by UDP
-typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
-
-static NetworkUDPPacket* const _network_udp_packet[] = {
-	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
-	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
-	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
-	NULL,
-	NULL,
-	RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER),
-	NULL,
-	RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST),
-	NULL,
-	RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS),
-	RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS),
-};
-
-
-// If this fails, check the array above with network_data.h
-assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
-
-
-static void NetworkHandleUDPPacket(Packet* p, struct sockaddr_in* client_addr)
-{
-	byte type;
-
-	/* Fake a client, so we can see when there is an illegal packet */
-	_udp_cs.socket = INVALID_SOCKET;
-	_udp_cs.has_quit = false;
-
-	type = NetworkRecv_uint8(&_udp_cs, p);
-
-	if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.has_quit) {
-		_network_udp_packet[type](p, client_addr);
-	} else {
-		if (!_udp_cs.has_quit) {
-			DEBUG(net, 0, "[udp] received invalid packet type %d", type);
-		} else {
-			DEBUG(net, 0, "[udp] received illegal packet");
-		}
-	}
-}
-
-
-// Send a packet over UDP
-static void NetworkSendUDP_Packet(SOCKET udp, Packet* p, struct sockaddr_in* recv)
-{
-	int res;
-
-	// Put the length in the buffer
-	p->buffer[0] = p->size & 0xFF;
-	p->buffer[1] = p->size >> 8;
-
-	// Send the buffer
-	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
-
-	// Check for any errors, but ignore it otherwise
-	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
-}
-
-// Start UDP listener
-bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
-{
-	struct sockaddr_in sin;
-
-	// Make sure socket is closed
-	closesocket(*udp);
-
-	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	if (*udp == INVALID_SOCKET) {
-		DEBUG(net, 0, "[udp] failed to start UDP listener");
-		return false;
-	}
-
-	// set nonblocking mode for socket
-	{
-		unsigned long blocking = 1;
-#ifndef BEOS_NET_SERVER
-		ioctlsocket(*udp, FIONBIO, &blocking);
-#else
-		setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL);
-#endif
-	}
-
-	sin.sin_family = AF_INET;
-	// Listen on all IPs
-	sin.sin_addr.s_addr = host;
-	sin.sin_port = htons(port);
-
-	if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
-		DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
-		return false;
-	}
-
-	if (broadcast) {
-		/* Enable broadcast */
-		unsigned long val = 1;
-#ifndef BEOS_NET_SERVER // will work around this, some day; maybe.
-		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
-#endif
-	}
-
-	DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
-
-	return true;
-}
-
-// Close UDP connection
-void NetworkUDPClose(void)
-{
-	DEBUG(net, 1, "[udp] closed listeners");
-
-	if (_network_udp_server) {
-		if (_udp_server_socket != INVALID_SOCKET) {
-			closesocket(_udp_server_socket);
-			_udp_server_socket = INVALID_SOCKET;
-		}
-
-		if (_udp_master_socket != INVALID_SOCKET) {
-			closesocket(_udp_master_socket);
-			_udp_master_socket = INVALID_SOCKET;
-		}
-
-		_network_udp_server = false;
-		_network_udp_broadcast = 0;
-	} else {
-		if (_udp_client_socket != INVALID_SOCKET) {
-			closesocket(_udp_client_socket);
-			_udp_client_socket = INVALID_SOCKET;
-		}
-		_network_udp_broadcast = 0;
-	}
-}
-
-// Receive something on UDP level
-void NetworkUDPReceive(SOCKET udp)
-{
-	struct sockaddr_in client_addr;
-	socklen_t client_len;
-	int nbytes;
-	static Packet *p = NULL;
-	int packet_len;
-
-	// If p is NULL, malloc him.. this prevents unneeded mallocs
-	if (p == NULL) p = malloc(sizeof(*p));
-
-	packet_len = sizeof(p->buffer);
-	client_len = sizeof(client_addr);
-
-	// Try to receive anything
-	nbytes = recvfrom(udp, p->buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
-
-	// We got some bytes.. just asume we receive the whole packet
-	if (nbytes > 0) {
-		// Get the size of the buffer
-		p->size = (uint16)p->buffer[0];
-		p->size += (uint16)p->buffer[1] << 8;
-		// Put the position on the right place
-		p->pos = 2;
-		p->next = NULL;
-
-		// Handle the packet
-		NetworkHandleUDPPacket(p, &client_addr);
-
-		// Free the packet
-		free(p);
-		p = NULL;
-	}
-}
-
-// Broadcast to all ips
-static void NetworkUDPBroadCast(SOCKET udp)
-{
-	Packet* p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
-	uint i;
-
-	for (i = 0; _broadcast_list[i] != 0; i++) {
-		struct sockaddr_in out_addr;
-
-		out_addr.sin_family = AF_INET;
-		out_addr.sin_port = htons(_network_server_port);
-		out_addr.sin_addr.s_addr = _broadcast_list[i];
-
-		DEBUG(net, 4, "[udp] broadcasting to %s", inet_ntoa(out_addr.sin_addr));
-
-		NetworkSendUDP_Packet(udp, p, &out_addr);
-	}
-
-	free(p);
-}
-
-
-// Request the the server-list from the master server
-void NetworkUDPQueryMasterServer(void)
-{
-	struct sockaddr_in out_addr;
-	Packet *p;
-
-	if (_udp_client_socket == INVALID_SOCKET)
-		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
-			return;
-
-	p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
-
-	out_addr.sin_family = AF_INET;
-	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
-	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
-
-	// packet only contains protocol version
-	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
-
-	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
-
-	DEBUG(net, 2, "[udp] master server queried at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
-
-	free(p);
-}
-
-// Find all servers
-void NetworkUDPSearchGame(void)
-{
-	// We are still searching..
-	if (_network_udp_broadcast > 0) return;
-
-	// No UDP-socket yet..
-	if (_udp_client_socket == INVALID_SOCKET)
-		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
-			return;
-
-	DEBUG(net, 0, "[udp] searching server");
-
-	NetworkUDPBroadCast(_udp_client_socket);
-	_network_udp_broadcast = 300; // Stay searching for 300 ticks
-}
-
-NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
-{
-	struct sockaddr_in out_addr;
-	Packet *p;
-	NetworkGameList *item;
-
-	// No UDP-socket yet..
-	if (_udp_client_socket == INVALID_SOCKET)
-		if (!NetworkUDPListen(&_udp_client_socket, 0, 0, true))
-			return NULL;
-
-	out_addr.sin_family = AF_INET;
-	out_addr.sin_port = htons(port);
-	out_addr.sin_addr.s_addr = NetworkResolveHost(host);
-
-	// Clear item in gamelist
-	item = NetworkGameListAddItem(inet_addr(inet_ntoa(out_addr.sin_addr)), ntohs(out_addr.sin_port));
-	memset(&item->info, 0, sizeof(item->info));
-	ttd_strlcpy(item->info.server_name, host, lengthof(item->info.server_name));
-	ttd_strlcpy(item->info.hostname, host, lengthof(item->info.hostname));
-	item->online = false;
-
-	// Init the packet
-	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
-
-	NetworkSendUDP_Packet(_udp_client_socket, p, &out_addr);
-
-	free(p);
-
-	UpdateNetworkGameWindow(false);
-	return item;
-}
-
-/* Remove our advertise from the master-server */
-void NetworkUDPRemoveAdvertise(void)
-{
-	struct sockaddr_in out_addr;
-	Packet *p;
-
-	/* Check if we are advertising */
-	if (!_networking || !_network_server || !_network_udp_server) return;
-
-	/* check for socket */
-	if (_udp_master_socket == INVALID_SOCKET)
-		if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
-			return;
-
-	DEBUG(net, 1, "[udp] removing advertise from master server");
-
-	/* Find somewhere to send */
-	out_addr.sin_family = AF_INET;
-	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
-	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
-
-	/* Send the packet */
-	p = NetworkSend_Init(PACKET_UDP_SERVER_UNREGISTER);
-	/* Packet is: Version, server_port */
-	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
-	NetworkSend_uint16(p, _network_server_port);
-	NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
-
-	free(p);
-}
-
-/* Register us to the master server
-     This function checks if it needs to send an advertise */
-void NetworkUDPAdvertise(void)
-{
-	struct sockaddr_in out_addr;
-	Packet *p;
-
-	/* Check if we should send an advertise */
-	if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
-		return;
-
-	/* check for socket */
-	if (_udp_master_socket == INVALID_SOCKET)
-		if (!NetworkUDPListen(&_udp_master_socket, _network_server_bind_ip, 0, false))
-			return;
-
-	if (_network_need_advertise) {
-		_network_need_advertise = false;
-		_network_advertise_retries = ADVERTISE_RETRY_TIMES;
-	} else {
-		/* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */
-		if (_network_advertise_retries == 0) {
-			if ((_network_last_advertise_frame + ADVERTISE_NORMAL_INTERVAL) > _frame_counter)
-				return;
-			_network_advertise_retries = ADVERTISE_RETRY_TIMES;
-		}
-
-		if ((_network_last_advertise_frame + ADVERTISE_RETRY_INTERVAL) > _frame_counter)
-			return;
-	}
-
-	_network_advertise_retries--;
-	_network_last_advertise_frame = _frame_counter;
-
-	/* Find somewhere to send */
-	out_addr.sin_family = AF_INET;
-	out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
-	out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
-
-	DEBUG(net, 1, "[udp] advertising to master server");
-
-	/* Send the packet */
-	p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
-	/* Packet is: WELCOME_MESSAGE, Version, server_port */
-	NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
-	NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
-	NetworkSend_uint16(p, _network_server_port);
-	NetworkSendUDP_Packet(_udp_master_socket, p, &out_addr);
-
-	free(p);
-}
-
-void NetworkUDPInitialize(void)
-{
-	_udp_client_socket = INVALID_SOCKET;
-	_udp_server_socket = INVALID_SOCKET;
-	_udp_master_socket = INVALID_SOCKET;
-
-	_network_udp_server = false;
-	_network_udp_broadcast = 0;
-}
-
-#endif /* ENABLE_NETWORK */
--- a/network_udp.h	Tue Jan 02 12:52:29 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/* $Id$ */
-
-#ifndef NETWORK_UDP_H
-#define NETWORK_UDP_H
-
-#ifdef ENABLE_NETWORK
-
-void NetworkUDPInitialize(void);
-bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast);
-void NetworkUDPReceive(SOCKET udp);
-void NetworkUDPSearchGame(void);
-void NetworkUDPQueryMasterServer(void);
-NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port);
-void NetworkUDPAdvertise(void);
-void NetworkUDPRemoveAdvertise(void);
-
-#endif /* ENABLE_NETWORK */
-
-#endif /* NETWORK_UDP_H */
--- a/newgrf_config.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/newgrf_config.c	Tue Jan 02 17:34:03 2007 +0000
@@ -9,7 +9,7 @@
 #include "string.h"
 #include "saveload.h"
 #include "md5.h"
-#include "network_data.h"
+#include "network/network_data.h"
 #include "newgrf.h"
 #include "newgrf_config.h"
 
--- a/npf.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/npf.c	Tue Jan 02 17:34:03 2007 +0000
@@ -14,7 +14,7 @@
 #include "tile.h"
 #include "depot.h"
 #include "tunnel_map.h"
-#include "network.h"
+#include "network/network.h"
 #include "water_map.h"
 
 static AyStar _npf_aystar;
--- a/oldloader.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/oldloader.c	Tue Jan 02 17:34:03 2007 +0000
@@ -16,7 +16,7 @@
 #include "signs.h"
 #include "debug.h"
 #include "depot.h"
-#include "network.h"
+#include "network/network.h"
 #include "ai/ai.h"
 #include "date.h"
 
--- a/openttd.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/openttd.c	Tue Jan 02 17:34:03 2007 +0000
@@ -41,7 +41,7 @@
 #include "airport.h"
 #include "console.h"
 #include "screenshot.h"
-#include "network.h"
+#include "network/network.h"
 #include "signs.h"
 #include "depot.h"
 #include "waypoint.h"
--- a/openttd.vcproj	Tue Jan 02 12:52:29 2007 +0000
+++ b/openttd.vcproj	Tue Jan 02 17:34:03 2007 +0000
@@ -292,22 +292,31 @@
 				RelativePath=".\namegen.c">
 			</File>
 			<File
-				RelativePath=".\network.c">
-			</File>
-			<File
-				RelativePath=".\network_client.c">
+				RelativePath=".\network\core\packet.c">
 			</File>
 			<File
-				RelativePath=".\network_data.c">
+				RelativePath=".\network\core\tcp.c">
 			</File>
 			<File
-				RelativePath=".\network_gamelist.c">
+				RelativePath=".\network\core\udp.c">
 			</File>
 			<File
-				RelativePath=".\network_server.c">
+				RelativePath=".\network\network.c">
 			</File>
 			<File
-				RelativePath=".\network_udp.c">
+				RelativePath=".\network\network_client.c">
+			</File>
+			<File
+				RelativePath=".\network\network_data.c">
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.c">
+			</File>
+			<File
+				RelativePath=".\network\network_server.c">
+			</File>
+			<File
+				RelativePath=".\network\network_udp.c">
 			</File>
 			<File
 				RelativePath=".\newgrf.c">
@@ -542,22 +551,37 @@
 				RelativePath=".\music.h">
 			</File>
 			<File
-				RelativePath=".\network.h">
-			</File>
-			<File
-				RelativePath=".\network_client.h">
+				RelativePath=".\network\core\config.h">
 			</File>
 			<File
-				RelativePath=".\network_core.h">
+				RelativePath=".\network\core\game.h">
 			</File>
 			<File
-				RelativePath=".\network_data.h">
+				RelativePath=".\network\core\os_abstraction.h">
 			</File>
 			<File
-				RelativePath=".\network_gamelist.h">
+				RelativePath=".\network\core\packet.h">
 			</File>
 			<File
-				RelativePath=".\network_gui.h">
+				RelativePath=".\network\core\tcp.h">
+			</File>
+			<File
+				RelativePath=".\network\core\udp.h">
+			</File>
+			<File
+				RelativePath=".\network\network.h">
+			</File>
+			<File
+				RelativePath=".\network\network_client.h">
+			</File>
+			<File
+				RelativePath=".\network\network_data.h">
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.h">
+			</File>
+			<File
+				RelativePath=".\network\network_gui.h">
 			</File>
 			<File
 				RelativePath=".\network_server.h">
--- a/openttd_vs80.vcproj	Tue Jan 02 12:52:29 2007 +0000
+++ b/openttd_vs80.vcproj	Tue Jan 02 17:34:03 2007 +0000
@@ -653,27 +653,39 @@
 				>
 			</File>
 			<File
-				RelativePath=".\network.c"
-				>
-			</File>
-			<File
-				RelativePath=".\network_client.c"
+				RelativePath=".\network\core\packet.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_data.c"
+				RelativePath=".\network\core\tcp.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_gamelist.c"
+				RelativePath=".\network\core\udp.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_server.c"
+				RelativePath=".\network\network.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_udp.c"
+				RelativePath=".\network\network_client.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_data.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_server.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_udp.c"
 				>
 			</File>
 			<File
@@ -1036,35 +1048,55 @@
 				>
 			</File>
 			<File
-				RelativePath=".\network.h"
-				>
-			</File>
-			<File
-				RelativePath=".\network_client.h"
-				>
-			</File>
-			<File
-				RelativePath=".\network_core.h"
+				RelativePath=".\networe\core\config.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_data.h"
-				>
-			</File>
-			<File
-				RelativePath=".\network_gamelist.h"
+				RelativePath=".\network\core\game.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_gui.h"
+				RelativePath=".\network\core\os_abstraction.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_server.h"
+				RelativePath=".\network\core\packet.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_udp.h"
+				RelativePath=".\network\core\tcp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\core\udp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_client.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_data.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gui.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_server.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_udp.h"
 				>
 			</File>
 			<File
--- a/player_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/player_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -13,13 +13,13 @@
 #include "command.h"
 #include "vehicle.h"
 #include "economy.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "train.h"
 #include "date.h"
 #include "newgrf.h"
-#include "network_data.h"
-#include "network_client.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
 
 static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied);
 
--- a/players.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/players.c	Tue Jan 02 17:34:03 2007 +0000
@@ -21,7 +21,7 @@
 #include "saveload.h"
 #include "command.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "engine.h"
 #include "ai/ai.h"
--- a/saveload.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/saveload.c	Tue Jan 02 17:34:03 2007 +0000
@@ -26,7 +26,7 @@
 #include "town.h"
 #include "player.h"
 #include "saveload.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include <setjmp.h>
 
@@ -1042,7 +1042,6 @@
 //********** START OF MEMORY CODE (in ram)****
 //********************************************
 
-#include "network.h"
 #include "table/strings.h"
 #include "table/sprites.h"
 #include "gfx.h"
--- a/settings.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/settings.c	Tue Jan 02 17:34:03 2007 +0000
@@ -28,7 +28,7 @@
 #include "sound.h"
 #include "string.h"
 #include "variables.h"
-#include "network.h"
+#include "network/network.h"
 #include "settings.h"
 #include "command.h"
 #include "console.h"
--- a/settings_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/settings_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -15,7 +15,7 @@
 #include "engine.h"
 #include "screenshot.h"
 #include "newgrf.h"
-#include "network.h"
+#include "network/network.h"
 #include "town.h"
 #include "variables.h"
 #include "settings.h"
--- a/town_gui.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/town_gui.c	Tue Jan 02 17:34:03 2007 +0000
@@ -14,7 +14,7 @@
 #include "gui.h"
 #include "command.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 
 static const Widget _town_authority_widgets[] = {
--- a/vehicle.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/vehicle.c	Tue Jan 02 17:34:03 2007 +0000
@@ -30,7 +30,7 @@
 #include "industry_map.h"
 #include "station_map.h"
 #include "water_map.h"
-#include "network.h"
+#include "network/network.h"
 #include "yapf/yapf.h"
 #include "date.h"
 #include "newgrf_engine.h"
--- a/video/cocoa_v.m	Tue Jan 02 12:52:29 2007 +0000
+++ b/video/cocoa_v.m	Tue Jan 02 17:34:03 2007 +0000
@@ -54,7 +54,7 @@
 #include "../macros.h"
 #include "../sdl.h"
 #include "../window.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "../os/macosx/splash.h"
 
--- a/video/dedicated_v.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/video/dedicated_v.c	Tue Jan 02 17:34:03 2007 +0000
@@ -8,7 +8,7 @@
 #include "../debug.h"
 #include "../functions.h"
 #include "../gfx.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../window.h"
 #include "../console.h"
 #include "../variables.h"
--- a/video/sdl_v.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/video/sdl_v.c	Tue Jan 02 17:34:03 2007 +0000
@@ -11,7 +11,7 @@
 #include "../macros.h"
 #include "../sdl.h"
 #include "../window.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "sdl_v.h"
 #include <SDL.h>
--- a/video/win32_v.c	Tue Jan 02 12:52:29 2007 +0000
+++ b/video/win32_v.c	Tue Jan 02 17:34:03 2007 +0000
@@ -5,7 +5,7 @@
 #include "../functions.h"
 #include "../gfx.h"
 #include "../macros.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "../win32.h"
 #include "../window.h"