mirror of https://github.com/OpenTTD/OpenTTD.git
Add: use Game Coordinator to get latest public server listing
This commit is contained in:
parent
b1280fd17e
commit
aa93d76223
|
@ -31,6 +31,8 @@ bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *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);
|
||||
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::Receive_GC_ERROR(Packet *p) { return this-
|
|||
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); }
|
||||
|
|
|
@ -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:
|
||||
/**
|
||||
|
|
|
@ -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 ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p)
|
|||
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 ClientNetworkCoordinatorSocketHandler::Connect()
|
|||
this->Reopen();
|
||||
|
||||
this->connecting = true;
|
||||
this->last_activity = std::chrono::steady_clock::now();
|
||||
|
||||
new NetworkCoordinatorConnecter(NETWORK_COORDINATOR_SERVER_HOST);
|
||||
}
|
||||
|
||||
|
@ -172,6 +212,23 @@ void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
|
|||
this->SendPacket(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ClientNetworkCoordinatorSocketHandler::SendReceive()
|
|||
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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
QueryString name_editbox; ///< Client name editbox.
|
||||
QueryString filter_editbox; ///< Editbox for filter on servers
|
||||
GUITimer requery_timer; ///< Timer for network requery
|
||||
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.
|
||||
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);
|
||||
this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000);
|
||||
|
||||
NetworkGameListRequery();
|
||||
_network_coordinator_client.GetListing();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue