mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-10 08:00:05 +00:00
Add: use Game Coordinator to annouce public servers
This commit is contained in:
parent
e1e2212e0e
commit
b1280fd17e
@ -1995,7 +1995,7 @@ STR_FACE_TIE :Tie:
|
||||
STR_FACE_EARRING :Earring:
|
||||
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Change tie or earring
|
||||
|
||||
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Private
|
||||
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
|
||||
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Public
|
||||
|
||||
# Network server list
|
||||
@ -2136,6 +2136,8 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Edit the
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Name of the server
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibility
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Whether other people can see your server in the public listing
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Connection type
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Whether and how your server can be reached by others
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Player
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Name
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Your player name
|
||||
@ -2154,6 +2156,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game
|
||||
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies}
|
||||
|
||||
############ Begin of ConnectionType
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Local
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Remote players can't connect
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Public
|
||||
############ End of ConnectionType
|
||||
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete
|
||||
@ -2281,6 +2289,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The serv
|
||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
|
||||
STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING})
|
||||
|
||||
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Server registration failed
|
||||
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Your server doesn't allow remote connections
|
||||
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Other players won't be able to connect to your server
|
||||
|
||||
# Content downloading window
|
||||
STR_CONTENT_TITLE :{WHITE}Content downloading
|
||||
STR_CONTENT_TYPE_CAPTION :{BLACK}Type
|
||||
|
@ -14,6 +14,8 @@ add_files(
|
||||
network_content.h
|
||||
network_content_gui.cpp
|
||||
network_content_gui.h
|
||||
network_coordinator.cpp
|
||||
network_coordinator.h
|
||||
network_func.h
|
||||
network_gamelist.cpp
|
||||
network_gamelist.h
|
||||
|
@ -20,6 +20,8 @@ add_files(
|
||||
tcp_content.cpp
|
||||
tcp_content.h
|
||||
tcp_content_type.h
|
||||
tcp_coordinator.cpp
|
||||
tcp_coordinator.h
|
||||
tcp_game.cpp
|
||||
tcp_game.h
|
||||
tcp_http.cpp
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
/** DNS hostname of the masterserver */
|
||||
static const char * const NETWORK_MASTER_SERVER_HOST = "master.openttd.org";
|
||||
/** DNS hostname of the Game Coordinator server */
|
||||
static const char * const NETWORK_COORDINATOR_SERVER_HOST = "coordinator.openttd.org";
|
||||
/** DNS hostname of the content server */
|
||||
static const char * const NETWORK_CONTENT_SERVER_HOST = "content.openttd.org";
|
||||
/** DNS hostname of the HTTP-content mirror server */
|
||||
@ -23,14 +25,15 @@ static const char * const NETWORK_CONTENT_MIRROR_URL = "/bananas";
|
||||
/** Message sent to the masterserver to 'identify' this client as OpenTTD */
|
||||
static const char * const NETWORK_MASTER_SERVER_WELCOME_MESSAGE = "OpenTTDRegister";
|
||||
|
||||
static const uint16 NETWORK_MASTER_SERVER_PORT = 3978; ///< The default port of the master server (UDP)
|
||||
static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
|
||||
static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP)
|
||||
static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
|
||||
static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
|
||||
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
|
||||
static const uint16 NETWORK_MASTER_SERVER_PORT = 3978; ///< The default port of the master server (UDP)
|
||||
static const uint16 NETWORK_COORDINATOR_SERVER_PORT = 3976; ///< The default port of the Game Coordinator server (TCP)
|
||||
static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
|
||||
static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP)
|
||||
static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
|
||||
static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
|
||||
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
|
||||
|
||||
static const uint16 UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
|
||||
static const uint16 UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
|
||||
/*
|
||||
* Technically a TCP packet could become 64kiB, however the high bit is kept so it becomes possible in the future
|
||||
* to go to (significantly) larger packets if needed. This would entail a strategy such as employed for UTF-8.
|
||||
@ -45,40 +48,42 @@ static const uint16 UDP_MTU = 1460; ///< Number of
|
||||
* Send_uint16(GB(size, 16, 14) | 0b10 << 14)
|
||||
* Send_uint16(GB(size, 0, 16))
|
||||
*/
|
||||
static const uint16 TCP_MTU = 32767; ///< Number of bytes we can pack in a single TCP packet
|
||||
static const uint16 COMPAT_MTU = 1460; ///< Number of bytes we can pack in a single packet for backward compatibility
|
||||
static const uint16 TCP_MTU = 32767; ///< Number of bytes we can pack in a single TCP packet
|
||||
static const uint16 COMPAT_MTU = 1460; ///< Number of bytes we can pack in a single packet for backward compatibility
|
||||
|
||||
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
|
||||
static const byte NETWORK_GAME_INFO_VERSION = 4; ///< 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_MASTER_SERVER_VERSION = 2; ///< What version of master-server-protocol do we use?
|
||||
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
|
||||
static const byte NETWORK_GAME_INFO_VERSION = 4; ///< 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_MASTER_SERVER_VERSION = 2; ///< What version of master-server-protocol do we use?
|
||||
static const byte NETWORK_COORDINATOR_VERSION = 1; ///< 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'
|
||||
static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0'
|
||||
static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
|
||||
static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0'
|
||||
static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0'
|
||||
static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
|
||||
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
|
||||
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
|
||||
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
|
||||
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
|
||||
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
|
||||
static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_NAME_LENGTH = 32; ///< The maximum length of a content's name, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_VERSION_LENGTH = 16; ///< The maximum length of a content's version, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_URL_LENGTH = 96; ///< The maximum length of a content's url, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_DESC_LENGTH = 512; ///< The maximum length of a content's description, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_TAG_LENGTH = 32; ///< The maximum length of a content's tag, in bytes including '\0'.
|
||||
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'
|
||||
static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0'
|
||||
static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
|
||||
static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0'
|
||||
static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0'
|
||||
static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
|
||||
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
|
||||
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
|
||||
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
|
||||
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
|
||||
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
|
||||
static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_NAME_LENGTH = 32; ///< The maximum length of a content's name, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_VERSION_LENGTH = 16; ///< The maximum length of a content's version, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_URL_LENGTH = 96; ///< The maximum length of a content's url, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_DESC_LENGTH = 512; ///< The maximum length of a content's description, in bytes including '\0'.
|
||||
static const uint NETWORK_CONTENT_TAG_LENGTH = 32; ///< The maximum length of a content's tag, in bytes including '\0'.
|
||||
static const uint NETWORK_ERROR_DETAIL_LENGTH = 100; ///< The maximum length of the error detail, in bytes including '\0'
|
||||
|
||||
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
||||
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
||||
|
||||
/**
|
||||
* Maximum number of GRFs that can be sent.
|
||||
* This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of UDP_MTU bytes.
|
||||
*/
|
||||
static const uint NETWORK_MAX_GRF_COUNT = 62;
|
||||
static const uint NETWORK_MAX_GRF_COUNT = 62;
|
||||
|
||||
/**
|
||||
* The number of landscapes in OpenTTD.
|
||||
@ -88,6 +93,6 @@ static const uint NETWORK_MAX_GRF_COUNT = 62;
|
||||
* there is a compile assertion to check that this NUM_LANDSCAPE is equal
|
||||
* to NETWORK_NUM_LANDSCAPES.
|
||||
*/
|
||||
static const uint NETWORK_NUM_LANDSCAPES = 4;
|
||||
static const uint NETWORK_NUM_LANDSCAPES = 4;
|
||||
|
||||
#endif /* NETWORK_CORE_CONFIG_H */
|
||||
|
80
src/network/core/tcp_coordinator.cpp
Normal file
80
src/network/core/tcp_coordinator.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tcp_coordinator.cpp Basic functions to receive and send Game Coordinator packets.
|
||||
*/
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "../../date_func.h"
|
||||
#include "../../debug.h"
|
||||
#include "tcp_coordinator.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/**
|
||||
* Handle the given packet, i.e. pass it to the right.
|
||||
* parser receive command.
|
||||
* @param p The packet to handle.
|
||||
* @return True iff we should immediately handle further packets.
|
||||
*/
|
||||
bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *p)
|
||||
{
|
||||
PacketCoordinatorType type = (PacketCoordinatorType)p->Recv_uint8();
|
||||
|
||||
switch (type) {
|
||||
case PACKET_COORDINATOR_GC_ERROR: return this->Receive_GC_ERROR(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);
|
||||
|
||||
default:
|
||||
Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a packet at TCP level.
|
||||
* @return Whether at least one packet was received.
|
||||
*/
|
||||
bool NetworkCoordinatorSocketHandler::ReceivePackets()
|
||||
{
|
||||
/*
|
||||
* We read only a few of the packets. This allows the GUI to update when
|
||||
* a large set of servers is being received. Otherwise the interface
|
||||
* "hangs" while the game is updating the server-list.
|
||||
*
|
||||
* What arbitrary number to choose is the ultimate question though.
|
||||
*/
|
||||
Packet *p;
|
||||
static const int MAX_PACKETS_TO_RECEIVE = 42;
|
||||
int i = MAX_PACKETS_TO_RECEIVE;
|
||||
while (--i != 0 && (p = this->ReceivePacket()) != nullptr) {
|
||||
bool cont = this->HandlePacket(p);
|
||||
delete p;
|
||||
if (!cont) return true;
|
||||
}
|
||||
|
||||
return i != MAX_PACKETS_TO_RECEIVE - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for logging receiving invalid packets.
|
||||
* @param type The received packet type.
|
||||
* @return Always false, as it's an error.
|
||||
*/
|
||||
bool NetworkCoordinatorSocketHandler::ReceiveInvalidPacket(PacketCoordinatorType type)
|
||||
{
|
||||
Debug(net, 0, "[tcp/coordinator] Received illegal packet type {}", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_ERROR); }
|
||||
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); }
|
115
src/network/core/tcp_coordinator.h
Normal file
115
src/network/core/tcp_coordinator.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tcp_coordinator.h Basic functions to receive and send TCP packets to/from the Game Coordinator server.
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_CORE_TCP_COORDINATOR_H
|
||||
#define NETWORK_CORE_TCP_COORDINATOR_H
|
||||
|
||||
#include "os_abstraction.h"
|
||||
#include "tcp.h"
|
||||
#include "packet.h"
|
||||
#include "game_info.h"
|
||||
|
||||
/**
|
||||
* Enum with all types of TCP Game Coordinator packets. The order MUST not be changed.
|
||||
*
|
||||
* GC -> packets from Game Coordinator to either Client or Server.
|
||||
* SERVER -> packets from Server to Game Coordinator.
|
||||
* CLIENT -> packets from Client to Game Coordinator.
|
||||
**/
|
||||
enum PacketCoordinatorType {
|
||||
PACKET_COORDINATOR_GC_ERROR, ///< Game Coordinator indicates there was an error.
|
||||
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_END, ///< Must ALWAYS be on the end of this list!! (period).
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of connection the Game Coordinator can detect we have.
|
||||
*/
|
||||
enum ConnectionType {
|
||||
CONNECTION_TYPE_UNKNOWN, ///< The Game Coordinator hasn't informed us yet what type of connection we have.
|
||||
CONNECTION_TYPE_ISOLATED, ///< The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
|
||||
CONNECTION_TYPE_DIRECT, ///< The Game Coordinator can directly connect to your server.
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
};
|
||||
|
||||
/** Base socket handler for all Game Coordinator TCP sockets. */
|
||||
class NetworkCoordinatorSocketHandler : public NetworkTCPSocketHandler {
|
||||
protected:
|
||||
bool ReceiveInvalidPacket(PacketCoordinatorType type);
|
||||
|
||||
/**
|
||||
* Game Coordinator indicates there was an error. This can either be a
|
||||
* permanent error causing the connection to be dropped, or in response
|
||||
* to a request that is invalid.
|
||||
*
|
||||
* uint8 Type of error (see NetworkCoordinatorErrorType).
|
||||
* string Details of the error.
|
||||
*
|
||||
* @param p The packet that was just received.
|
||||
* @return True upon success, otherwise false.
|
||||
*/
|
||||
virtual bool Receive_GC_ERROR(Packet *p);
|
||||
|
||||
/**
|
||||
* Server is starting a multiplayer game and wants to let the
|
||||
* Game Coordinator know.
|
||||
*
|
||||
* uint8 Game Coordinator protocol version.
|
||||
* uint8 Type of game (see ServerGameType).
|
||||
* uint16 Local port of the server.
|
||||
*
|
||||
* @param p The packet that was just received.
|
||||
* @return True upon success, otherwise false.
|
||||
*/
|
||||
virtual bool Receive_SERVER_REGISTER(Packet *p);
|
||||
|
||||
/**
|
||||
* Game Coordinator acknowledges the registration.
|
||||
*
|
||||
* uint8 Type of connection was detected (see ConnectionType).
|
||||
*
|
||||
* @param p The packet that was just received.
|
||||
* @return True upon success, otherwise false.
|
||||
*/
|
||||
virtual bool Receive_GC_REGISTER_ACK(Packet *p);
|
||||
|
||||
/**
|
||||
* Send an update of the current state of the server to the Game Coordinator.
|
||||
*
|
||||
* uint8 Game Coordinator protocol version.
|
||||
* 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_SERVER_UPDATE(Packet *p);
|
||||
|
||||
bool HandlePacket(Packet *p);
|
||||
public:
|
||||
/**
|
||||
* Create a new cs socket handler for a given cs.
|
||||
* @param s The socket we are connected with.
|
||||
*/
|
||||
NetworkCoordinatorSocketHandler(SOCKET s = INVALID_SOCKET) : NetworkTCPSocketHandler(s) {}
|
||||
|
||||
bool ReceivePackets();
|
||||
};
|
||||
|
||||
#endif /* NETWORK_CORE_TCP_COORDINATOR_H */
|
@ -19,6 +19,7 @@
|
||||
#include "network_udp.h"
|
||||
#include "network_gamelist.h"
|
||||
#include "network_base.h"
|
||||
#include "network_coordinator.h"
|
||||
#include "core/udp.h"
|
||||
#include "core/host.h"
|
||||
#include "network_gui.h"
|
||||
@ -591,6 +592,8 @@ void NetworkClose(bool close_admins)
|
||||
}
|
||||
ServerNetworkGameSocketHandler::CloseListeners();
|
||||
ServerNetworkAdminSocketHandler::CloseListeners();
|
||||
|
||||
_network_coordinator_client.CloseConnection();
|
||||
} else if (MyClient::my_client != nullptr) {
|
||||
MyClient::SendQuit();
|
||||
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||
@ -932,6 +935,10 @@ bool NetworkServerStart()
|
||||
|
||||
NetworkInitGameInfo();
|
||||
|
||||
if (_settings_client.network.server_advertise) {
|
||||
_network_coordinator_client.Register();
|
||||
}
|
||||
|
||||
/* execute server initialization script */
|
||||
IConsoleCmdExec("exec scripts/on_server.scr 0");
|
||||
/* if the server is dedicated ... add some other script */
|
||||
@ -1032,6 +1039,7 @@ static void NetworkSend()
|
||||
void NetworkBackgroundLoop()
|
||||
{
|
||||
_network_content_client.SendReceive();
|
||||
_network_coordinator_client.SendReceive();
|
||||
TCPConnecter::CheckCallbacks();
|
||||
NetworkHTTPSocketHandler::HTTPReceive();
|
||||
|
||||
|
234
src/network/network_coordinator.cpp
Normal file
234
src/network/network_coordinator.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file network_coordinator.cpp Game Coordinator sending/receiving part of the network protocol. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../debug.h"
|
||||
#include "../error.h"
|
||||
#include "../rev.h"
|
||||
#include "../settings_type.h"
|
||||
#include "../strings_func.h"
|
||||
#include "../window_func.h"
|
||||
#include "../window_type.h"
|
||||
#include "network.h"
|
||||
#include "network_coordinator.h"
|
||||
#include "network_gamelist.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES = std::chrono::seconds(30); ///< How many time between updates the server sends to the Game Coordinator.
|
||||
ClientNetworkCoordinatorSocketHandler _network_coordinator_client; ///< The connection to the Game Coordinator.
|
||||
ConnectionType _network_server_connection_type = CONNECTION_TYPE_UNKNOWN; ///< What type of connection the Game Coordinator detected we are on.
|
||||
|
||||
/** Connect to the Game Coordinator server. */
|
||||
class NetworkCoordinatorConnecter : TCPConnecter {
|
||||
public:
|
||||
/**
|
||||
* Initiate the connecting.
|
||||
* @param address The address of the Game Coordinator server.
|
||||
*/
|
||||
NetworkCoordinatorConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_COORDINATOR_SERVER_PORT) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
_network_coordinator_client.connecting = false;
|
||||
_network_coordinator_client.CloseConnection(true);
|
||||
}
|
||||
|
||||
void OnConnect(SOCKET s) override
|
||||
{
|
||||
assert(_network_coordinator_client.sock == INVALID_SOCKET);
|
||||
|
||||
_network_coordinator_client.sock = s;
|
||||
_network_coordinator_client.connecting = false;
|
||||
}
|
||||
};
|
||||
|
||||
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
|
||||
{
|
||||
NetworkCoordinatorErrorType error = (NetworkCoordinatorErrorType)p->Recv_uint8();
|
||||
std::string detail = p->Recv_string(NETWORK_ERROR_DETAIL_LENGTH);
|
||||
|
||||
switch (error) {
|
||||
case NETWORK_COORDINATOR_ERROR_UNKNOWN:
|
||||
this->CloseConnection();
|
||||
return false;
|
||||
|
||||
case NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED:
|
||||
SetDParamStr(0, detail);
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
|
||||
|
||||
/* To prevent that we constantly try to reconnect, switch to private game. */
|
||||
_settings_client.network.server_advertise = false;
|
||||
|
||||
this->CloseConnection();
|
||||
return false;
|
||||
|
||||
default:
|
||||
Debug(net, 0, "Invalid error type {} received from Game Coordinator", error);
|
||||
this->CloseConnection();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p)
|
||||
{
|
||||
/* Schedule sending an update. */
|
||||
this->next_update = std::chrono::steady_clock::now();
|
||||
|
||||
_network_server_connection_type = (ConnectionType)p->Recv_uint8();
|
||||
|
||||
if (_network_server_connection_type == CONNECTION_TYPE_ISOLATED) {
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_ISOLATED, STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL, WL_ERROR);
|
||||
}
|
||||
|
||||
SetWindowDirty(WC_CLIENT_LIST, 0);
|
||||
|
||||
if (_network_dedicated) {
|
||||
std::string connection_type;
|
||||
switch (_network_server_connection_type) {
|
||||
case CONNECTION_TYPE_ISOLATED: connection_type = "Remote players can't connect"; break;
|
||||
case CONNECTION_TYPE_DIRECT: connection_type = "Public"; break;
|
||||
|
||||
case CONNECTION_TYPE_UNKNOWN: // Never returned from Game Coordinator.
|
||||
default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
|
||||
}
|
||||
|
||||
Debug(net, 3, "----------------------------------------");
|
||||
Debug(net, 3, "Your server is now registered with the Game Coordinator:");
|
||||
Debug(net, 3, " Game type: Public");
|
||||
Debug(net, 3, " Connection type: {}", connection_type);
|
||||
Debug(net, 3, "----------------------------------------");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientNetworkCoordinatorSocketHandler::Connect()
|
||||
{
|
||||
/* We are either already connected or are trying to connect. */
|
||||
if (this->sock != INVALID_SOCKET || this->connecting) return;
|
||||
|
||||
this->Reopen();
|
||||
|
||||
this->connecting = true;
|
||||
new NetworkCoordinatorConnecter(NETWORK_COORDINATOR_SERVER_HOST);
|
||||
}
|
||||
|
||||
NetworkRecvStatus ClientNetworkCoordinatorSocketHandler::CloseConnection(bool error)
|
||||
{
|
||||
NetworkCoordinatorSocketHandler::CloseConnection(error);
|
||||
|
||||
this->CloseSocket();
|
||||
this->connecting = false;
|
||||
|
||||
_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
|
||||
this->next_update = {};
|
||||
|
||||
SetWindowDirty(WC_CLIENT_LIST, 0);
|
||||
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our server to receive our join-key.
|
||||
*/
|
||||
void ClientNetworkCoordinatorSocketHandler::Register()
|
||||
{
|
||||
_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
|
||||
this->next_update = {};
|
||||
|
||||
SetWindowDirty(WC_CLIENT_LIST, 0);
|
||||
|
||||
this->Connect();
|
||||
|
||||
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_REGISTER);
|
||||
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
|
||||
p->Send_uint8(SERVER_GAME_TYPE_PUBLIC);
|
||||
p->Send_uint16(_settings_client.network.server_port);
|
||||
|
||||
this->SendPacket(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an update of our server status to the Game Coordinator.
|
||||
*/
|
||||
void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
|
||||
{
|
||||
Debug(net, 6, "Sending server update to Game Coordinator");
|
||||
this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
|
||||
|
||||
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_UPDATE);
|
||||
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
|
||||
SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo());
|
||||
|
||||
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.
|
||||
*/
|
||||
void ClientNetworkCoordinatorSocketHandler::SendReceive()
|
||||
{
|
||||
/* Private games are not listed via the Game Coordinator. */
|
||||
if (_network_server && !_settings_client.network.server_advertise) {
|
||||
if (this->sock != INVALID_SOCKET) {
|
||||
this->CloseConnection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int last_attempt_backoff = 1;
|
||||
static bool first_reconnect = true;
|
||||
|
||||
if (this->sock == INVALID_SOCKET) {
|
||||
static std::chrono::steady_clock::time_point last_attempt = {};
|
||||
|
||||
/* Don't auto-reconnect when we are not a server. */
|
||||
if (!_network_server) return;
|
||||
/* Don't reconnect if we are connecting. */
|
||||
if (this->connecting) return;
|
||||
/* Throttle how often we try to reconnect. */
|
||||
if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff) return;
|
||||
|
||||
last_attempt = std::chrono::steady_clock::now();
|
||||
/* Delay reconnecting with up to 32 seconds. */
|
||||
if (last_attempt_backoff < 32) {
|
||||
last_attempt_backoff *= 2;
|
||||
}
|
||||
|
||||
/* Do not reconnect on the first attempt, but only initialize the
|
||||
* last_attempt variables. Otherwise after an outage all servers
|
||||
* reconnect at the same time, potentially overwhelming the
|
||||
* Game Coordinator. */
|
||||
if (first_reconnect) {
|
||||
first_reconnect = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Debug(net, 1, "Connection with Game Coordinator lost; reconnecting...");
|
||||
this->Register();
|
||||
return;
|
||||
}
|
||||
|
||||
last_attempt_backoff = 1;
|
||||
first_reconnect = true;
|
||||
|
||||
if (_network_server && _network_server_connection_type != CONNECTION_TYPE_UNKNOWN && std::chrono::steady_clock::now() > this->next_update) {
|
||||
this->SendServerUpdate();
|
||||
}
|
||||
|
||||
if (this->CanSendReceive()) {
|
||||
this->ReceivePackets();
|
||||
}
|
||||
|
||||
this->SendPackets();
|
||||
}
|
51
src/network/network_coordinator.h
Normal file
51
src/network/network_coordinator.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file network_coordinator.h Part of the network protocol handling Game Coordinator requests. */
|
||||
|
||||
#ifndef NETWORK_COORDINATOR_H
|
||||
#define NETWORK_COORDINATOR_H
|
||||
|
||||
#include "core/tcp_coordinator.h"
|
||||
|
||||
/**
|
||||
* Game Coordinator communication.
|
||||
*
|
||||
* For servers:
|
||||
* - Server sends SERVER_REGISTER.
|
||||
* - 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.
|
||||
*/
|
||||
|
||||
/** Class for handling the client side of the Game Coordinator connection. */
|
||||
class ClientNetworkCoordinatorSocketHandler : public NetworkCoordinatorSocketHandler {
|
||||
private:
|
||||
std::chrono::steady_clock::time_point next_update; ///< When to send the next update (if server and public).
|
||||
|
||||
protected:
|
||||
bool Receive_GC_ERROR(Packet *p) override;
|
||||
bool Receive_GC_REGISTER_ACK(Packet *p) override;
|
||||
|
||||
public:
|
||||
bool connecting; ///< Are we connecting to the Game Coordinator?
|
||||
|
||||
ClientNetworkCoordinatorSocketHandler() : connecting(false) {}
|
||||
|
||||
NetworkRecvStatus CloseConnection(bool error = true) override;
|
||||
void SendReceive();
|
||||
|
||||
void Connect();
|
||||
|
||||
void Register();
|
||||
void SendServerUpdate();
|
||||
};
|
||||
|
||||
extern ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
|
||||
|
||||
#endif /* NETWORK_COORDINATOR_H */
|
@ -62,7 +62,7 @@ static CompanyID _admin_company_id = INVALID_COMPANY; ///< For what company a co
|
||||
* do not.
|
||||
*/
|
||||
static const StringID _server_visibility_dropdown[] = {
|
||||
STR_NETWORK_SERVER_VISIBILITY_PRIVATE,
|
||||
STR_NETWORK_SERVER_VISIBILITY_LOCAL,
|
||||
STR_NETWORK_SERVER_VISIBILITY_PUBLIC,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
@ -1607,21 +1607,26 @@ static const NWidgetPart _nested_client_list_widgets[] = {
|
||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER, STR_NULL), SetPadding(4, 4, 0, 4), SetPIP(0, 2, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_NAME, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(10, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_SERVER_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(20, 0), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_CL_SERVER_VISIBILITY), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(10, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_CONNECTION_TYPE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_NETWORK_CLIENT_LIST_PLAYER, STR_NULL), SetPadding(4, 4, 4, 4), SetPIP(0, 2, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_PLAYER_NAME, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(20, 0),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(10, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_CLIENT_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP),
|
||||
EndContainer(),
|
||||
@ -2050,6 +2055,10 @@ public:
|
||||
SetDParam(0, _server_visibility_dropdown[_settings_client.network.server_advertise]);
|
||||
break;
|
||||
|
||||
case WID_CL_SERVER_CONNECTION_TYPE:
|
||||
SetDParam(0, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN + _network_server_connection_type);
|
||||
break;
|
||||
|
||||
case WID_CL_CLIENT_NAME:
|
||||
SetDParamStr(0, _settings_client.network.client_name);
|
||||
break;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define NETWORK_INTERNAL_H
|
||||
|
||||
#include "network_func.h"
|
||||
#include "core/tcp_coordinator.h"
|
||||
#include "core/tcp_game.h"
|
||||
|
||||
#include "../command_type.h"
|
||||
@ -82,6 +83,7 @@ extern NetworkJoinStatus _network_join_status;
|
||||
extern uint8 _network_join_waiting;
|
||||
extern uint32 _network_join_bytes;
|
||||
extern uint32 _network_join_bytes_total;
|
||||
extern ConnectionType _network_server_connection_type;
|
||||
|
||||
extern uint8 _network_reconnect;
|
||||
|
||||
|
@ -35,6 +35,15 @@ enum NetworkVehicleType {
|
||||
NETWORK_VEH_END
|
||||
};
|
||||
|
||||
/**
|
||||
* Game type the server can be using.
|
||||
* Used on the network protocol to communicate with Game Coordinator.
|
||||
*/
|
||||
enum ServerGameType : uint8 {
|
||||
SERVER_GAME_TYPE_LOCAL = 0,
|
||||
SERVER_GAME_TYPE_PUBLIC,
|
||||
};
|
||||
|
||||
/** 'Unique' identifier to be given to clients */
|
||||
enum ClientID : uint32 {
|
||||
INVALID_CLIENT_ID = 0, ///< Client is not part of anything
|
||||
|
@ -101,6 +101,7 @@ enum ClientListWidgets {
|
||||
WID_CL_SERVER_NAME, ///< Server name.
|
||||
WID_CL_SERVER_NAME_EDIT, ///< Edit button for server name.
|
||||
WID_CL_SERVER_VISIBILITY, ///< Server visibility.
|
||||
WID_CL_SERVER_CONNECTION_TYPE, ///< The type of connection the Game Coordinator detected for this server.
|
||||
WID_CL_CLIENT_NAME, ///< Client name.
|
||||
WID_CL_CLIENT_NAME_EDIT, ///< Edit button for client name.
|
||||
WID_CL_MATRIX, ///< Company/client list.
|
||||
|
Loading…
Reference in New Issue
Block a user