Changeset - r25800:5bcbdca2efaf
[Not reviewed]
master
0 9 4
Patric Stout - 3 years ago 2021-07-03 09:04:32
truebrain@openttd.org
Add: use Game Coordinator to annouce public servers
13 files changed with 569 insertions and 39 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -1986,25 +1986,25 @@ STR_FACE_LIPS                           
 
STR_FACE_MOUSTACHE                                              :Moustache:
 
STR_FACE_LIPS_MOUSTACHE_TOOLTIP                                 :{BLACK}Change lips or moustache
 
STR_FACE_CHIN                                                   :Chin:
 
STR_FACE_CHIN_TOOLTIP                                           :{BLACK}Change chin
 
STR_FACE_JACKET                                                 :Jacket:
 
STR_FACE_JACKET_TOOLTIP                                         :{BLACK}Change jacket
 
STR_FACE_COLLAR                                                 :Collar:
 
STR_FACE_COLLAR_TOOLTIP                                         :{BLACK}Change collar
 
STR_FACE_TIE                                                    :Tie:
 
STR_FACE_EARRING                                                :Earring:
 
STR_FACE_TIE_EARRING_TOOLTIP                                    :{BLACK}Change tie or earring
 

	
 
STR_NETWORK_SERVER_VISIBILITY_PRIVATE                           :Private
 
STR_NETWORK_SERVER_VISIBILITY_LOCAL                             :Local
 
STR_NETWORK_SERVER_VISIBILITY_PUBLIC                            :Public
 

	
 
# Network server list
 
STR_NETWORK_SERVER_LIST_CAPTION                                 :{WHITE}Multiplayer
 
STR_NETWORK_SERVER_LIST_PLAYER_NAME                             :{BLACK}Player name:
 
STR_NETWORK_SERVER_LIST_ENTER_NAME_TOOLTIP                      :{BLACK}This is the name other players will identify you by
 

	
 
STR_NETWORK_SERVER_LIST_GAME_NAME                               :{BLACK}Name
 
STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP                       :{BLACK}Name of the game
 
STR_NETWORK_SERVER_LIST_GENERAL_ONLINE                          :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA}
 
STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION                         :{BLACK}Clients
 
STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP                 :{BLACK}Clients online / clients max{}Companies online / companies max
 
@@ -2127,42 +2127,50 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTIO
 
# Network company list added strings
 
STR_NETWORK_COMPANY_LIST_CLIENT_LIST                            :Online players
 

	
 
# Network client list
 
STR_NETWORK_CLIENT_LIST_CAPTION                                 :{WHITE}Multiplayer
 
STR_NETWORK_CLIENT_LIST_SERVER                                  :{BLACK}Server
 
STR_NETWORK_CLIENT_LIST_SERVER_NAME                             :{BLACK}Name
 
STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP                     :{BLACK}Name of the server you are playing on
 
STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP                :{BLACK}Edit the name of your server
 
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION               :Name of the server
 
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY                       :{BLACK}Visibility
 
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP               :{BLACK}Whether other people can see your server in the public listing
 
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE                  :{BLACK}Connection type
 
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP          :{BLACK}Whether and how your server can be reached by others
 
STR_NETWORK_CLIENT_LIST_PLAYER                                  :{BLACK}Player
 
STR_NETWORK_CLIENT_LIST_PLAYER_NAME                             :{BLACK}Name
 
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP                     :{BLACK}Your player name
 
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP                :{BLACK}Edit your player name
 
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION               :Your player name
 
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP                    :{BLACK}Administrative actions to perform for this client
 
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP                   :{BLACK}Administrative actions to perform for this company
 
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP                            :{BLACK}Join this company
 
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP                     :{BLACK}Send a message to this player
 
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP                    :{BLACK}Send a message to all players of this company
 
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP                  :{BLACK}Send a message to all spectators
 
STR_NETWORK_CLIENT_LIST_SPECTATORS                              :Spectators
 
STR_NETWORK_CLIENT_LIST_NEW_COMPANY                             :(New company)
 
STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP                     :{BLACK}Create a new company and join it
 
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP                :{BLACK}This is you
 
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP                :{BLACK}This is the host of the game
 
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT                    :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies}
 

	
 
############ Begin of ConnectionType
 
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN          :{BLACK}Local
 
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED         :{RED}Remote players can't connect
 
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT           :{BLACK}Public
 
############ End of ConnectionType
 

	
 
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK                       :Kick
 
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN                        :Ban
 
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET                     :Delete
 
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK                    :Password unlock
 

	
 
STR_NETWORK_CLIENT_LIST_ASK_CAPTION                             :{WHITE}Admin action
 
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK                         :{YELLOW}Are you sure you want to kick player '{RAW_STRING}'?
 
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN                          :{YELLOW}Are you sure you want to ban player '{RAW_STRING}'?
 
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET                       :{YELLOW}Are you sure you want to delete company '{COMPANY}'?
 
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK                      :{YELLOW}Are you sure you want to reset the password of company '{COMPANY}'?
 

	
 
STR_NETWORK_SERVER                                              :Server
 
@@ -2272,24 +2280,28 @@ STR_NETWORK_MESSAGE_CLIENT_LEAVING      
 
STR_NETWORK_MESSAGE_CLIENT_JOINED                               :*** {RAW_STRING} has joined the game
 
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID                            :*** {RAW_STRING} has joined the game (Client #{2:NUM})
 
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN                         :*** {RAW_STRING} has joined company #{2:NUM}
 
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE                     :*** {RAW_STRING} has joined spectators
 
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW                          :*** {RAW_STRING} has started a new company (#{2:NUM})
 
STR_NETWORK_MESSAGE_CLIENT_LEFT                                 :*** {RAW_STRING} has left the game ({2:STRING})
 
STR_NETWORK_MESSAGE_NAME_CHANGE                                 :*** {RAW_STRING} has changed their name to {RAW_STRING}
 
STR_NETWORK_MESSAGE_GIVE_MONEY                                  :*** {RAW_STRING} gave {2:CURRENCY_LONG} to {1:RAW_STRING}
 
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN                             :{WHITE}The server closed the session
 
STR_NETWORK_MESSAGE_SERVER_REBOOT                               :{WHITE}The server is restarting...{}Please wait...
 
STR_NETWORK_MESSAGE_KICKED                                      :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING})
 

	
 
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED               :{WHITE}Server registration failed
 
STR_NETWORK_ERROR_COORDINATOR_ISOLATED                          :{WHITE}Your server doesn't allow remote connections
 
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL                   :{WHITE}Other players won't be able to connect to your server
 

	
 
# Content downloading window
 
STR_CONTENT_TITLE                                               :{WHITE}Content downloading
 
STR_CONTENT_TYPE_CAPTION                                        :{BLACK}Type
 
STR_CONTENT_TYPE_CAPTION_TOOLTIP                                :{BLACK}Type of the content
 
STR_CONTENT_NAME_CAPTION                                        :{BLACK}Name
 
STR_CONTENT_NAME_CAPTION_TOOLTIP                                :{BLACK}Name of the content
 
STR_CONTENT_MATRIX_TOOLTIP                                      :{BLACK}Click on a line to see the details{}Click on the checkbox to select it for downloading
 
STR_CONTENT_SELECT_ALL_CAPTION                                  :{BLACK}Select all
 
STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP                          :{BLACK}Mark all content to be downloaded
 
STR_CONTENT_SELECT_UPDATES_CAPTION                              :{BLACK}Select upgrades
 
STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP                      :{BLACK}Mark all content that is an upgrade for existing content to be downloaded
 
STR_CONTENT_UNSELECT_ALL_CAPTION                                :{BLACK}Unselect all
src/network/CMakeLists.txt
Show inline comments
 
@@ -5,24 +5,26 @@ add_files(
 
    network.h
 
    network_admin.cpp
 
    network_admin.h
 
    network_base.h
 
    network_chat_gui.cpp
 
    network_client.cpp
 
    network_client.h
 
    network_command.cpp
 
    network_content.cpp
 
    network_content.h
 
    network_content_gui.cpp
 
    network_content_gui.h
 
    network_coordinator.cpp
 
    network_coordinator.h
 
    network_func.h
 
    network_gamelist.cpp
 
    network_gamelist.h
 
    network_gui.cpp
 
    network_gui.h
 
    network_internal.h
 
    network_server.cpp
 
    network_server.h
 
    network_type.h
 
    network_udp.cpp
 
    network_udp.h
 
)
src/network/core/CMakeLists.txt
Show inline comments
 
@@ -11,20 +11,22 @@ add_files(
 
    os_abstraction.cpp
 
    os_abstraction.h
 
    packet.cpp
 
    packet.h
 
    tcp.cpp
 
    tcp.h
 
    tcp_admin.cpp
 
    tcp_admin.h
 
    tcp_connect.cpp
 
    tcp_content.cpp
 
    tcp_content.h
 
    tcp_content_type.h
 
    tcp_coordinator.cpp
 
    tcp_coordinator.h
 
    tcp_game.cpp
 
    tcp_game.h
 
    tcp_http.cpp
 
    tcp_http.h
 
    tcp_listen.h
 
    udp.cpp
 
    udp.h
 
)
src/network/core/config.h
Show inline comments
 
@@ -5,89 +5,94 @@
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * @file config.h Configuration options of the network stuff. It is used even when compiling without network support.
 
 */
 

	
 
#ifndef NETWORK_CORE_CONFIG_H
 
#define NETWORK_CORE_CONFIG_H
 

	
 
/** DNS hostname of the masterserver */
 
static const char * const NETWORK_MASTER_SERVER_HOST            = "master.openttd.org";
 
/** DNS hostname of the Game Coordinator server */
 
static const char * const NETWORK_COORDINATOR_SERVER_HOST       = "coordinator.openttd.org";
 
/** DNS hostname of the content server */
 
static const char * const NETWORK_CONTENT_SERVER_HOST           = "content.openttd.org";
 
/** DNS hostname of the HTTP-content mirror server */
 
static const char * const NETWORK_CONTENT_MIRROR_HOST           = "binaries.openttd.org";
 
/** URL of the HTTP mirror system */
 
static const char * const NETWORK_CONTENT_MIRROR_URL            = "/bananas";
 
/** Message sent to the masterserver to 'identify' this client as OpenTTD */
 
static const char * const NETWORK_MASTER_SERVER_WELCOME_MESSAGE = "OpenTTDRegister";
 

	
 
static const uint16 NETWORK_MASTER_SERVER_PORT    = 3978;         ///< The default port of the master server (UDP)
 
static const uint16 NETWORK_CONTENT_SERVER_PORT   = 3978;         ///< The default port of the content server (TCP)
 
static const uint16 NETWORK_CONTENT_MIRROR_PORT   =   80;         ///< The default port of the content mirror (TCP)
 
static const uint16 NETWORK_DEFAULT_PORT          = 3979;         ///< The default port of the game server (TCP & UDP)
 
static const uint16 NETWORK_ADMIN_PORT            = 3977;         ///< The default port for admin network
 
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982;         ///< The default port debug-log is sent to (TCP)
 
static const uint16 NETWORK_MASTER_SERVER_PORT      = 3978;           ///< The default port of the master server (UDP)
 
static const uint16 NETWORK_COORDINATOR_SERVER_PORT = 3976;           ///< The default port of the Game Coordinator server (TCP)
 
static const uint16 NETWORK_CONTENT_SERVER_PORT     = 3978;           ///< The default port of the content server (TCP)
 
static const uint16 NETWORK_CONTENT_MIRROR_PORT     =   80;           ///< The default port of the content mirror (TCP)
 
static const uint16 NETWORK_DEFAULT_PORT            = 3979;           ///< The default port of the game server (TCP & UDP)
 
static const uint16 NETWORK_ADMIN_PORT              = 3977;           ///< The default port for admin network
 
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT   = 3982;           ///< The default port debug-log is sent to (TCP)
 

	
 
static const uint16 UDP_MTU                       = 1460;         ///< Number of bytes we can pack in a single UDP packet
 
static const uint16 UDP_MTU                         = 1460;           ///< Number of bytes we can pack in a single UDP packet
 
/*
 
 * Technically a TCP packet could become 64kiB, however the high bit is kept so it becomes possible in the future
 
 * to go to (significantly) larger packets if needed. This would entail a strategy such as employed for UTF-8.
 
 *
 
 * Packets up to 32 KiB have the high bit not set:
 
 * 00000000 00000000 0bbbbbbb aaaaaaaa -> aaaaaaaa 0bbbbbbb
 
 * Send_uint16(GB(size, 0, 15)
 
 *
 
 * Packets up to 1 GiB, first uint16 has high bit set so it knows to read a
 
 * next uint16 for the remaining bits of the size.
 
 * 00dddddd cccccccc bbbbbbbb aaaaaaaa -> cccccccc 10dddddd aaaaaaaa bbbbbbbb
 
 * Send_uint16(GB(size, 16, 14) | 0b10 << 14)
 
 * Send_uint16(GB(size,  0, 16))
 
 */
 
static const uint16 TCP_MTU                       = 32767;        ///< Number of bytes we can pack in a single TCP packet
 
static const uint16 COMPAT_MTU                    = 1460;         ///< Number of bytes we can pack in a single packet for backward compatibility
 
static const uint16 TCP_MTU                         = 32767;          ///< Number of bytes we can pack in a single TCP packet
 
static const uint16 COMPAT_MTU                      = 1460;           ///< Number of bytes we can pack in a single packet for backward compatibility
 

	
 
static const byte NETWORK_GAME_ADMIN_VERSION      =    1;         ///< What version of the admin network do we use?
 
static const byte NETWORK_GAME_INFO_VERSION       =    4;         ///< What version of game-info do we use?
 
static const byte NETWORK_COMPANY_INFO_VERSION    =    6;         ///< What version of company info is this?
 
static const byte NETWORK_MASTER_SERVER_VERSION   =    2;         ///< What version of master-server-protocol do we use?
 
static const byte NETWORK_GAME_ADMIN_VERSION        =    1;           ///< What version of the admin network do we use?
 
static const byte NETWORK_GAME_INFO_VERSION         =    4;           ///< What version of game-info do we use?
 
static const byte NETWORK_COMPANY_INFO_VERSION      =    6;           ///< What version of company info is this?
 
static const byte NETWORK_MASTER_SERVER_VERSION     =    2;           ///< What version of master-server-protocol do we use?
 
static const byte NETWORK_COORDINATOR_VERSION       =    1;           ///< What version of game-coordinator-protocol do we use?
 

	
 
static const uint NETWORK_NAME_LENGTH             =   80;         ///< The maximum length of the server name and map name, in bytes including '\0'
 
static const uint NETWORK_COMPANY_NAME_LENGTH     =  128;         ///< The maximum length of the company name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_LENGTH         =   80;         ///< The maximum length of the host name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_PORT_LENGTH    =   80 + 6;     ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
 
static const uint NETWORK_SERVER_ID_LENGTH        =   33;         ///< The maximum length of the network id of the servers, in bytes including '\0'
 
static const uint NETWORK_REVISION_LENGTH         =   33;         ///< The maximum length of the revision, in bytes including '\0'
 
static const uint NETWORK_PASSWORD_LENGTH         =   33;         ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
 
static const uint NETWORK_CLIENTS_LENGTH          =  200;         ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
 
static const uint NETWORK_CLIENT_NAME_LENGTH      =   25;         ///< The maximum length of a client's name, in bytes including '\0'
 
static const uint NETWORK_RCONCOMMAND_LENGTH      =  500;         ///< The maximum length of a rconsole command, in bytes including '\0'
 
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH  = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
 
static const uint NETWORK_CHAT_LENGTH             =  900;         ///< The maximum length of a chat message, in bytes including '\0'
 
static const uint NETWORK_CONTENT_FILENAME_LENGTH =   48;         ///< The maximum length of a content's filename, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_NAME_LENGTH     =   32;         ///< The maximum length of a content's name, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_VERSION_LENGTH  =   16;         ///< The maximum length of a content's version, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_URL_LENGTH      =   96;         ///< The maximum length of a content's url, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_DESC_LENGTH     =  512;         ///< The maximum length of a content's description, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_TAG_LENGTH      =   32;         ///< The maximum length of a content's tag, in bytes including '\0'.
 
static const uint NETWORK_NAME_LENGTH               =   80;           ///< The maximum length of the server name and map name, in bytes including '\0'
 
static const uint NETWORK_COMPANY_NAME_LENGTH       =  128;           ///< The maximum length of the company name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_LENGTH           =   80;           ///< The maximum length of the host name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_PORT_LENGTH      =   80 + 6;       ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
 
static const uint NETWORK_SERVER_ID_LENGTH          =   33;           ///< The maximum length of the network id of the servers, in bytes including '\0'
 
static const uint NETWORK_REVISION_LENGTH           =   33;           ///< The maximum length of the revision, in bytes including '\0'
 
static const uint NETWORK_PASSWORD_LENGTH           =   33;           ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
 
static const uint NETWORK_CLIENTS_LENGTH            =  200;           ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
 
static const uint NETWORK_CLIENT_NAME_LENGTH        =   25;           ///< The maximum length of a client's name, in bytes including '\0'
 
static const uint NETWORK_RCONCOMMAND_LENGTH        =  500;           ///< The maximum length of a rconsole command, in bytes including '\0'
 
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH    = COMPAT_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
 
static const uint NETWORK_CHAT_LENGTH               =  900;           ///< The maximum length of a chat message, in bytes including '\0'
 
static const uint NETWORK_CONTENT_FILENAME_LENGTH   =   48;           ///< The maximum length of a content's filename, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_NAME_LENGTH       =   32;           ///< The maximum length of a content's name, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_VERSION_LENGTH    =   16;           ///< The maximum length of a content's version, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_URL_LENGTH        =   96;           ///< The maximum length of a content's url, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_DESC_LENGTH       =  512;           ///< The maximum length of a content's description, in bytes including '\0'.
 
static const uint NETWORK_CONTENT_TAG_LENGTH        =   32;           ///< The maximum length of a content's tag, in bytes including '\0'.
 
static const uint NETWORK_ERROR_DETAIL_LENGTH        = 100;           ///< The maximum length of the error detail, in bytes including '\0'
 

	
 
static const uint NETWORK_GRF_NAME_LENGTH         =   80;         ///< Maximum length of the name of a GRF
 
static const uint NETWORK_GRF_NAME_LENGTH           =   80;           ///< Maximum length of the name of a GRF
 

	
 
/**
 
 * Maximum number of GRFs that can be sent.
 
 * This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of UDP_MTU bytes.
 
 */
 
static const uint NETWORK_MAX_GRF_COUNT           =   62;
 
static const uint NETWORK_MAX_GRF_COUNT             =   62;
 

	
 
/**
 
 * The number of landscapes in OpenTTD.
 
 * This number must be equal to NUM_LANDSCAPE, but as this number is used
 
 * within the network code and that the network code is shared with the
 
 * masterserver/updater, it has to be declared in here too. In network.cpp
 
 * there is a compile assertion to check that this NUM_LANDSCAPE is equal
 
 * to NETWORK_NUM_LANDSCAPES.
 
 */
 
static const uint NETWORK_NUM_LANDSCAPES          =    4;
 
static const uint NETWORK_NUM_LANDSCAPES            =    4;
 

	
 
#endif /* NETWORK_CORE_CONFIG_H */
src/network/core/tcp_coordinator.cpp
Show inline comments
 
new file 100644
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * @file tcp_coordinator.cpp Basic functions to receive and send Game Coordinator packets.
 
 */
 

	
 
#include "../../stdafx.h"
 
#include "../../date_func.h"
 
#include "../../debug.h"
 
#include "tcp_coordinator.h"
 

	
 
#include "../../safeguards.h"
 

	
 
/**
 
 * Handle the given packet, i.e. pass it to the right.
 
 * parser receive command.
 
 * @param p The packet to handle.
 
 * @return True iff we should immediately handle further packets.
 
 */
 
bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *p)
 
{
 
	PacketCoordinatorType type = (PacketCoordinatorType)p->Recv_uint8();
 

	
 
	switch (type) {
 
		case PACKET_COORDINATOR_GC_ERROR:        return this->Receive_GC_ERROR(p);
 
		case PACKET_COORDINATOR_SERVER_REGISTER: return this->Receive_SERVER_REGISTER(p);
 
		case PACKET_COORDINATOR_GC_REGISTER_ACK: return this->Receive_GC_REGISTER_ACK(p);
 
		case PACKET_COORDINATOR_SERVER_UPDATE:   return this->Receive_SERVER_UPDATE(p);
 

	
 
		default:
 
			Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type);
 
			return false;
 
	}
 
}
 

	
 
/**
 
 * Receive a packet at TCP level.
 
 * @return Whether at least one packet was received.
 
 */
 
bool NetworkCoordinatorSocketHandler::ReceivePackets()
 
{
 
	/*
 
	 * We read only a few of the packets. This allows the GUI to update when
 
	 * a large set of servers is being received. Otherwise the interface
 
	 * "hangs" while the game is updating the server-list.
 
	 *
 
	 * What arbitrary number to choose is the ultimate question though.
 
	 */
 
	Packet *p;
 
	static const int MAX_PACKETS_TO_RECEIVE = 42;
 
	int i = MAX_PACKETS_TO_RECEIVE;
 
	while (--i != 0 && (p = this->ReceivePacket()) != nullptr) {
 
		bool cont = this->HandlePacket(p);
 
		delete p;
 
		if (!cont) return true;
 
	}
 

	
 
	return i != MAX_PACKETS_TO_RECEIVE - 1;
 
}
 

	
 
/**
 
 * Helper for logging receiving invalid packets.
 
 * @param type The received packet type.
 
 * @return Always false, as it's an error.
 
 */
 
bool NetworkCoordinatorSocketHandler::ReceiveInvalidPacket(PacketCoordinatorType type)
 
{
 
	Debug(net, 0, "[tcp/coordinator] Received illegal packet type {}", type);
 
	return false;
 
}
 

	
 
bool NetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_ERROR); }
 
bool NetworkCoordinatorSocketHandler::Receive_SERVER_REGISTER(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERVER_REGISTER); }
 
bool NetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_REGISTER_ACK); }
 
bool NetworkCoordinatorSocketHandler::Receive_SERVER_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERVER_UPDATE); }
src/network/core/tcp_coordinator.h
Show inline comments
 
new file 100644
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * @file tcp_coordinator.h Basic functions to receive and send TCP packets to/from the Game Coordinator server.
 
 */
 

	
 
#ifndef NETWORK_CORE_TCP_COORDINATOR_H
 
#define NETWORK_CORE_TCP_COORDINATOR_H
 

	
 
#include "os_abstraction.h"
 
#include "tcp.h"
 
#include "packet.h"
 
#include "game_info.h"
 

	
 
/**
 
 * Enum with all types of TCP Game Coordinator packets. The order MUST not be changed.
 
 *
 
 * GC     -> packets from Game Coordinator to either Client or Server.
 
 * SERVER -> packets from Server to Game Coordinator.
 
 * CLIENT -> packets from Client to Game Coordinator.
 
 **/
 
enum PacketCoordinatorType {
 
	PACKET_COORDINATOR_GC_ERROR,        ///< Game Coordinator indicates there was an error.
 
	PACKET_COORDINATOR_SERVER_REGISTER, ///< Server registration.
 
	PACKET_COORDINATOR_GC_REGISTER_ACK, ///< Game Coordinator accepts the registration.
 
	PACKET_COORDINATOR_SERVER_UPDATE,   ///< Server sends an set intervals an update of the server.
 
	PACKET_COORDINATOR_END,             ///< Must ALWAYS be on the end of this list!! (period).
 
};
 

	
 
/**
 
 * The type of connection the Game Coordinator can detect we have.
 
 */
 
enum ConnectionType {
 
	CONNECTION_TYPE_UNKNOWN,  ///< The Game Coordinator hasn't informed us yet what type of connection we have.
 
	CONNECTION_TYPE_ISOLATED, ///< The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
 
	CONNECTION_TYPE_DIRECT,   ///< The Game Coordinator can directly connect to your server.
 
};
 

	
 
/**
 
 * The type of error from the Game Coordinator.
 
 */
 
enum NetworkCoordinatorErrorType {
 
	NETWORK_COORDINATOR_ERROR_UNKNOWN,             ///< There was an unknown error.
 
	NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED, ///< Your request for registration failed.
 
};
 

	
 
/** Base socket handler for all Game Coordinator TCP sockets. */
 
class NetworkCoordinatorSocketHandler : public NetworkTCPSocketHandler {
 
protected:
 
	bool ReceiveInvalidPacket(PacketCoordinatorType type);
 

	
 
	/**
 
	 * Game Coordinator indicates there was an error. This can either be a
 
	 * permanent error causing the connection to be dropped, or in response
 
	 * to a request that is invalid.
 
	 *
 
	 *  uint8   Type of error (see NetworkCoordinatorErrorType).
 
	 *  string  Details of the error.
 
	 *
 
	 * @param p The packet that was just received.
 
	 * @return True upon success, otherwise false.
 
	 */
 
	virtual bool Receive_GC_ERROR(Packet *p);
 

	
 
	/**
 
	 * Server is starting a multiplayer game and wants to let the
 
	 * Game Coordinator know.
 
	 *
 
	 *  uint8   Game Coordinator protocol version.
 
	 *  uint8   Type of game (see ServerGameType).
 
	 *  uint16  Local port of the server.
 
	 *
 
	 * @param p The packet that was just received.
 
	 * @return True upon success, otherwise false.
 
	 */
 
	virtual bool Receive_SERVER_REGISTER(Packet *p);
 

	
 
	/**
 
	 * Game Coordinator acknowledges the registration.
 
	 *
 
	 *  uint8   Type of connection was detected (see ConnectionType).
 
	 *
 
	 * @param p The packet that was just received.
 
	 * @return True upon success, otherwise false.
 
	 */
 
	virtual bool Receive_GC_REGISTER_ACK(Packet *p);
 

	
 
	/**
 
	 * Send an update of the current state of the server to the Game Coordinator.
 
	 *
 
	 *  uint8   Game Coordinator protocol version.
 
	 *  Serialized NetworkGameInfo. See game_info.hpp for details.
 
	 *
 
	 * @param p The packet that was just received.
 
	 * @return True upon success, otherwise false.
 
	 */
 
	virtual bool Receive_SERVER_UPDATE(Packet *p);
 

	
 
	bool HandlePacket(Packet *p);
 
public:
 
	/**
 
	 * Create a new cs socket handler for a given cs.
 
	 * @param s The socket we are connected with.
 
	 */
 
	NetworkCoordinatorSocketHandler(SOCKET s = INVALID_SOCKET) : NetworkTCPSocketHandler(s) {}
 

	
 
	bool ReceivePackets();
 
};
 

	
 
#endif /* NETWORK_CORE_TCP_COORDINATOR_H */
src/network/network.cpp
Show inline comments
 
@@ -10,24 +10,25 @@
 
#include "../stdafx.h"
 

	
 
#include "../strings_func.h"
 
#include "../command_func.h"
 
#include "../date_func.h"
 
#include "network_admin.h"
 
#include "network_client.h"
 
#include "network_server.h"
 
#include "network_content.h"
 
#include "network_udp.h"
 
#include "network_gamelist.h"
 
#include "network_base.h"
 
#include "network_coordinator.h"
 
#include "core/udp.h"
 
#include "core/host.h"
 
#include "network_gui.h"
 
#include "../console_func.h"
 
#include "../3rdparty/md5/md5.h"
 
#include "../core/random_func.hpp"
 
#include "../window_func.h"
 
#include "../company_func.h"
 
#include "../company_base.h"
 
#include "../landscape_type.h"
 
#include "../rev.h"
 
#include "../core/pool_func.hpp"
 
@@ -582,24 +583,26 @@ void NetworkClose(bool close_admins)
 
	if (_network_server) {
 
		if (close_admins) {
 
			for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) {
 
				as->CloseConnection(true);
 
			}
 
		}
 

	
 
		for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
 
			cs->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
 
		}
 
		ServerNetworkGameSocketHandler::CloseListeners();
 
		ServerNetworkAdminSocketHandler::CloseListeners();
 

	
 
		_network_coordinator_client.CloseConnection();
 
	} else if (MyClient::my_client != nullptr) {
 
		MyClient::SendQuit();
 
		MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
 
	}
 

	
 
	TCPConnecter::KillAll();
 

	
 
	_networking = false;
 
	_network_server = false;
 

	
 
	NetworkFreeLocalCommandQueue();
 

	
 
@@ -923,24 +926,28 @@ bool NetworkServerStart()
 
	_networking = 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();
 

	
 
	if (_settings_client.network.server_advertise) {
 
		_network_coordinator_client.Register();
 
	}
 

	
 
	/* 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_need_advertise = true;
 
	NetworkUDPAdvertise();
 

	
 
	/* welcome possibly still connected admins - this can only happen on a dedicated server. */
 
	if (_network_dedicated) ServerNetworkAdminSocketHandler::WelcomeAll();
 

	
 
@@ -1023,24 +1030,25 @@ static void NetworkSend()
 
		ClientNetworkGameSocketHandler::Send();
 
	}
 
}
 

	
 
/**
 
 * We have to do some (simple) background stuff that runs normally,
 
 * even when we are not in multiplayer. For example stuff needed
 
 * for finding servers or downloading content.
 
 */
 
void NetworkBackgroundLoop()
 
{
 
	_network_content_client.SendReceive();
 
	_network_coordinator_client.SendReceive();
 
	TCPConnecter::CheckCallbacks();
 
	NetworkHTTPSocketHandler::HTTPReceive();
 

	
 
	NetworkBackgroundUDPLoop();
 
}
 

	
 
/* The main loop called from ttd.c
 
 *  Here we also have to do StateGameLoop if needed! */
 
void NetworkGameLoop()
 
{
 
	if (!_networking) return;
 

	
src/network/network_coordinator.cpp
Show inline comments
 
new file 100644
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file network_coordinator.cpp Game Coordinator sending/receiving part of the network protocol. */
 

	
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../error.h"
 
#include "../rev.h"
 
#include "../settings_type.h"
 
#include "../strings_func.h"
 
#include "../window_func.h"
 
#include "../window_type.h"
 
#include "network.h"
 
#include "network_coordinator.h"
 
#include "network_gamelist.h"
 
#include "table/strings.h"
 

	
 
#include "../safeguards.h"
 

	
 
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES = std::chrono::seconds(30); ///< How many time between updates the server sends to the Game Coordinator.
 
ClientNetworkCoordinatorSocketHandler _network_coordinator_client; ///< The connection to the Game Coordinator.
 
ConnectionType _network_server_connection_type = CONNECTION_TYPE_UNKNOWN; ///< What type of connection the Game Coordinator detected we are on.
 

	
 
/** Connect to the Game Coordinator server. */
 
class NetworkCoordinatorConnecter : TCPConnecter {
 
public:
 
	/**
 
	 * Initiate the connecting.
 
	 * @param address The address of the Game Coordinator server.
 
	 */
 
	NetworkCoordinatorConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_COORDINATOR_SERVER_PORT) {}
 

	
 
	void OnFailure() override
 
	{
 
		_network_coordinator_client.connecting = false;
 
		_network_coordinator_client.CloseConnection(true);
 
	}
 

	
 
	void OnConnect(SOCKET s) override
 
	{
 
		assert(_network_coordinator_client.sock == INVALID_SOCKET);
 

	
 
		_network_coordinator_client.sock = s;
 
		_network_coordinator_client.connecting = false;
 
	}
 
};
 

	
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
 
{
 
	NetworkCoordinatorErrorType error = (NetworkCoordinatorErrorType)p->Recv_uint8();
 
	std::string detail = p->Recv_string(NETWORK_ERROR_DETAIL_LENGTH);
 

	
 
	switch (error) {
 
		case NETWORK_COORDINATOR_ERROR_UNKNOWN:
 
			this->CloseConnection();
 
			return false;
 

	
 
		case NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED:
 
			SetDParamStr(0, detail);
 
			ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
 

	
 
			/* To prevent that we constantly try to reconnect, switch to private game. */
 
			_settings_client.network.server_advertise = false;
 

	
 
			this->CloseConnection();
 
			return false;
 

	
 
		default:
 
			Debug(net, 0, "Invalid error type {} received from Game Coordinator", error);
 
			this->CloseConnection();
 
			return false;
 
	}
 
}
 

	
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p)
 
{
 
	/* Schedule sending an update. */
 
	this->next_update = std::chrono::steady_clock::now();
 

	
 
	_network_server_connection_type = (ConnectionType)p->Recv_uint8();
 

	
 
	if (_network_server_connection_type == CONNECTION_TYPE_ISOLATED) {
 
		ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_ISOLATED, STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL, WL_ERROR);
 
	}
 

	
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	if (_network_dedicated) {
 
		std::string connection_type;
 
		switch (_network_server_connection_type) {
 
			case CONNECTION_TYPE_ISOLATED: connection_type = "Remote players can't connect"; break;
 
			case CONNECTION_TYPE_DIRECT:   connection_type = "Public"; break;
 

	
 
			case CONNECTION_TYPE_UNKNOWN: // Never returned from Game Coordinator.
 
			default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
 
		}
 

	
 
		Debug(net, 3, "----------------------------------------");
 
		Debug(net, 3, "Your server is now registered with the Game Coordinator:");
 
		Debug(net, 3, "  Game type:       Public");
 
		Debug(net, 3, "  Connection type: {}", connection_type);
 
		Debug(net, 3, "----------------------------------------");
 
	}
 

	
 
	return true;
 
}
 

	
 
void ClientNetworkCoordinatorSocketHandler::Connect()
 
{
 
	/* We are either already connected or are trying to connect. */
 
	if (this->sock != INVALID_SOCKET || this->connecting) return;
 

	
 
	this->Reopen();
 

	
 
	this->connecting = true;
 
	new NetworkCoordinatorConnecter(NETWORK_COORDINATOR_SERVER_HOST);
 
}
 

	
 
NetworkRecvStatus ClientNetworkCoordinatorSocketHandler::CloseConnection(bool error)
 
{
 
	NetworkCoordinatorSocketHandler::CloseConnection(error);
 

	
 
	this->CloseSocket();
 
	this->connecting = false;
 

	
 
	_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
 
	this->next_update = {};
 

	
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
/**
 
 * Register our server to receive our join-key.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::Register()
 
{
 
	_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
 
	this->next_update = {};
 

	
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	this->Connect();
 

	
 
	Packet *p = new Packet(PACKET_COORDINATOR_SERVER_REGISTER);
 
	p->Send_uint8(NETWORK_COORDINATOR_VERSION);
 
	p->Send_uint8(SERVER_GAME_TYPE_PUBLIC);
 
	p->Send_uint16(_settings_client.network.server_port);
 

	
 
	this->SendPacket(p);
 
}
 

	
 
/**
 
 * Send an update of our server status to the Game Coordinator.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
 
{
 
	Debug(net, 6, "Sending server update to Game Coordinator");
 
	this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
 

	
 
	Packet *p = new Packet(PACKET_COORDINATOR_SERVER_UPDATE);
 
	p->Send_uint8(NETWORK_COORDINATOR_VERSION);
 
	SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo());
 

	
 
	this->SendPacket(p);
 
}
 

	
 
/**
 
 * Check whether we received/can send some data from/to the Game Coordinator server and
 
 * when that's the case handle it appropriately.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::SendReceive()
 
{
 
	/* Private games are not listed via the Game Coordinator. */
 
	if (_network_server && !_settings_client.network.server_advertise) {
 
		if (this->sock != INVALID_SOCKET) {
 
			this->CloseConnection();
 
		}
 
		return;
 
	}
 

	
 
	static int last_attempt_backoff = 1;
 
	static bool first_reconnect = true;
 

	
 
	if (this->sock == INVALID_SOCKET) {
 
		static std::chrono::steady_clock::time_point last_attempt = {};
 

	
 
		/* Don't auto-reconnect when we are not a server. */
 
		if (!_network_server) return;
 
		/* Don't reconnect if we are connecting. */
 
		if (this->connecting) return;
 
		/* Throttle how often we try to reconnect. */
 
		if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff) return;
 

	
 
		last_attempt = std::chrono::steady_clock::now();
 
		/* Delay reconnecting with up to 32 seconds. */
 
		if (last_attempt_backoff < 32) {
 
			last_attempt_backoff *= 2;
 
		}
 

	
 
		/* Do not reconnect on the first attempt, but only initialize the
 
		 * last_attempt variables.  Otherwise after an outage all servers
 
		 * reconnect at the same time, potentially overwhelming the
 
		 * Game Coordinator. */
 
		if (first_reconnect) {
 
			first_reconnect = false;
 
			return;
 
		}
 

	
 
		Debug(net, 1, "Connection with Game Coordinator lost; reconnecting...");
 
		this->Register();
 
		return;
 
	}
 

	
 
	last_attempt_backoff = 1;
 
	first_reconnect = true;
 

	
 
	if (_network_server && _network_server_connection_type != CONNECTION_TYPE_UNKNOWN && std::chrono::steady_clock::now() > this->next_update) {
 
		this->SendServerUpdate();
 
	}
 

	
 
	if (this->CanSendReceive()) {
 
		this->ReceivePackets();
 
	}
 

	
 
	this->SendPackets();
 
}
src/network/network_coordinator.h
Show inline comments
 
new file 100644
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file network_coordinator.h Part of the network protocol handling Game Coordinator requests. */
 

	
 
#ifndef NETWORK_COORDINATOR_H
 
#define NETWORK_COORDINATOR_H
 

	
 
#include "core/tcp_coordinator.h"
 

	
 
/**
 
 * Game Coordinator communication.
 
 *
 
 * For servers:
 
 *  - Server sends SERVER_REGISTER.
 
 *  - Game Coordinator probes server to check if it can directly connect.
 
 *  - Game Coordinator sends GC_REGISTER_ACK with type of connection.
 
 *  - Server sends every 30 seconds SERVER_UPDATE.
 
 */
 

	
 
/** Class for handling the client side of the Game Coordinator connection. */
 
class ClientNetworkCoordinatorSocketHandler : public NetworkCoordinatorSocketHandler {
 
private:
 
	std::chrono::steady_clock::time_point next_update; ///< When to send the next update (if server and public).
 

	
 
protected:
 
	bool Receive_GC_ERROR(Packet *p) override;
 
	bool Receive_GC_REGISTER_ACK(Packet *p) override;
 

	
 
public:
 
	bool connecting; ///< Are we connecting to the Game Coordinator?
 

	
 
	ClientNetworkCoordinatorSocketHandler() : connecting(false) {}
 

	
 
	NetworkRecvStatus CloseConnection(bool error = true) override;
 
	void SendReceive();
 

	
 
	void Connect();
 

	
 
	void Register();
 
	void SendServerUpdate();
 
};
 

	
 
extern ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
 

	
 
#endif /* NETWORK_COORDINATOR_H */
src/network/network_gui.cpp
Show inline comments
 
@@ -53,25 +53,25 @@
 

	
 
static void ShowNetworkStartServerWindow();
 
static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
 

	
 
static ClientID _admin_client_id = INVALID_CLIENT_ID; ///< For what client a confirmation window is open.
 
static CompanyID _admin_company_id = INVALID_COMPANY; ///< For what company a confirmation window is open.
 

	
 
/**
 
 * Visibility of the server. Public servers advertise, where private servers
 
 * do not.
 
 */
 
static const StringID _server_visibility_dropdown[] = {
 
	STR_NETWORK_SERVER_VISIBILITY_PRIVATE,
 
	STR_NETWORK_SERVER_VISIBILITY_LOCAL,
 
	STR_NETWORK_SERVER_VISIBILITY_PUBLIC,
 
	INVALID_STRING_ID
 
};
 

	
 
/**
 
 * Update the network new window because a new server is
 
 * found on the network.
 
 */
 
void UpdateNetworkGameWindow()
 
{
 
	InvalidateWindowData(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME, 0);
 
}
 
@@ -1598,39 +1598,44 @@ extern void DrawCompanyIcon(CompanyID ci
 
static const NWidgetPart _nested_client_list_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_GREY),
 
		NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NETWORK_CLIENT_LIST_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
 
		NWidget(WWT_STICKYBOX, COLOUR_GREY),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_GREY),
 
		NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CL_SERVER_SELECTOR),
 
			NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER, STR_NULL), SetPadding(4, 4, 0, 4), SetPIP(0, 2, 0),
 
				NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
 
					NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_NAME, STR_NULL),
 
					NWidget(NWID_SPACER), SetMinimalSize(20, 0),
 
					NWidget(NWID_SPACER), SetMinimalSize(10, 0),
 
					NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
 
					NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_SERVER_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP),
 
				EndContainer(),
 
				NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
 
					NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY, STR_NULL),
 
					NWidget(NWID_SPACER), SetMinimalSize(20, 0), SetFill(1, 0), SetResize(1, 0),
 
					NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0), SetResize(1, 0),
 
					NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_CL_SERVER_VISIBILITY), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP),
 
				EndContainer(),
 
				NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
 
					NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE, STR_NULL),
 
					NWidget(NWID_SPACER), SetMinimalSize(10, 0),
 
					NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_CONNECTION_TYPE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
 
				EndContainer(),
 
			EndContainer(),
 
		EndContainer(),
 
		NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_NETWORK_CLIENT_LIST_PLAYER, STR_NULL), SetPadding(4, 4, 4, 4), SetPIP(0, 2, 0),
 
			NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
 
				NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_PLAYER_NAME, STR_NULL),
 
				NWidget(NWID_SPACER), SetMinimalSize(20, 0),
 
				NWidget(NWID_SPACER), SetMinimalSize(10, 0),
 
				NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
 
				NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_CLIENT_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP),
 
			EndContainer(),
 
		EndContainer(),
 
		NWidget(NWID_HORIZONTAL),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(WWT_MATRIX, COLOUR_GREY, WID_CL_MATRIX), SetMinimalSize(180, 0), SetResize(1, 1), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_CL_SCROLLBAR),
 
				NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_COMPANY_COUNT), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetPadding(2, 1, 2, 1), SetAlignment(SA_CENTER), SetDataTip(STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT, STR_NULL),
 
			EndContainer(),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_CL_SCROLLBAR),
 
				NWidget(WWT_RESIZEBOX, COLOUR_GREY),
 
@@ -2041,24 +2046,28 @@ public:
 

	
 
	void SetStringParameters(int widget) const override
 
	{
 
		switch (widget) {
 
			case WID_CL_SERVER_NAME:
 
				SetDParamStr(0, _settings_client.network.server_name);
 
				break;
 

	
 
			case WID_CL_SERVER_VISIBILITY:
 
				SetDParam(0, _server_visibility_dropdown[_settings_client.network.server_advertise]);
 
				break;
 

	
 
			case WID_CL_SERVER_CONNECTION_TYPE:
 
				SetDParam(0, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN + _network_server_connection_type);
 
				break;
 

	
 
			case WID_CL_CLIENT_NAME:
 
				SetDParamStr(0, _settings_client.network.client_name);
 
				break;
 

	
 
			case WID_CL_CLIENT_COMPANY_COUNT:
 
				SetDParam(0, NetworkClientInfo::GetNumItems());
 
				SetDParam(1, Company::GetNumItems());
 
				break;
 
		}
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
src/network/network_internal.h
Show inline comments
 
@@ -2,24 +2,25 @@
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file network_internal.h Variables and function used internally. */
 

	
 
#ifndef NETWORK_INTERNAL_H
 
#define NETWORK_INTERNAL_H
 

	
 
#include "network_func.h"
 
#include "core/tcp_coordinator.h"
 
#include "core/tcp_game.h"
 

	
 
#include "../command_type.h"
 

	
 
#ifdef RANDOM_DEBUG
 
/**
 
 * 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
 
@@ -73,24 +74,25 @@ extern NetworkAddressList _broadcast_lis
 

	
 
extern uint32 _sync_seed_1;
 
#ifdef NETWORK_SEND_DOUBLE_SEED
 
extern uint32 _sync_seed_2;
 
#endif
 
extern uint32 _sync_frame;
 
extern bool _network_first_time;
 
/* Vars needed for the join-GUI */
 
extern NetworkJoinStatus _network_join_status;
 
extern uint8 _network_join_waiting;
 
extern uint32 _network_join_bytes;
 
extern uint32 _network_join_bytes_total;
 
extern ConnectionType _network_server_connection_type;
 

	
 
extern uint8 _network_reconnect;
 

	
 
extern CompanyMask _network_company_passworded;
 

	
 
void NetworkQueryServer(const std::string &connection_string);
 
void NetworkQueryLobbyServer(const std::string &connection_string);
 

	
 
void GetBindAddresses(NetworkAddressList *addresses, uint16 port);
 
struct NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually = true, bool never_expire = false);
 
void NetworkRebuildHostList();
 
void UpdateNetworkGameWindow();
src/network/network_type.h
Show inline comments
 
@@ -26,24 +26,33 @@ static const uint MAX_CLIENT_SLOTS = 256
 
 * Vehicletypes in the order they are send in info packets.
 
 */
 
enum NetworkVehicleType {
 
	NETWORK_VEH_TRAIN = 0,
 
	NETWORK_VEH_LORRY,
 
	NETWORK_VEH_BUS,
 
	NETWORK_VEH_PLANE,
 
	NETWORK_VEH_SHIP,
 

	
 
	NETWORK_VEH_END
 
};
 

	
 
/**
 
 * Game type the server can be using.
 
 * Used on the network protocol to communicate with Game Coordinator.
 
 */
 
enum ServerGameType : uint8 {
 
	SERVER_GAME_TYPE_LOCAL = 0,
 
	SERVER_GAME_TYPE_PUBLIC,
 
};
 

	
 
/** 'Unique' identifier to be given to clients */
 
enum ClientID : uint32 {
 
	INVALID_CLIENT_ID = 0, ///< Client is not part of anything
 
	CLIENT_ID_SERVER  = 1, ///< Servers always have this ID
 
	CLIENT_ID_FIRST   = 2, ///< The first client ID
 
};
 

	
 
/** Indices into the client tables */
 
typedef uint8 ClientIndex;
 

	
 
/** Indices into the admin tables. */
 
typedef uint8 AdminIndex;
src/widgets/network_widget.h
Show inline comments
 
@@ -92,24 +92,25 @@ enum NetworkLobbyWidgets {
 
	WID_NL_SPECTATE,   ///< 'Spectate game' button.
 
	WID_NL_REFRESH,    ///< 'Refresh server' button.
 
	WID_NL_CANCEL,     ///< 'Cancel' button.
 
};
 

	
 
/** Widgets of the #NetworkClientListWindow class. */
 
enum ClientListWidgets {
 
	WID_CL_PANEL,                      ///< Panel of the window.
 
	WID_CL_SERVER_SELECTOR,            ///< Selector to hide the server frame.
 
	WID_CL_SERVER_NAME,                ///< Server name.
 
	WID_CL_SERVER_NAME_EDIT,           ///< Edit button for server name.
 
	WID_CL_SERVER_VISIBILITY,          ///< Server visibility.
 
	WID_CL_SERVER_CONNECTION_TYPE,     ///< The type of connection the Game Coordinator detected for this server.
 
	WID_CL_CLIENT_NAME,                ///< Client name.
 
	WID_CL_CLIENT_NAME_EDIT,           ///< Edit button for client name.
 
	WID_CL_MATRIX,                     ///< Company/client list.
 
	WID_CL_SCROLLBAR,                  ///< Scrollbar for company/client list.
 
	WID_CL_COMPANY_JOIN,               ///< Used for QueryWindow when a company has a password.
 
	WID_CL_CLIENT_COMPANY_COUNT,       ///< Count of clients and companies.
 
};
 

	
 
/** Widgets of the #NetworkJoinStatusWindow class. */
 
enum NetworkJoinStatusWidgets {
 
	WID_NJS_BACKGROUND, ///< Background of the window.
 
	WID_NJS_CANCELOK,   ///< Cancel / OK button.
0 comments (0 inline, 0 general)