Changeset - r26005:fa9fad1bd9d6
[Not reviewed]
master
0 4 0
Patric Stout - 3 years ago 2021-10-03 09:02:28
truebrain@openttd.org
Add: [Network] Keep the refresh button in lowered state while refreshing (#9600)

This gives user visual feedback that the refresh is still pending, and
prevents people from clicking again and again thinking nothing is
happening. This is especially true for connections that fall back to
TURN, as that takes a few seconds to kick in.

Additionally, prevent clicking on the button again while a refresh
is pending. This is only delaying a successful result.
4 files changed with 13 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/network/network.cpp
Show inline comments
 
@@ -626,42 +626,47 @@ static void NetworkInitialize(bool close
 
/** Non blocking connection to query servers for their game info. */
 
class TCPQueryConnecter : TCPServerConnecter {
 
private:
 
	std::string connection_string;
 

	
 
public:
 
	TCPQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
 

	
 
	void OnFailure() override
 
	{
 
		NetworkGameList *item = NetworkGameListAddItem(connection_string);
 
		item->status = NGLS_OFFLINE;
 
		item->refreshing = false;
 

	
 
		UpdateNetworkGameWindow();
 
	}
 

	
 
	void OnConnect(SOCKET s) override
 
	{
 
		QueryNetworkGameSocketHandler::QueryServer(s, this->connection_string);
 
	}
 
};
 

	
 
/**
 
 * Query a server to fetch the game-info.
 
 * @param connection_string the address to query.
 
 */
 
void NetworkQueryServer(const std::string &connection_string)
 
{
 
	if (!_network_available) return;
 

	
 
	/* Mark the entry as refreshing, so the GUI can show the refresh is pending. */
 
	NetworkGameList *item = NetworkGameListAddItem(connection_string);
 
	item->refreshing = true;
 

	
 
	new TCPQueryConnecter(connection_string);
 
}
 

	
 
/**
 
 * 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 of the server to add.
 
 * @param manually Whether the enter should be marked as manual added.
 
 * @param never_expire Whether the entry can expire (removed when no longer found in the public listing).
 
 * @return The entry on the game list.
 
 */
src/network/network_gamelist.h
Show inline comments
 
@@ -22,25 +22,25 @@ enum NetworkGameListStatus {
 
	NGLS_BANNED,  ///< You are banned from this server.
 
	NGLS_TOO_OLD, ///< Server is too old to query.
 
};
 

	
 
/** Structure with information shown in the game list (GUI) */
 
struct NetworkGameList {
 
	NetworkGameList(const std::string &connection_string) : connection_string(connection_string) {}
 

	
 
	NetworkGameInfo info = {};                   ///< The game information of this server.
 
	std::string connection_string;               ///< Address of the server.
 
	NetworkGameListStatus status = NGLS_OFFLINE; ///< Stats of the server.
 
	bool manually = false;                       ///< True if the server was added manually.
 
	uint8 retries = 0;                           ///< Number of retries (to stop requerying).
 
	bool refreshing = false;                     ///< Whether this server is being queried.
 
	int version = 0;                             ///< Used to see which servers are no longer available on the Game Coordinator and can be removed.
 
	NetworkGameList *next = nullptr;             ///< Next pointer to make a linked game list.
 
};
 

	
 
extern NetworkGameList *_network_game_list;
 
extern int _network_game_list_version;
 

	
 
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string);
 
void NetworkGameListRemoveItem(NetworkGameList *remove);
 
void NetworkGameListRemoveExpired();
 

	
 
#endif /* NETWORK_GAMELIST_H */
src/network/network_gui.cpp
Show inline comments
 
@@ -604,24 +604,26 @@ public:
 
			this->SortNetworkGameList();
 
		}
 

	
 
		NetworkGameList *sel = this->server;
 
		/* 'Refresh' button invisible if no server selected */
 
		this->SetWidgetDisabledState(WID_NG_REFRESH, sel == nullptr);
 
		/* 'Join' button disabling conditions */
 
		this->SetWidgetDisabledState(WID_NG_JOIN, sel == nullptr || // no Selected Server
 
				sel->status != NGLS_ONLINE || // Server offline
 
				sel->info.clients_on >= sel->info.clients_max || // Server full
 
				!sel->info.compatible); // Revision mismatch
 

	
 
		this->SetWidgetLoweredState(WID_NG_REFRESH, sel != nullptr && sel->refreshing);
 

	
 
		/* 'NewGRF Settings' button invisible if no NewGRF is used */
 
		this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == nullptr || sel->status != NGLS_ONLINE || sel->info.grfconfig == nullptr);
 
		this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == nullptr || sel->status != NGLS_ONLINE || sel->info.grfconfig == nullptr || !sel->info.version_compatible || sel->info.compatible);
 

	
 
#ifdef __EMSCRIPTEN__
 
		this->SetWidgetDisabledState(WID_NG_SEARCH_INTERNET, true);
 
		this->SetWidgetDisabledState(WID_NG_SEARCH_LAN, true);
 
		this->SetWidgetDisabledState(WID_NG_ADD, true);
 
		this->SetWidgetDisabledState(WID_NG_START, true);
 
#endif
 

	
 
		this->DrawWidgets();
 
@@ -781,25 +783,25 @@ public:
 

	
 
			case WID_NG_START: // Start server
 
				ShowNetworkStartServerWindow();
 
				break;
 

	
 
			case WID_NG_JOIN: // Join Game
 
				if (this->server != nullptr) {
 
					NetworkClientConnectGame(this->server->connection_string, COMPANY_SPECTATOR);
 
				}
 
				break;
 

	
 
			case WID_NG_REFRESH: // Refresh
 
				if (this->server != nullptr) NetworkQueryServer(this->server->connection_string);
 
				if (this->server != nullptr && !this->server->refreshing) NetworkQueryServer(this->server->connection_string);
 
				break;
 

	
 
			case WID_NG_NEWGRF: // NewGRF Settings
 
				if (this->server != nullptr) ShowNewGRFSettings(false, false, false, &this->server->info.grfconfig);
 
				break;
 

	
 
			case WID_NG_NEWGRF_MISSING: // Find missing content online
 
				if (this->server != nullptr) ShowMissingContentWindow(this->server->info.grfconfig);
 
				break;
 
		}
 
	}
 

	
src/network/network_query.cpp
Show inline comments
 
@@ -70,73 +70,77 @@ void QueryNetworkGameSocketHandler::Send
 
 * Query the server for server information.
 
 */
 
NetworkRecvStatus QueryNetworkGameSocketHandler::SendGameInfo()
 
{
 
	this->SendPacket(new Packet(PACKET_CLIENT_GAME_INFO));
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
 
{
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 
	item->status = NGLS_FULL;
 
	item->refreshing = false;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *p)
 
{
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 
	item->status = NGLS_BANNED;
 
	item->refreshing = false;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet *p)
 
{
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 

	
 
	/* Clear any existing GRFConfig chain. */
 
	ClearGRFConfigList(&item->info.grfconfig);
 
	/* Retrieve the NetworkGameInfo from the packet. */
 
	DeserializeNetworkGameInfo(p, &item->info);
 
	/* Check for compatability with the client. */
 
	CheckGameCompatibility(item->info);
 
	/* Ensure we consider the server online. */
 
	item->status = NGLS_ONLINE;
 
	item->refreshing = false;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p)
 
{
 
	NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
 

	
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 

	
 
	if (error == NETWORK_ERROR_NOT_EXPECTED) {
 
		/* 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 to the
 
		 * user this server is too old to query.
 
		 */
 
		item->status = NGLS_TOO_OLD;
 
	} else {
 
		item->status = NGLS_OFFLINE;
 
	}
 
	item->refreshing = false;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
/**
 
 * Check if any query needs to send or receive.
 
 */
 
/* static */ void QueryNetworkGameSocketHandler::SendReceive()
 
{
 
	for (auto it = QueryNetworkGameSocketHandler::queries.begin(); it != QueryNetworkGameSocketHandler::queries.end(); /* nothing */) {
0 comments (0 inline, 0 general)