Merge tag '12.0-beta2' into jgrpp-beta
# Conflicts: # docs/landscape_grid.html # src/lang/simplified_chinese.txt # src/network/network_server.cpp # src/station_cmd.cpp
This commit is contained in:
@@ -51,7 +51,7 @@ static const uint16 COMPAT_MTU = 1460; ///< Numbe
|
||||
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
|
||||
static const byte NETWORK_GAME_INFO_VERSION = 6; ///< What version of game-info do we use?
|
||||
static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this?
|
||||
static const byte NETWORK_COORDINATOR_VERSION = 5; ///< What version of game-coordinator-protocol do we use?
|
||||
static const byte NETWORK_COORDINATOR_VERSION = 6; ///< What version of game-coordinator-protocol do we use?
|
||||
|
||||
static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0'
|
||||
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
|
||||
|
@@ -61,9 +61,10 @@ enum ConnectionType {
|
||||
* The type of error from the Game Coordinator.
|
||||
*/
|
||||
enum NetworkCoordinatorErrorType {
|
||||
NETWORK_COORDINATOR_ERROR_UNKNOWN, ///< There was an unknown error.
|
||||
NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED, ///< Your request for registration failed.
|
||||
NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE, ///< The invite code given is invalid.
|
||||
NETWORK_COORDINATOR_ERROR_UNKNOWN, ///< There was an unknown error.
|
||||
NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED, ///< Your request for registration failed.
|
||||
NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE, ///< The invite code given is invalid.
|
||||
NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE, ///< The invite code is used by another (newer) server.
|
||||
};
|
||||
|
||||
/** Base socket handler for all Game Coordinator TCP sockets. */
|
||||
|
@@ -135,8 +135,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
|
||||
return false;
|
||||
|
||||
case NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED:
|
||||
SetDParamStr(0, detail);
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, INVALID_STRING_ID, WL_ERROR);
|
||||
|
||||
/* To prevent that we constantly try to reconnect, switch to local game. */
|
||||
_settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
|
||||
@@ -159,6 +158,15 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
|
||||
return true;
|
||||
}
|
||||
|
||||
case NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE:
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE, INVALID_STRING_ID, WL_ERROR);
|
||||
|
||||
/* To prevent that we constantly battle for the same invite-code, switch to local game. */
|
||||
_settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
|
||||
|
||||
this->CloseConnection();
|
||||
return false;
|
||||
|
||||
default:
|
||||
DEBUG(net, 0, "Invalid error type %u received from Game Coordinator", error);
|
||||
this->CloseConnection();
|
||||
@@ -271,7 +279,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet *p)
|
||||
}
|
||||
|
||||
/* Now store it based on the token. */
|
||||
this->connecter[token] = connecter_pre_it->second;
|
||||
this->connecter[token] = {invite_code, connecter_pre_it->second};
|
||||
this->connecter_pre.erase(connecter_pre_it);
|
||||
|
||||
return true;
|
||||
@@ -373,13 +381,20 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_TURN_CONNECT(Packet *p)
|
||||
this->turn_handlers[token] = ClientNetworkTurnSocketHandler::Turn(token, tracking_number, ticket, connection_string);
|
||||
|
||||
if (!_network_server) {
|
||||
auto connecter_it = this->connecter.find(token);
|
||||
if (connecter_it == this->connecter.end()) {
|
||||
/* Make sure we are still interested in connecting to this server. */
|
||||
this->ConnectFailure(token, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (_settings_client.network.use_relay_service) {
|
||||
case URS_NEVER:
|
||||
this->ConnectFailure(token, 0);
|
||||
break;
|
||||
|
||||
case URS_ASK:
|
||||
ShowNetworkAskRelay(connection_string, token);
|
||||
ShowNetworkAskRelay(connecter_it->second.first, connection_string, token);
|
||||
break;
|
||||
|
||||
case URS_ALLOW:
|
||||
@@ -571,7 +586,7 @@ void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &to
|
||||
* processes of connecting us. */
|
||||
auto connecter_it = this->connecter.find(token);
|
||||
if (connecter_it != this->connecter.end()) {
|
||||
connecter_it->second->SetConnected(sock);
|
||||
connecter_it->second.second->SetConnected(sock);
|
||||
this->connecter.erase(connecter_it);
|
||||
}
|
||||
}
|
||||
@@ -657,7 +672,7 @@ void ClientNetworkCoordinatorSocketHandler::CloseToken(const std::string &token)
|
||||
/* Close the caller of the connection attempt. */
|
||||
auto connecter_it = this->connecter.find(token);
|
||||
if (connecter_it != this->connecter.end()) {
|
||||
connecter_it->second->SetFailure();
|
||||
connecter_it->second.second->SetFailure();
|
||||
this->connecter.erase(connecter_it);
|
||||
}
|
||||
}
|
||||
@@ -677,7 +692,7 @@ void ClientNetworkCoordinatorSocketHandler::CloseAllConnections()
|
||||
for (auto &[token, it] : this->connecter) {
|
||||
this->CloseStunHandler(token);
|
||||
this->CloseTurnHandler(token);
|
||||
it->SetFailure();
|
||||
it.second->SetFailure();
|
||||
|
||||
/* Inform the Game Coordinator he can stop trying to connect us to the server. */
|
||||
this->ConnectFailure(token, 0);
|
||||
|
@@ -54,7 +54,7 @@
|
||||
class ClientNetworkCoordinatorSocketHandler : public NetworkCoordinatorSocketHandler {
|
||||
private:
|
||||
std::chrono::steady_clock::time_point next_update; ///< When to send the next update (if server and public).
|
||||
std::map<std::string, TCPServerConnecter *> connecter; ///< Based on tokens, the current connecters that are pending.
|
||||
std::map<std::string, std::pair<std::string, TCPServerConnecter *>> connecter; ///< Based on tokens, the current (invite-code, connecter) that are pending.
|
||||
std::map<std::string, TCPServerConnecter *> connecter_pre; ///< Based on invite codes, the current connecters that are pending.
|
||||
std::map<std::string, std::map<int, std::unique_ptr<ClientNetworkStunSocketHandler>>> stun_handlers; ///< All pending STUN handlers, stored by token:family.
|
||||
std::map<std::string, std::unique_ptr<ClientNetworkTurnSocketHandler>> turn_handlers; ///< Pending TURN handler (if any), stored by token.
|
||||
|
@@ -2094,7 +2094,7 @@ public:
|
||||
this->DrawCompany(c->index, r.left, r.right, r.top, line);
|
||||
}
|
||||
|
||||
/* Specators */
|
||||
/* Spectators */
|
||||
this->DrawCompany(COMPANY_SPECTATOR, r.left, r.right, r.top, line);
|
||||
|
||||
break;
|
||||
@@ -2376,13 +2376,18 @@ void ShowNetworkCompanyPasswordWindow(Window *parent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Window used for asking the user if he is okay using a TURN server.
|
||||
* Window used for asking the user if he is okay using a relay server.
|
||||
*/
|
||||
struct NetworkAskRelayWindow : public Window {
|
||||
std::string connection_string; ///< The TURN server we want to connect to.
|
||||
std::string token; ///< The token for this connection.
|
||||
std::string server_connection_string; ///< The game server we want to connect to.
|
||||
std::string relay_connection_string; ///< The relay server we want to connect to.
|
||||
std::string token; ///< The token for this connection.
|
||||
|
||||
NetworkAskRelayWindow(WindowDesc *desc, Window *parent, const std::string &connection_string, const std::string &token) : Window(desc), connection_string(connection_string), token(token)
|
||||
NetworkAskRelayWindow(WindowDesc *desc, Window *parent, const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token) :
|
||||
Window(desc),
|
||||
server_connection_string(server_connection_string),
|
||||
relay_connection_string(relay_connection_string),
|
||||
token(token)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->InitNested(0);
|
||||
@@ -2415,7 +2420,8 @@ struct NetworkAskRelayWindow : public Window {
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_NAR_TEXT:
|
||||
SetDParamStr(0, this->connection_string);
|
||||
SetDParamStr(0, this->server_connection_string);
|
||||
SetDParamStr(1, this->relay_connection_string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2466,13 +2472,14 @@ static WindowDesc _network_ask_relay_desc(
|
||||
|
||||
/**
|
||||
* Show a modal confirmation window with "no" / "yes, once" / "yes, always" buttons.
|
||||
* @param connection_string The relay server we want to connect to.
|
||||
* @param server_connection_string The game server we want to connect to.
|
||||
* @param relay_connection_string The relay server we want to connect to.
|
||||
* @param token The token for this connection.
|
||||
*/
|
||||
void ShowNetworkAskRelay(const std::string &connection_string, const std::string &token)
|
||||
void ShowNetworkAskRelay(const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token)
|
||||
{
|
||||
DeleteWindowByClass(WC_NETWORK_ASK_RELAY);
|
||||
|
||||
Window *parent = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
new NetworkAskRelayWindow(&_network_ask_relay_desc, parent, connection_string, token);
|
||||
new NetworkAskRelayWindow(&_network_ask_relay_desc, parent, server_connection_string, relay_connection_string, token);
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ void ShowJoinStatusWindow();
|
||||
void ShowNetworkGameWindow();
|
||||
void ShowClientList();
|
||||
void ShowNetworkCompanyPasswordWindow(Window *parent);
|
||||
void ShowNetworkAskRelay(const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token);
|
||||
|
||||
|
||||
/** Company information stored at the client side */
|
||||
@@ -38,6 +39,5 @@ struct NetworkCompanyInfo : NetworkCompanyStats {
|
||||
std::string clients; ///< The clients that control this company (Name1, name2, ..)
|
||||
};
|
||||
|
||||
void ShowNetworkAskRelay(const std::string &connection_string, const std::string &token);
|
||||
|
||||
#endif /* NETWORK_GUI_H */
|
||||
|
@@ -1714,13 +1714,12 @@ static void NetworkAutoCleanCompanies()
|
||||
bool NetworkMakeClientNameUnique(std::string &name)
|
||||
{
|
||||
bool is_name_unique = false;
|
||||
uint number = 0;
|
||||
std::string original_name = name;
|
||||
|
||||
while (!is_name_unique) {
|
||||
for (uint number = 1; !is_name_unique && number <= MAX_CLIENTS; number++) { // Something's really wrong when there're more names than clients
|
||||
is_name_unique = true;
|
||||
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
|
||||
if (ci->client_name.compare(name) == 0) {
|
||||
if (ci->client_name == name) {
|
||||
/* Name already in use */
|
||||
is_name_unique = false;
|
||||
break;
|
||||
@@ -1729,7 +1728,7 @@ bool NetworkMakeClientNameUnique(std::string &name)
|
||||
/* Check if it is the same as the server-name */
|
||||
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
|
||||
if (ci != nullptr) {
|
||||
if (ci->client_name.compare(name) == 0) is_name_unique = false; // name already in use
|
||||
if (ci->client_name == name) is_name_unique = false; // name already in use
|
||||
}
|
||||
|
||||
if (!is_name_unique) {
|
||||
@@ -1833,10 +1832,10 @@ void NetworkServer_Tick(bool send_frame)
|
||||
/* Client did still not report in within the specified limit. */
|
||||
IConsolePrintF(CC_ERROR, cs->last_packet + std::chrono::milliseconds(lag * MILLISECONDS_PER_TICK) > std::chrono::steady_clock::now() ?
|
||||
/* A packet was received in the last three game days, so the client is likely lagging behind. */
|
||||
"Client #%d is dropped because the client's game state is more than %d ticks behind" :
|
||||
"Client #%d (IP: %s) is dropped because the client's game state is more than %d ticks behind" :
|
||||
/* No packet was received in the last three game days; sounds like a lost connection. */
|
||||
"Client #%d is dropped because the client did not respond for more than %d ticks",
|
||||
cs->client_id, lag);
|
||||
"Client #%d (IP: %s) is dropped because the client did not respond for more than %d ticks",
|
||||
cs->client_id, cs->GetClientIP(), lag);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
|
Reference in New Issue
Block a user