@@ -705,192 +705,193 @@ void NetworkRebuildHostList()
{
_network_host_list.Clear();
for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
if (item->manually) *_network_host_list.Append() = strdup(item->address.GetAddressAsString(false));
}
/** Non blocking connection create to actually connect to servers */
class TCPClientConnecter : TCPConnecter {
public:
TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
virtual void OnFailure()
NetworkError(STR_NETWORK_ERROR_NOCONNECTION);
virtual void OnConnect(SOCKET s)
_networking = true;
NetworkAllocClient(s);
IConsoleCmdExec("exec scripts/on_client.scr 0");
NetworkClient_Connected();
};
/* Used by clients, to connect to a server */
void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password, const char *join_company_password)
if (!_network_available) return;
if (address.GetPort() == 0) return;
strecpy(_settings_client.network.last_host, address.GetHostname(), lastof(_settings_client.network.last_host));
_settings_client.network.last_port = address.GetPort();
_network_join_as = join_as;
_network_join_server_password = join_server_password;
_network_join_company_password = join_company_password;
NetworkDisconnect();
NetworkInitialize();
_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
ShowJoinStatusWindow();
new TCPClientConnecter(address);
static void NetworkInitGameInfo()
if (StrEmpty(_settings_client.network.server_name)) {
snprintf(_settings_client.network.server_name, sizeof(_settings_client.network.server_name), "Unnamed Server");
/* The server is a client too */
_network_game_info.clients_on = _network_dedicated ? 0 : 1;
NetworkClientInfo *ci = new NetworkClientInfo(CLIENT_ID_SERVER);
ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : _local_company;
/* Give the server a valid IP; banning it is pointless anyways */
sockaddr_in sock;
memset(&sock, 0, sizeof(sock));
sock.sin_family = AF_INET;
ci->client_address = NetworkAddress((sockaddr*)&sock, sizeof(sock));
strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name));
strecpy(ci->unique_id, _settings_client.network.network_id, lastof(ci->unique_id));
bool NetworkServerStart()
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");
if (!NetworkListen()) return false;
/* Try to start UDP-server */
_network_udp_server = _udp_server_socket->Listen();
_network_company_states = CallocT<NetworkCompanyState>(MAX_COMPANIES);
_network_server = true;
_frame_counter = 0;
_frame_counter_server = 0;
_frame_counter_max = 0;
_last_sync_frame = 0;
_network_own_client_id = CLIENT_ID_SERVER;
_network_clients_connected = 0;
_network_company_passworded = 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");
/* 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()
if (_network_server) {
NetworkClientSocket *cs;
FOR_ALL_CLIENT_SOCKETS(cs) {
SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
cs->Send_Packets();
NetworkClose();
/**
* We want to disconnect from the host/clients.
* @param blocking whether to wait till everything has been closed
*/
void NetworkDisconnect(bool blocking)
SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(blocking);
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
/* Receives something from the network */
static bool NetworkReceive()
fd_set read_fd, write_fd;
struct timeval tv;
FD_ZERO(&read_fd);
FD_ZERO(&write_fd);
FD_SET(cs->sock, &read_fd);
FD_SET(cs->sock, &write_fd);
/* take care of listener port */
for (SocketList::iterator s = _listensockets.Begin(); s != _listensockets.End(); s++) {
FD_SET(s->second, &read_fd);
tv.tv_sec = tv.tv_usec = 0; // don't block at all.
#if !defined(__MORPHOS__) && !defined(__AMIGA__)
int n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
#else
int n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
#endif
if (n == -1 && !_network_server) NetworkError(STR_NETWORK_ERROR_LOSTCONNECTION);
/* accept clients.. */
if (FD_ISSET(s->second, &read_fd)) NetworkAcceptClients(s->second);
/* read stuff from clients */
cs->writable = !!FD_ISSET(cs->sock, &write_fd);
if (FD_ISSET(cs->sock, &read_fd)) {
NetworkServer_ReadPackets(cs);
} else {
NetworkRecvStatus res;
/* The client already was quiting! */
if (cs->HasClientQuit()) return false;
Status change: