Changeset - r25313:a5c6f5530336
[Not reviewed]
master
0 8 0
Patric Stout - 3 years ago 2021-04-30 09:34:47
truebrain@openttd.org
Change: use TCP for everything except for master-server and initial server scan (#9130)

This means that pressing Refresh button and adding servers manually
now uses TCP.

The master-server and initial scan are still UDP as they will be
replaced by Game Coordinator; no need to change this now.

If we query a server that is too old, show a proper warning to the
user informing him the server is too old.
8 files changed with 78 insertions and 43 deletions:
0 comments (0 inline, 0 general)
os/emscripten/pre.js
Show inline comments
 
@@ -65,10 +65,14 @@ Module.preRun.push(function() {
 
    }
 

	
 
    window.openttd_server_list = function() {
 
        add_server = Module.cwrap("em_openttd_add_server", null, ["string", "number"]);
 
        add_server = Module.cwrap("em_openttd_add_server", null, ["string"]);
 

	
 
        /* Add servers that support WebSocket here. Example:
 
         *  add_server("localhost", 3979); */
 
        /* Add servers that support WebSocket here. Examples:
 
         *  add_server("localhost");
 
         *  add_server("localhost:3979");
 
         *  add_server("127.0.0.1:3979");
 
         *  add_server("[::1]:3979");
 
         */
 
    }
 

	
 
    var leftButtonDown = false;
src/lang/english.txt
Show inline comments
 
@@ -2217,6 +2217,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER      
 
STR_NETWORK_ERROR_TIMEOUT_MAP                                   :{WHITE}Your computer took too long to download the map
 
STR_NETWORK_ERROR_TIMEOUT_JOIN                                  :{WHITE}Your computer took too long to join the server
 
STR_NETWORK_ERROR_INVALID_CLIENT_NAME                           :{WHITE}Your player name is not valid
 
STR_NETWORK_ERROR_SERVER_TOO_OLD                                :{WHITE}The queried server is too old for this client
 

	
 
############ Leave those lines in this order!!
 
STR_NETWORK_ERROR_CLIENT_GENERAL                                :general error
src/network/network.cpp
Show inline comments
 
@@ -602,8 +602,11 @@ static void NetworkInitialize(bool close
 

	
 
/** Non blocking connection create to query servers */
 
class TCPQueryConnecter : TCPConnecter {
 
private:
 
	bool request_company_info;
 

	
 
public:
 
	TCPQueryConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
 
	TCPQueryConnecter(const NetworkAddress &address, bool request_company_info) : TCPConnecter(address), request_company_info(request_company_info) {}
 

	
 
	void OnFailure() override
 
	{
 
@@ -613,36 +616,53 @@ public:
 
	void OnConnect(SOCKET s) override
 
	{
 
		_networking = true;
 
		new ClientNetworkGameSocketHandler(s);
 
		MyClient::SendInformationQuery();
 
		new ClientNetworkGameSocketHandler(s, address);
 
		MyClient::SendInformationQuery(request_company_info);
 
	}
 
};
 

	
 
/**
 
 * Query a server to fetch his game-info.
 
 * @param address the address to query.
 
 * @param request_company_info Whether to request company info too.
 
 */
 
void NetworkTCPQueryServer(NetworkAddress address)
 
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info)
 
{
 
	if (!_network_available) return;
 

	
 
	NetworkDisconnect();
 
	NetworkInitialize();
 

	
 
	new TCPQueryConnecter(address);
 
	new TCPQueryConnecter(address, request_company_info);
 
}
 

	
 
/**
 
 * 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.
 
 * @param connection_string The IP:port to add to the list.
 
 * @param connection_string The IP:port of the server to add.
 
 * @return The entry on the game list.
 
 */
 
void NetworkAddServer(const char *connection_string)
 
NetworkGameList *NetworkAddServer(const std::string &connection_string)
 
{
 
	if (StrEmpty(connection_string)) return;
 
	if (connection_string.empty()) return nullptr;
 

	
 
	NetworkAddress address = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT);
 

	
 
	NetworkUDPQueryServer(ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT), true);
 
	/* Ensure the item already exists in the list */
 
	NetworkGameList *item = NetworkGameListAddItem(address);
 
	if (StrEmpty(item->info.server_name)) {
 
		ClearGRFConfigList(&item->info.grfconfig);
 
		address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
 
		item->manually = true;
 

	
 
		NetworkRebuildHostList();
 
		UpdateNetworkGameWindow();
 
	}
 

	
 
	NetworkTCPQueryServer(address);
 

	
 
	return item;
 
}
 

	
 
/**
 
@@ -687,7 +707,7 @@ public:
 
	void OnConnect(SOCKET s) override
 
	{
 
		_networking = true;
 
		new ClientNetworkGameSocketHandler(s);
 
		new ClientNetworkGameSocketHandler(s, this->address);
 
		IConsoleCmdExec("exec scripts/on_client.scr 0");
 
		NetworkClient_Connected();
 
	}
 
@@ -1132,9 +1152,9 @@ void NetworkShutDown()
 
#ifdef __EMSCRIPTEN__
 
extern "C" {
 

	
 
void CDECL em_openttd_add_server(const char *host, int port)
 
void CDECL em_openttd_add_server(const char *connection_string)
 
{
 
	NetworkUDPQueryServer(NetworkAddress(host, port), true);
 
	NetworkAddServer(connection_string);
 
}
 

	
 
}
src/network/network_client.cpp
Show inline comments
 
@@ -145,7 +145,7 @@ void ClientNetworkEmergencySave()
 
 * Create a new socket for the client side of the game connection.
 
 * @param s The socket to connect with.
 
 */
 
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s), savegame(nullptr), status(STATUS_INACTIVE)
 
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address) : NetworkGameSocketHandler(s), address(address), savegame(nullptr), status(STATUS_INACTIVE)
 
{
 
	assert(ClientNetworkGameSocketHandler::my_client == nullptr);
 
	ClientNetworkGameSocketHandler::my_client = this;
 
@@ -345,14 +345,18 @@ static_assert(NETWORK_SERVER_ID_LENGTH =
 
/**
 
 * Query the server for server information.
 
 */
 
NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery()
 
NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery(bool request_company_info)
 
{
 
	my_client->status = STATUS_COMPANY_INFO;
 
	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
 
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
 
	my_client->status = STATUS_GAME_INFO;
 
	my_client->SendPacket(new Packet(PACKET_CLIENT_GAME_INFO));
 

	
 
	my_client->SendPacket(new Packet(PACKET_CLIENT_GAME_INFO));
 
	my_client->SendPacket(new Packet(PACKET_CLIENT_COMPANY_INFO));
 
	if (request_company_info) {
 
		my_client->status = STATUS_COMPANY_INFO;
 
		_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
 
		SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
 

	
 
		my_client->SendPacket(new Packet(PACKET_CLIENT_COMPANY_INFO));
 
	}
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 
@@ -577,9 +581,13 @@ NetworkRecvStatus ClientNetworkGameSocke
 

	
 
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet *p)
 
{
 
	if (this->status != STATUS_COMPANY_INFO && this->status != STATUS_INACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
	if (this->status != STATUS_COMPANY_INFO && this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 

	
 
	NetworkGameList *item = GetLobbyGameInfo();
 
	if (item == nullptr) {
 
		/* This is not the lobby, so add it to the game list. */
 
		item = NetworkGameListAddItem(this->address);
 
	}
 

	
 
	/* Clear any existing GRFConfig chain. */
 
	ClearGRFConfigList(&item->info.grfconfig);
 
@@ -590,6 +598,8 @@ NetworkRecvStatus ClientNetworkGameSocke
 
	/* Ensure we consider the server online. */
 
	item->online = true;
 

	
 
	/* It could be either window, but only one is open, so redraw both. */
 
	SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
 
	SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
 

	
 
	/* We will receive company info next, so keep connection open. */
 
@@ -727,6 +737,15 @@ NetworkRecvStatus ClientNetworkGameSocke
 

	
 
	NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
 

	
 
	/* If we query a server that is 1.11.1 or older, we get an
 
	 * NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show a special
 
	 * error popup in that case.
 
	 */
 
	if (error == NETWORK_ERROR_NOT_EXPECTED && (this->status == STATUS_GAME_INFO || this->status == STATUS_COMPANY_INFO)) {
 
		ShowErrorMessage(STR_NETWORK_ERROR_SERVER_TOO_OLD, INVALID_STRING_ID, WL_CRITICAL);
 
		return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
	}
 

	
 
	StringID err = STR_NETWORK_ERROR_LOSTCONNECTION;
 
	if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
 
	/* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */
src/network/network_client.h
Show inline comments
 
@@ -15,12 +15,14 @@
 
/** Class for handling the client side of the game connection. */
 
class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler {
 
private:
 
	NetworkAddress address;        ///< Address we are connected to.
 
	struct PacketReader *savegame; ///< Packet reader for reading the savegame.
 
	byte token;                    ///< The token we need to send back to the server to prove we're the right client.
 

	
 
	/** Status of the connection with the server. */
 
	enum ServerStatus {
 
		STATUS_INACTIVE,      ///< The client is not connected nor active.
 
		STATUS_GAME_INFO,     ///< We are trying to get the game information.
 
		STATUS_COMPANY_INFO,  ///< We are trying to get company information.
 
		STATUS_JOIN,          ///< We are trying to join a server.
 
		STATUS_NEWGRFS_CHECK, ///< Last action was checking NewGRFs.
 
@@ -74,13 +76,13 @@ protected:
 
	static NetworkRecvStatus SendMapOk();
 
	void CheckConnection();
 
public:
 
	ClientNetworkGameSocketHandler(SOCKET s);
 
	ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address);
 
	~ClientNetworkGameSocketHandler();
 

	
 
	NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override;
 
	void ClientError(NetworkRecvStatus res);
 

	
 
	static NetworkRecvStatus SendInformationQuery();
 
	static NetworkRecvStatus SendInformationQuery(bool request_company_info);
 

	
 
	static NetworkRecvStatus SendJoin();
 
	static NetworkRecvStatus SendCommand(const CommandPacket *cp);
src/network/network_gamelist.cpp
Show inline comments
 
@@ -69,15 +69,6 @@ static void NetworkGameListHandleDelayed
 
 */
 
NetworkGameList *NetworkGameListAddItem(NetworkAddress address)
 
{
 
	const char *hostname = address.GetHostname();
 

	
 
	/* Do not query the 'any' address. */
 
	if (StrEmpty(hostname) ||
 
			strcmp(hostname, "0.0.0.0") == 0 ||
 
			strcmp(hostname, "::") == 0) {
 
		return nullptr;
 
	}
 

	
 
	NetworkGameList *item, *prev_item;
 

	
 
	prev_item = nullptr;
 
@@ -95,7 +86,6 @@ NetworkGameList *NetworkGameListAddItem(
 
	} else {
 
		prev_item->next = item;
 
	}
 
	DEBUG(net, 4, "[gamelist] added server to list");
 

	
 
	UpdateNetworkGameWindow();
 

	
src/network/network_gui.cpp
Show inline comments
 
@@ -472,9 +472,8 @@ public:
 
		EM_ASM(if (window["openttd_server_list"]) openttd_server_list());
 
#endif
 

	
 
		this->last_joined = NetworkGameListAddItem(ParseConnectionString(_settings_client.network.last_joined, NETWORK_DEFAULT_PORT));
 
		this->last_joined = NetworkAddServer(_settings_client.network.last_joined);
 
		this->server = this->last_joined;
 
		if (this->last_joined != nullptr) NetworkUDPQueryServer(this->last_joined->address);
 

	
 
		this->requery_timer.SetInterval(MILLISECONDS_PER_TICK);
 

	
 
@@ -750,7 +749,7 @@ public:
 
				break;
 

	
 
			case WID_NG_REFRESH: // Refresh
 
				if (this->server != nullptr) NetworkUDPQueryServer(this->server->address);
 
				if (this->server != nullptr) NetworkTCPQueryServer(this->server->address);
 
				break;
 

	
 
			case WID_NG_NEWGRF: // NewGRF Settings
 
@@ -971,7 +970,7 @@ void ShowNetworkGameWindow()
 
		first = false;
 
		/* Add all servers from the config file to our list. */
 
		for (const auto &iter : _network_host_list) {
 
			NetworkAddServer(iter.c_str());
 
			NetworkAddServer(iter);
 
		}
 
	}
 

	
 
@@ -1485,7 +1484,7 @@ struct NetworkLobbyWindow : public Windo
 
				/* Clear the information so removed companies don't remain */
 
				for (auto &company : this->company_info) company = {};
 

	
 
				NetworkTCPQueryServer(this->server->address);
 
				NetworkTCPQueryServer(this->server->address, true);
 
				break;
 
		}
 
	}
 
@@ -1555,7 +1554,7 @@ static void ShowNetworkLobbyWindow(Netwo
 

	
 
	strecpy(_settings_client.network.last_joined, ngl->address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined));
 

	
 
	NetworkTCPQueryServer(ngl->address);
 
	NetworkTCPQueryServer(ngl->address, true);
 

	
 
	new NetworkLobbyWindow(&_network_lobby_window_desc, ngl);
 
}
src/network/network_internal.h
Show inline comments
 
@@ -87,10 +87,10 @@ extern uint8 _network_reconnect;
 

	
 
extern CompanyMask _network_company_passworded;
 

	
 
void NetworkTCPQueryServer(NetworkAddress address);
 
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info = false);
 

	
 
void GetBindAddresses(NetworkAddressList *addresses, uint16 port);
 
void NetworkAddServer(const char *b);
 
struct NetworkGameList *NetworkAddServer(const std::string &connection_string);
 
void NetworkRebuildHostList();
 
void UpdateNetworkGameWindow();
 

	
0 comments (0 inline, 0 general)