Changeset - r25801:cac5091e0a66
[Not reviewed]
master
0 5 0
Patric Stout - 3 years ago 2021-07-03 09:12:28
truebrain@openttd.org
Add: use Game Coordinator to get latest public server listing
5 files changed with 136 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/network/core/tcp_coordinator.cpp
Show inline comments
 
@@ -31,6 +31,8 @@ bool NetworkCoordinatorSocketHandler::Ha
 
		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);
 
		case PACKET_COORDINATOR_CLIENT_LISTING:  return this->Receive_CLIENT_LISTING(p);
 
		case PACKET_COORDINATOR_GC_LISTING:      return this->Receive_GC_LISTING(p);
 

	
 
		default:
 
			Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type);
 
@@ -78,3 +80,5 @@ bool NetworkCoordinatorSocketHandler::Re
 
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); }
 
bool NetworkCoordinatorSocketHandler::Receive_CLIENT_LISTING(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_CLIENT_LISTING); }
 
bool NetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_LISTING); }
src/network/core/tcp_coordinator.h
Show inline comments
 
@@ -29,6 +29,8 @@ enum PacketCoordinatorType {
 
	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_CLIENT_LISTING,  ///< Client is requesting a listing of all public servers.
 
	PACKET_COORDINATOR_GC_LISTING,      ///< Game Coordinator returns a listing of all public servers.
 
	PACKET_COORDINATOR_END,             ///< Must ALWAYS be on the end of this list!! (period).
 
};
 

	
 
@@ -101,6 +103,33 @@ protected:
 
	 */
 
	virtual bool Receive_SERVER_UPDATE(Packet *p);
 

	
 
	/**
 
	 * Client requests a list of all public servers.
 
	 *
 
	 *  uint8   Game Coordinator protocol version.
 
	 *  uint8   Game-info version used by this client.
 
	 *  string  Revision of the client.
 
	 *
 
	 * @param p The packet that was just received.
 
	 * @return True upon success, otherwise false.
 
	 */
 
	virtual bool Receive_CLIENT_LISTING(Packet *p);
 

	
 
	/**
 
	 * Game Coordinator replies with a list of all public servers. Multiple
 
	 * of these packets are received after a request till all servers are
 
	 * sent over. Last packet will have server count of 0.
 
	 *
 
	 *  uint16  Amount of public servers in this packet.
 
	 *  For each server:
 
	 *    string  Connection string for this server.
 
	 *    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_GC_LISTING(Packet *p);
 

	
 
	bool HandlePacket(Packet *p);
 
public:
 
	/**
src/network/network_coordinator.cpp
Show inline comments
 
@@ -19,6 +19,7 @@
 
#include "network.h"
 
#include "network_coordinator.h"
 
#include "network_gamelist.h"
 
#include "network_internal.h"
 
#include "table/strings.h"
 

	
 
#include "../safeguards.h"
 
@@ -47,6 +48,7 @@ public:
 
		assert(_network_coordinator_client.sock == INVALID_SOCKET);
 

	
 
		_network_coordinator_client.sock = s;
 
		_network_coordinator_client.last_activity = std::chrono::steady_clock::now();
 
		_network_coordinator_client.connecting = false;
 
	}
 
};
 
@@ -111,6 +113,42 @@ bool ClientNetworkCoordinatorSocketHandl
 
	return true;
 
}
 

	
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p)
 
{
 
	uint8 servers = p->Recv_uint16();
 

	
 
	/* End of list; we can now remove all expired items from the list. */
 
	if (servers == 0) {
 
		NetworkGameListRemoveExpired();
 
		return true;
 
	}
 

	
 
	for (; servers > 0; servers--) {
 
		std::string connection_string = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
 

	
 
		/* Read the NetworkGameInfo from the packet. */
 
		NetworkGameInfo ngi = {};
 
		DeserializeNetworkGameInfo(p, &ngi);
 

	
 
		/* Now we know the join-key, we can add it to our list. */
 
		NetworkGameList *item = NetworkGameListAddItem(connection_string);
 

	
 
		/* Clear any existing GRFConfig chain. */
 
		ClearGRFConfigList(&item->info.grfconfig);
 
		/* Copy the new NetworkGameInfo info. */
 
		item->info = ngi;
 
		/* Check for compatability with the client. */
 
		CheckGameCompatibility(item->info);
 
		/* Mark server as online. */
 
		item->online = true;
 
		/* Mark the item as up-to-date. */
 
		item->version = _network_game_list_version;
 
	}
 

	
 
	UpdateNetworkGameWindow();
 
	return true;
 
}
 

	
 
void ClientNetworkCoordinatorSocketHandler::Connect()
 
{
 
	/* We are either already connected or are trying to connect. */
 
@@ -119,6 +157,8 @@ void ClientNetworkCoordinatorSocketHandl
 
	this->Reopen();
 

	
 
	this->connecting = true;
 
	this->last_activity = std::chrono::steady_clock::now();
 

	
 
	new NetworkCoordinatorConnecter(NETWORK_COORDINATOR_SERVER_HOST);
 
}
 

	
 
@@ -173,6 +213,23 @@ void ClientNetworkCoordinatorSocketHandl
 
}
 

	
 
/**
 
 * Request a listing of all public servers.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::GetListing()
 
{
 
	this->Connect();
 

	
 
	_network_game_list_version++;
 

	
 
	Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_LISTING);
 
	p->Send_uint8(NETWORK_COORDINATOR_VERSION);
 
	p->Send_uint8(NETWORK_GAME_INFO_VERSION);
 
	p->Send_string(_openttd_revision);
 

	
 
	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.
 
 */
 
@@ -226,8 +283,15 @@ void ClientNetworkCoordinatorSocketHandl
 
		this->SendServerUpdate();
 
	}
 

	
 
	if (!_network_server && std::chrono::steady_clock::now() > this->last_activity + IDLE_TIMEOUT) {
 
		this->CloseConnection();
 
		return;
 
	}
 

	
 
	if (this->CanSendReceive()) {
 
		this->ReceivePackets();
 
		if (this->ReceivePackets()) {
 
			this->last_activity = std::chrono::steady_clock::now();
 
		}
 
	}
 

	
 
	this->SendPackets();
src/network/network_coordinator.h
Show inline comments
 
@@ -21,6 +21,10 @@
 
 *  - 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.
 
 *
 
 * For clients (listing):
 
 *  - Client sends CLIENT_LISTING.
 
 *  - Game Coordinator returns the full list of public servers via GC_LISTING (multiple packets).
 
 */
 

	
 
/** Class for handling the client side of the Game Coordinator connection. */
 
@@ -31,8 +35,13 @@ private:
 
protected:
 
	bool Receive_GC_ERROR(Packet *p) override;
 
	bool Receive_GC_REGISTER_ACK(Packet *p) override;
 
	bool Receive_GC_LISTING(Packet *p) override;
 

	
 
public:
 
	/** The idle timeout; when to close the connection because it's idle. */
 
	static constexpr std::chrono::seconds IDLE_TIMEOUT = std::chrono::seconds(60);
 

	
 
	std::chrono::steady_clock::time_point last_activity;  ///< The last time there was network activity.
 
	bool connecting; ///< Are we connecting to the Game Coordinator?
 

	
 
	ClientNetworkCoordinatorSocketHandler() : connecting(false) {}
 
@@ -44,6 +53,7 @@ public:
 

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

	
 
extern ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
src/network/network_gui.cpp
Show inline comments
 
@@ -18,6 +18,7 @@
 
#include "network_base.h"
 
#include "network_content.h"
 
#include "network_server.h"
 
#include "network_coordinator.h"
 
#include "../gui.h"
 
#include "network_udp.h"
 
#include "../window_func.h"
 
@@ -54,6 +55,8 @@
 
static void ShowNetworkStartServerWindow();
 
static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
 

	
 
static const int NETWORK_LIST_REFRESH_DELAY = 30; ///< Time, in seconds, between updates of the network list.
 

	
 
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.
 

	
 
@@ -219,14 +222,15 @@ protected:
 
	static GUIGameServerList::SortFunction * const sorter_funcs[];
 
	static GUIGameServerList::FilterFunction * const filter_funcs[];
 

	
 
	NetworkGameList *server;      ///< selected server
 
	NetworkGameList *last_joined; ///< the last joined server
 
	GUIGameServerList servers;    ///< list with game servers.
 
	ServerListPosition list_pos;  ///< position of the selected server
 
	Scrollbar *vscroll;           ///< vertical scrollbar of the list of servers
 
	NetworkGameList *server;        ///< Selected server.
 
	NetworkGameList *last_joined;   ///< The last joined server.
 
	GUIGameServerList servers;      ///< List with game servers.
 
	ServerListPosition list_pos;    ///< Position of the selected server.
 
	Scrollbar *vscroll;             ///< Vertical scrollbar of the list of servers.
 
	QueryString name_editbox;     ///< Client name editbox.
 
	QueryString filter_editbox;   ///< Editbox for filter on servers
 
	GUITimer requery_timer;       ///< Timer for network requery
 
	QueryString filter_editbox;     ///< Editbox for filter on servers.
 
	GUITimer requery_timer;         ///< Timer for network requery.
 
	bool searched_internet = false; ///< Did we ever press "Search Internet" button?
 

	
 
	int lock_offset; ///< Left offset for lock icon.
 
	int blot_offset; ///< Left offset for green/yellow/red compatibility icon.
 
@@ -244,8 +248,18 @@ protected:
 
		/* Create temporary array of games to use for listing */
 
		this->servers.clear();
 

	
 
		bool found_current_server = false;
 
		for (NetworkGameList *ngl = _network_game_list; ngl != nullptr; ngl = ngl->next) {
 
			this->servers.push_back(ngl);
 
			if (ngl == this->server) {
 
				found_current_server = true;
 
			}
 
		}
 
		/* A refresh can cause the current server to be delete; so unselect. */
 
		if (!found_current_server) {
 
			if (this->server == this->last_joined) this->last_joined = nullptr;
 
			this->server = nullptr;
 
			this->list_pos = SLP_INVALID;
 
		}
 

	
 
		/* Apply the filter condition immediately, if a search string has been provided. */
 
@@ -479,7 +493,7 @@ public:
 
		this->last_joined = NetworkAddServer(_settings_client.network.last_joined, false);
 
		this->server = this->last_joined;
 

	
 
		this->requery_timer.SetInterval(MILLISECONDS_PER_TICK);
 
		this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000);
 

	
 
		this->servers.SetListing(this->last_sorting);
 
		this->servers.SetSortFuncs(this->sorter_funcs);
 
@@ -725,7 +739,8 @@ public:
 
			}
 

	
 
			case WID_NG_SEARCH_INTERNET:
 
				NetworkUDPQueryMasterServer();
 
				_network_coordinator_client.GetListing();
 
				this->searched_internet = true;
 
				break;
 

	
 
			case WID_NG_SEARCH_LAN:
 
@@ -841,10 +856,11 @@ public:
 

	
 
	void OnRealtimeTick(uint delta_ms) override
 
	{
 
		if (!this->searched_internet) return;
 
		if (!this->requery_timer.Elapsed(delta_ms)) return;
 
		this->requery_timer.SetInterval(MILLISECONDS_PER_TICK);
 

	
 
		NetworkGameListRequery();
 
		this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000);
 

	
 
		_network_coordinator_client.GetListing();
 
	}
 
};
 

	
0 comments (0 inline, 0 general)