Changeset - r25925:38cfb717fb3f
[Not reviewed]
master
0 6 0
Patric Stout - 3 years ago 2021-08-23 18:16:22
truebrain@openttd.org
Fix: [Network] show query errors in the server listing instead of error popup (#9506)

When you are query several servers at once, it is rather unclear
for which server you got a popup. Instead, show any errors on the
server itself.

This is only true for the query-part. Joining a server still gives
an error popup to tell you about any issue.
6 files changed with 60 insertions and 30 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2043,12 +2043,14 @@ STR_NETWORK_SERVER_LIST_SERVER_ADDRESS  
 
STR_NETWORK_SERVER_LIST_START_DATE                              :{SILVER}Start date: {WHITE}{DATE_SHORT}
 
STR_NETWORK_SERVER_LIST_CURRENT_DATE                            :{SILVER}Current date: {WHITE}{DATE_SHORT}
 
STR_NETWORK_SERVER_LIST_GAMESCRIPT                              :{SILVER}Game Script: {WHITE}{RAW_STRING} (v{NUM})
 
STR_NETWORK_SERVER_LIST_PASSWORD                                :{SILVER}Password protected!
 
STR_NETWORK_SERVER_LIST_SERVER_OFFLINE                          :{SILVER}SERVER OFFLINE
 
STR_NETWORK_SERVER_LIST_SERVER_FULL                             :{SILVER}SERVER FULL
 
STR_NETWORK_SERVER_LIST_SERVER_BANNED                           :{SILVER}SERVER BANNED YOU
 
STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD                          :{SILVER}SERVER TOO OLD
 
STR_NETWORK_SERVER_LIST_VERSION_MISMATCH                        :{SILVER}VERSION MISMATCH
 
STR_NETWORK_SERVER_LIST_GRF_MISMATCH                            :{SILVER}NEWGRF MISMATCH
 

	
 
STR_NETWORK_SERVER_LIST_JOIN_GAME                               :{BLACK}Join game
 
STR_NETWORK_SERVER_LIST_REFRESH                                 :{BLACK}Refresh server
 
STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP                         :{BLACK}Refresh the server info
 
@@ -2223,13 +2225,12 @@ STR_NETWORK_ERROR_CHEATER               
 
STR_NETWORK_ERROR_TOO_MANY_COMMANDS                             :{WHITE}You were sending too many commands to the server
 
STR_NETWORK_ERROR_TIMEOUT_PASSWORD                              :{WHITE}You took too long to enter the password
 
STR_NETWORK_ERROR_TIMEOUT_COMPUTER                              :{WHITE}Your computer is too slow to keep up with the server
 
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
 
STR_NETWORK_ERROR_CLIENT_DESYNC                                 :desync error
 
STR_NETWORK_ERROR_CLIENT_SAVEGAME                               :could not load map
 
STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST                        :connection lost
src/network/network.cpp
Show inline comments
 
@@ -629,13 +629,13 @@ private:
 
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->online = false;
 
		item->status = NGLS_OFFLINE;
 

	
 
		UpdateNetworkGameWindow();
 
	}
 

	
 
	void OnConnect(SOCKET s) override
 
	{
src/network/network_coordinator.cpp
Show inline comments
 
@@ -149,13 +149,13 @@ bool ClientNetworkCoordinatorSocketHandl
 
				connecter_pre_it->second->SetFailure();
 
				this->connecter_pre.erase(connecter_pre_it);
 
			}
 

	
 
			/* Mark the server as offline. */
 
			NetworkGameList *item = NetworkGameListAddItem(detail);
 
			item->online = false;
 
			item->status = NGLS_OFFLINE;
 

	
 
			UpdateNetworkGameWindow();
 
			return true;
 
		}
 

	
 
		case NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE:
 
@@ -254,13 +254,13 @@ bool ClientNetworkCoordinatorSocketHandl
 
		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;
 
		item->status = NGLS_ONLINE;
 
		/* Mark the item as up-to-date. */
 
		item->version = _network_game_list_version;
 
	}
 

	
 
	UpdateNetworkGameWindow();
 
	return true;
src/network/network_gamelist.h
Show inline comments
 
@@ -11,23 +11,32 @@
 
#define NETWORK_GAMELIST_H
 

	
 
#include "core/address.h"
 
#include "core/game_info.h"
 
#include "network_type.h"
 

	
 
/** The status a server can be in. */
 
enum NetworkGameListStatus {
 
	NGLS_OFFLINE, ///< Server is offline (or cannot be queried).
 
	NGLS_ONLINE,  ///< Server is online.
 
	NGLS_FULL,    ///< Server is full and cannot be queried.
 
	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
 
	bool online = false;             ///< False if the server did not respond (default status)
 
	bool manually = false;           ///< True if the server was added manually
 
	uint8 retries = 0;               ///< Number of retries (to stop requerying)
 
	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).
 
	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
 
	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);
src/network/network_gui.cpp
Show inline comments
 
@@ -404,13 +404,13 @@ protected:
 
		int icon_y_offset = (this->resize.step_height - GetSpriteSize(SPR_BLOT).height) / 2;
 
		int lock_y_offset = (this->resize.step_height - GetSpriteSize(SPR_LOCK).height) / 2;
 

	
 
		DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, cur_item->info.server_name, TC_BLACK);
 

	
 
		/* only draw details if the server is online */
 
		if (cur_item->online) {
 
		if (cur_item->status == NGLS_ONLINE) {
 
			const NWidgetServerListHeader *nwi_header = this->GetWidget<NWidgetServerListHeader>(WID_NG_HEADER);
 

	
 
			if (nwi_header->IsWidgetVisible(WID_NG_CLIENTS)) {
 
				const NWidgetBase *nwi_clients = this->GetWidget<NWidgetBase>(WID_NG_CLIENTS);
 
				SetDParam(0, cur_item->info.clients_on);
 
				SetDParam(1, cur_item->info.clients_max);
 
@@ -606,19 +606,19 @@ public:
 

	
 
		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->online || // Server offline
 
				sel->status != NGLS_ONLINE || // Server offline
 
				sel->info.clients_on >= sel->info.clients_max || // Server full
 
				!sel->info.compatible); // Revision mismatch
 

	
 
		/* 'NewGRF Settings' button invisible if no NewGRF is used */
 
		this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr);
 
		this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr || !sel->info.version_compatible || sel->info.compatible);
 
		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);
 
@@ -634,16 +634,26 @@ public:
 
		const int detail_height = 6 + 8 + 6 + 3 * FONT_HEIGHT_NORMAL;
 

	
 
		/* Draw the right menu */
 
		GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE);
 
		if (sel == nullptr) {
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);
 
		} else if (!sel->online) {
 
		} else if (sel->status != NGLS_ONLINE) {
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
 

	
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, STR_NETWORK_SERVER_LIST_SERVER_OFFLINE, TC_FROMSTRING, SA_HOR_CENTER); // server offline
 
			StringID message = INVALID_STRING_ID;
 
			switch (sel->status) {
 
				case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break;
 
				case NGLS_FULL: message = STR_NETWORK_SERVER_LIST_SERVER_FULL; break;
 
				case NGLS_BANNED: message = STR_NETWORK_SERVER_LIST_SERVER_BANNED; break;
 
				case NGLS_TOO_OLD: message = STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD; break;
 

	
 
				/* Handled by the if-case above. */
 
				case NGLS_ONLINE: NOT_REACHED();
 
			}
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline
 
		} else { // show game info
 

	
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);
 
			DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
 

	
 
			uint16 y = r.top + detail_height + 4;
src/network/network_query.cpp
Show inline comments
 
@@ -74,22 +74,28 @@ NetworkRecvStatus QueryNetworkGameSocket
 
	this->SendPacket(new Packet(PACKET_CLIENT_GAME_INFO));
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
 
{
 
	/* We try to join a server which is full */
 
	ShowErrorMessage(STR_NETWORK_ERROR_SERVER_FULL, INVALID_STRING_ID, WL_CRITICAL);
 
	return NETWORK_RECV_STATUS_SERVER_FULL;
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 
	item->status = NGLS_FULL;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *p)
 
{
 
	/* We try to join a server where we are banned */
 
	ShowErrorMessage(STR_NETWORK_ERROR_SERVER_BANNED, INVALID_STRING_ID, WL_CRITICAL);
 
	return NETWORK_RECV_STATUS_SERVER_BANNED;
 
	NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
 
	item->status = NGLS_BANNED;
 

	
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

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

	
 
@@ -97,34 +103,38 @@ NetworkRecvStatus QueryNetworkGameSocket
 
	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->online = true;
 
	item->status = NGLS_ONLINE;
 

	
 
	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 a special
 
	 * error popup in that case.
 
		 * NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show to the
 
		 * user this server is too old to query.
 
	 */
 
	if (error == NETWORK_ERROR_NOT_EXPECTED) {
 
		ShowErrorMessage(STR_NETWORK_ERROR_SERVER_TOO_OLD, INVALID_STRING_ID, WL_CRITICAL);
 
		return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
		item->status = NGLS_TOO_OLD;
 
	} else {
 
		item->status = NGLS_OFFLINE;
 
	}
 

	
 
	ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
 
	return NETWORK_RECV_STATUS_SERVER_ERROR;
 
	UpdateNetworkGameWindow();
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
/**
 
 * Check if any query needs to send or receive.
 
 */
 
/* static */ void QueryNetworkGameSocketHandler::SendReceive()
0 comments (0 inline, 0 general)