Merge remote-tracking branch 'upstream/master'

This commit is contained in:
pelya
2021-01-25 00:50:42 +02:00
1076 changed files with 25433 additions and 61762 deletions
+28
View File
@@ -0,0 +1,28 @@
add_subdirectory(core)
add_files(
network.cpp
network.h
network_admin.cpp
network_admin.h
network_base.h
network_chat_gui.cpp
network_client.cpp
network_client.h
network_command.cpp
network_content.cpp
network_content.h
network_content_gui.cpp
network_content_gui.h
network_func.h
network_gamelist.cpp
network_gamelist.h
network_gui.cpp
network_gui.h
network_internal.h
network_server.cpp
network_server.h
network_type.h
network_udp.cpp
network_udp.h
)
+27
View File
@@ -0,0 +1,27 @@
add_files(
address.cpp
address.h
config.h
core.cpp
core.h
game.h
host.cpp
host.h
os_abstraction.h
packet.cpp
packet.h
tcp.cpp
tcp.h
tcp_admin.cpp
tcp_admin.h
tcp_connect.cpp
tcp_content.cpp
tcp_content.h
tcp_game.cpp
tcp_game.h
tcp_http.cpp
tcp_http.h
tcp_listen.h
udp.cpp
udp.h
)
+28 -7
View File
@@ -96,12 +96,11 @@ void NetworkAddress::GetAddressAsString(char *buffer, const char *last, bool wit
* Get the address as a string, e.g. 127.0.0.1:12345.
* @param with_family whether to add the family (e.g. IPvX).
* @return the address
* @note NOT thread safe
*/
const char *NetworkAddress::GetAddressAsString(bool with_family)
std::string NetworkAddress::GetAddressAsString(bool with_family)
{
/* 6 = for the : and 5 for the decimal port number */
static char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7];
char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7];
this->GetAddressAsString(buf, lastof(buf), with_family);
return buf;
}
@@ -268,6 +267,18 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *
this->address_length = (int)runp->ai_addrlen;
assert(sizeof(this->address) >= runp->ai_addrlen);
memcpy(&this->address, runp->ai_addr, runp->ai_addrlen);
#ifdef __EMSCRIPTEN__
/* Emscripten doesn't zero sin_zero, but as we compare addresses
* to see if they are the same address, we need them to be zero'd.
* Emscripten is, as far as we know, the only OS not doing this.
*
* https://github.com/emscripten-core/emscripten/issues/12998
*/
if (this->address.ss_family == AF_INET) {
sockaddr_in *address_ipv4 = (sockaddr_in *)&this->address;
memset(address_ipv4->sin_zero, 0, sizeof(address_ipv4->sin_zero));
}
#endif
break;
}
@@ -289,7 +300,8 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
{
const char *type = NetworkAddress::SocketTypeAsString(runp->ai_socktype);
const char *family = NetworkAddress::AddressFamilyAsString(runp->ai_family);
const char *address = NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString();
char address[NETWORK_HOSTNAME_LENGTH + 6 + 7];
NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString(address, lastof(address));
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
if (sock == INVALID_SOCKET) {
@@ -299,7 +311,15 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
if (!SetNoDelay(sock)) DEBUG(net, 1, "[%s] setting TCP_NODELAY failed", type);
if (connect(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) {
int err = connect(sock, runp->ai_addr, (int)runp->ai_addrlen);
#ifdef __EMSCRIPTEN__
/* Emscripten is asynchronous, and as such a connect() is still in
* progress by the time the call returns. */
if (err != 0 && errno != EINPROGRESS)
#else
if (err != 0)
#endif
{
DEBUG(net, 1, "[%s] could not connect %s socket: %s", type, family, strerror(errno));
closesocket(sock);
return INVALID_SOCKET;
@@ -319,7 +339,7 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
*/
SOCKET NetworkAddress::Connect()
{
DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString());
DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString().c_str());
return this->Resolve(AF_UNSPEC, SOCK_STREAM, AI_ADDRCONFIG, nullptr, ConnectLoopProc);
}
@@ -333,7 +353,8 @@ static SOCKET ListenLoopProc(addrinfo *runp)
{
const char *type = NetworkAddress::SocketTypeAsString(runp->ai_socktype);
const char *family = NetworkAddress::AddressFamilyAsString(runp->ai_family);
const char *address = NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString();
char address[NETWORK_HOSTNAME_LENGTH + 6 + 7];
NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString(address, lastof(address));
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
if (sock == INVALID_SOCKET) {
+3 -1
View File
@@ -15,6 +15,8 @@
#include "../../string_func.h"
#include "../../core/smallmap_type.hpp"
#include <string>
class NetworkAddress;
typedef std::vector<NetworkAddress> NetworkAddressList; ///< Type for a list of addresses.
typedef SmallMap<NetworkAddress, SOCKET> SocketList; ///< Type for a mapping between address and socket.
@@ -91,7 +93,7 @@ public:
const char *GetHostname();
void GetAddressAsString(char *buffer, const char *last, bool with_family = true);
const char *GetAddressAsString(bool with_family = true);
std::string GetAddressAsString(bool with_family = true);
const sockaddr_storage *GetAddress();
/**
+45 -5
View File
@@ -83,6 +83,16 @@ typedef unsigned long in_addr_t;
# include <errno.h>
# include <sys/time.h>
# include <netdb.h>
# if defined(__EMSCRIPTEN__)
/* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
# undef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0
/* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
* https://github.com/emscripten-core/emscripten/issues/1711 */
# undef FD_SETSIZE
# define FD_SETSIZE 64
# endif
#endif /* UNIX */
/* OS/2 stuff */
@@ -141,6 +151,28 @@ typedef unsigned long in_addr_t;
#endif /* OS/2 */
#ifdef __EMSCRIPTEN__
/**
* Emscripten doesn't set 'addrlen' for accept(), getsockname(), getpeername()
* and recvfrom(), which confuses other functions and causes them to crash.
* This function needs to be called after these four functions to make sure
* 'addrlen' is patched up.
*
* https://github.com/emscripten-core/emscripten/issues/12996
*
* @param address The address returned by those four functions.
* @return The correct value for addrlen.
*/
static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address)
{
switch (address.ss_family) {
case AF_INET6: return sizeof(struct sockaddr_in6);
case AF_INET: return sizeof(struct sockaddr_in);
default: NOT_REACHED();
}
}
#endif
/**
* Try to set the socket into non-blocking mode.
* @param d The socket to set the non-blocking more for.
@@ -148,12 +180,16 @@ typedef unsigned long in_addr_t;
*/
static inline bool SetNonBlocking(SOCKET d)
{
#ifdef _WIN32
u_long nonblocking = 1;
#ifdef __EMSCRIPTEN__
return true;
#else
# ifdef _WIN32
u_long nonblocking = 1;
# else
int nonblocking = 1;
#endif
# endif
return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
#endif
}
/**
@@ -163,14 +199,18 @@ static inline bool SetNonBlocking(SOCKET d)
*/
static inline bool SetNoDelay(SOCKET d)
{
#ifdef __EMSCRIPTEN__
return true;
#else
/* XXX should this be done at all? */
int b = 1;
/* The (const char*) cast is needed for windows */
return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
#endif
}
/* Make sure these structures have the size we expect them to be */
assert_compile(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
assert_compile(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
static_assert(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
static_assert(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
+4 -2
View File
@@ -15,6 +15,8 @@
#include "address.h"
#include "packet.h"
#include <atomic>
/** The states of sending the packets. */
enum SendPacketsState {
SPS_CLOSED, ///< The connection got closed.
@@ -61,8 +63,8 @@ public:
*/
class TCPConnecter {
private:
bool connected; ///< Whether we succeeded in making the connection
bool aborted; ///< Whether we bailed out (i.e. connection making failed)
std::atomic<bool> connected;///< Whether we succeeded in making the connection
std::atomic<bool> aborted; ///< Whether we bailed out (i.e. connection making failed)
bool killed; ///< Whether we got killed
SOCKET sock; ///< The socket we're connecting with
+5 -4
View File
@@ -18,10 +18,10 @@
#include "../../safeguards.h"
/* Make sure that these enums match. */
assert_compile((int)CRR_MANUAL == (int)ADMIN_CRR_MANUAL);
assert_compile((int)CRR_AUTOCLEAN == (int)ADMIN_CRR_AUTOCLEAN);
assert_compile((int)CRR_BANKRUPT == (int)ADMIN_CRR_BANKRUPT);
assert_compile((int)CRR_END == (int)ADMIN_CRR_END);
static_assert((int)CRR_MANUAL == (int)ADMIN_CRR_MANUAL);
static_assert((int)CRR_AUTOCLEAN == (int)ADMIN_CRR_AUTOCLEAN);
static_assert((int)CRR_BANKRUPT == (int)ADMIN_CRR_BANKRUPT);
static_assert((int)CRR_END == (int)ADMIN_CRR_END);
/**
* Create the admin handler for the given socket.
@@ -115,6 +115,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets()
Packet *p;
while ((p = this->ReceivePacket()) != nullptr) {
NetworkRecvStatus res = this->HandlePacket(p);
delete p;
if (res != NETWORK_RECV_STATUS_OKAY) return res;
}
+2 -2
View File
@@ -134,7 +134,7 @@ protected:
/**
* Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet):
* uint16 Update type (see #AdminUpdateType).
* uint16 Update type (see #AdminUpdateType). Note integer type - see "Certain Packet Information" in docs/admin_network.md.
* uint16 Update frequency (see #AdminUpdateFrequency), setting #ADMIN_FREQUENCY_POLL is always ignored.
* @param p The packet that was just received.
* @return The state the network should have.
@@ -143,7 +143,7 @@ protected:
/**
* Poll the server for certain updates, an invalid poll (e.g. not existent id) gets silently dropped:
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet.
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet. Note integer type - see "Certain Packet Information" in docs/admin_network.md.
* uint32 ID relevant to the packet type, e.g.
* - the client ID for #ADMIN_UPDATE_CLIENT_INFO. Use UINT32_MAX to show all clients.
* - the company ID for #ADMIN_UPDATE_COMPANY_INFO. Use UINT32_MAX to show all companies.
+5 -3
View File
@@ -66,19 +66,21 @@ void TCPConnecter::Connect()
{
for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) {
TCPConnecter *cur = *iter;
if ((cur->connected || cur->aborted) && cur->killed) {
const bool connected = cur->connected.load();
const bool aborted = cur->aborted.load();
if ((connected || aborted) && cur->killed) {
iter = _tcp_connecters.erase(iter);
if (cur->sock != INVALID_SOCKET) closesocket(cur->sock);
delete cur;
continue;
}
if (cur->connected) {
if (connected) {
iter = _tcp_connecters.erase(iter);
cur->OnConnect(cur->sock);
delete cur;
continue;
}
if (cur->aborted) {
if (aborted) {
iter = _tcp_connecters.erase(iter);
cur->OnFailure();
delete cur;
+3 -3
View File
@@ -171,9 +171,9 @@ bool NetworkContentSocketHandler::HandlePacket(Packet *p)
default:
if (this->HasClientQuit()) {
DEBUG(net, 0, "[tcp/content] received invalid packet type %d from %s", type, this->client_addr.GetAddressAsString());
DEBUG(net, 0, "[tcp/content] received invalid packet type %d from %s", type, this->client_addr.GetAddressAsString().c_str());
} else {
DEBUG(net, 0, "[tcp/content] received illegal packet from %s", this->client_addr.GetAddressAsString());
DEBUG(net, 0, "[tcp/content] received illegal packet from %s", this->client_addr.GetAddressAsString().c_str());
}
return false;
}
@@ -224,7 +224,7 @@ bool NetworkContentSocketHandler::ReceivePackets()
*/
bool NetworkContentSocketHandler::ReceiveInvalidPacket(PacketContentType type)
{
DEBUG(net, 0, "[tcp/content] received illegal packet type %d from %s", type, this->client_addr.GetAddressAsString());
DEBUG(net, 0, "[tcp/content] received illegal packet type %d from %s", type, this->client_addr.GetAddressAsString().c_str());
return false;
}
+4 -4
View File
@@ -250,8 +250,8 @@ int NetworkHTTPSocketHandler::Receive()
/* Wait till we read the end-of-header identifier */
if (this->recv_length == 0) {
int read = this->recv_pos + res;
int end = min(read, lengthof(this->recv_buffer) - 1);
ssize_t read = this->recv_pos + res;
ssize_t end = std::min<ssize_t>(read, lengthof(this->recv_buffer) - 1);
/* Do a 'safe' search for the end of the header. */
char prev = this->recv_buffer[end];
@@ -272,7 +272,7 @@ int NetworkHTTPSocketHandler::Receive()
this->recv_length = ret;
end_of_header += strlen(END_OF_HEADER);
int len = min(read - (end_of_header - this->recv_buffer), res);
int len = std::min(read - (end_of_header - this->recv_buffer), res);
if (len != 0) {
this->callback->OnReceiveData(end_of_header, len);
this->recv_length -= len;
@@ -281,7 +281,7 @@ int NetworkHTTPSocketHandler::Receive()
this->recv_pos = 0;
}
} else {
res = min(this->recv_length, res);
res = std::min<ssize_t>(this->recv_length, res);
/* Receive whatever we're expecting. */
this->callback->OnReceiveData(this->recv_buffer, res);
this->recv_length -= res;
+3
View File
@@ -42,6 +42,9 @@ public:
socklen_t sin_len = sizeof(sin);
SOCKET s = accept(ls, (struct sockaddr*)&sin, &sin_len);
if (s == INVALID_SOCKET) return;
#ifdef __EMSCRIPTEN__
sin_len = FixAddrLenForEmscripten(sin);
#endif
SetNonBlocking(s); // XXX error handling?
+9 -6
View File
@@ -100,10 +100,10 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a
/* Send the buffer */
int res = sendto(s.second, (const char*)p->buffer, p->size, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength());
DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString());
DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString().c_str());
/* Check for any errors, but ignore it otherwise */
if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString(), GET_LAST_ERROR());
if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString().c_str(), GET_LAST_ERROR());
if (!all) break;
}
@@ -129,6 +129,9 @@ void NetworkUDPSocketHandler::ReceivePackets()
/* Did we get the bytes for the base header of the packet? */
if (nbytes <= 0) break; // No data, i.e. no packet
if (nbytes <= 2) continue; // Invalid data; try next packet
#ifdef __EMSCRIPTEN__
client_len = FixAddrLenForEmscripten(client_addr);
#endif
NetworkAddress address(client_addr, client_len);
p.PrepareToRead();
@@ -136,7 +139,7 @@ void NetworkUDPSocketHandler::ReceivePackets()
/* If the size does not match the packet must be corrupted.
* Otherwise it will be marked as corrupted later on. */
if (nbytes != p.size) {
DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString().c_str());
continue;
}
@@ -313,9 +316,9 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, NetworkAddress *client_
default:
if (this->HasClientQuit()) {
DEBUG(net, 0, "[udp] received invalid packet type %d from %s", type, client_addr->GetAddressAsString());
DEBUG(net, 0, "[udp] received invalid packet type %d from %s", type, client_addr->GetAddressAsString().c_str());
} else {
DEBUG(net, 0, "[udp] received illegal packet from %s", client_addr->GetAddressAsString());
DEBUG(net, 0, "[udp] received illegal packet from %s", client_addr->GetAddressAsString().c_str());
}
break;
}
@@ -328,7 +331,7 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, NetworkAddress *client_
*/
void NetworkUDPSocketHandler::ReceiveInvalidPacket(PacketUDPType type, NetworkAddress *client_addr)
{
DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s", type, client_addr->GetAddressAsString());
DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s", type, client_addr->GetAddressAsString().c_str());
}
void NetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_FIND_SERVER, client_addr); }
+22 -7
View File
@@ -43,7 +43,7 @@ bool _ddc_fastforward = true;
#endif /* DEBUG_DUMP_COMMANDS */
/** Make sure both pools have the same size. */
assert_compile(NetworkClientInfoPool::MAX_SIZE == NetworkClientSocketPool::MAX_SIZE);
static_assert(NetworkClientInfoPool::MAX_SIZE == NetworkClientSocketPool::MAX_SIZE);
/** The pool with client information. */
NetworkClientInfoPool _networkclientinfo_pool("NetworkClientInfo");
@@ -80,8 +80,8 @@ uint8 _network_advertise_retries; ///< The number of advertisement retries w
CompanyMask _network_company_passworded; ///< Bitmask of the password status of all companies.
/* Check whether NETWORK_NUM_LANDSCAPES is still in sync with NUM_LANDSCAPE */
assert_compile((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE);
assert_compile((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH);
static_assert((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE);
static_assert((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH);
extern NetworkUDPSocketHandler *_udp_client_socket; ///< udp client socket
extern NetworkUDPSocketHandler *_udp_server_socket; ///< udp server socket
@@ -245,7 +245,7 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
break;
case NETWORK_ACTION_LEAVE: strid = STR_NETWORK_MESSAGE_CLIENT_LEFT; break;
case NETWORK_ACTION_NAME_CHANGE: strid = STR_NETWORK_MESSAGE_NAME_CHANGE; break;
case NETWORK_ACTION_GIVE_MONEY: strid = self_send ? STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY : STR_NETWORK_MESSAGE_GIVE_MONEY; break;
case NETWORK_ACTION_GIVE_MONEY: strid = STR_NETWORK_MESSAGE_GIVE_MONEY; break;
case NETWORK_ACTION_CHAT_COMPANY: strid = self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY; break;
case NETWORK_ACTION_CHAT_CLIENT: strid = self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT; break;
case NETWORK_ACTION_KICKED: strid = STR_NETWORK_MESSAGE_KICKED; break;
@@ -322,7 +322,7 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err)
STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP,
STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN,
};
assert_compile(lengthof(network_error_strings) == NETWORK_ERROR_END);
static_assert(lengthof(network_error_strings) == NETWORK_ERROR_END);
if (err >= (ptrdiff_t)lengthof(network_error_strings)) err = NETWORK_ERROR_GENERAL;
@@ -342,7 +342,8 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
case PM_PAUSED_NORMAL:
case PM_PAUSED_JOIN:
case PM_PAUSED_GAME_SCRIPT:
case PM_PAUSED_ACTIVE_CLIENTS: {
case PM_PAUSED_ACTIVE_CLIENTS:
case PM_PAUSED_LINK_GRAPH: {
bool changed = ((_pause_mode == PM_UNPAUSED) != (prev_mode == PM_UNPAUSED));
bool paused = (_pause_mode != PM_UNPAUSED);
if (!paused && !changed) return;
@@ -355,6 +356,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
if ((_pause_mode & PM_PAUSED_JOIN) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS);
if ((_pause_mode & PM_PAUSED_GAME_SCRIPT) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT);
if ((_pause_mode & PM_PAUSED_ACTIVE_CLIENTS) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS);
if ((_pause_mode & PM_PAUSED_LINK_GRAPH) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH);
str = STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 + i;
} else {
switch (changed_mode) {
@@ -362,6 +364,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
case PM_PAUSED_JOIN: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); break;
case PM_PAUSED_GAME_SCRIPT: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); break;
case PM_PAUSED_ACTIVE_CLIENTS: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); break;
case PM_PAUSED_LINK_GRAPH: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH); break;
default: NOT_REACHED();
}
str = paused ? STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED : STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED;
@@ -917,7 +920,8 @@ void NetworkGameLoop()
if (*p == ' ') p++;
cp = CallocT<CommandPacket>(1);
int company;
int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; \"%[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, cp->text);
static_assert(sizeof(cp->text) == 128);
int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, cp->text);
/* There are 8 pieces of data to read, however the last is a
* string that might or might not exist. Ignore it if that
* string misses because in 99% of the time it's not used. */
@@ -1153,3 +1157,14 @@ bool IsNetworkCompatibleVersion(const char *other)
const char *hash2 = ExtractNetworkRevisionHash(other);
return hash1 && hash2 && (strncmp(hash1, hash2, GITHASH_SUFFIX_LEN) == 0);
}
#ifdef __EMSCRIPTEN__
extern "C" {
void CDECL em_openttd_add_server(const char *host, int port)
{
NetworkUDPQueryServer(NetworkAddress(host, port), true);
}
}
#endif
+4 -4
View File
@@ -54,7 +54,7 @@ static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_GAMESCRIPT
};
/** Sanity check. */
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
static_assert(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
/**
* Create a new socket for the server side of the admin network.
@@ -86,7 +86,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
bool accept = !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS;
/* We can't go over the MAX_ADMINS limit here. However, if we accept
* the connection, there has to be space in the pool. */
assert_compile(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS);
static_assert(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS);
assert(!accept || ServerNetworkAdminSocketHandler::CanAllocateItem());
return accept;
}
@@ -413,13 +413,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy()
p->Send_uint64(company->money);
p->Send_uint64(company->current_loan);
p->Send_uint64(income);
p->Send_uint16(min(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>()));
p->Send_uint16(static_cast<uint16>(std::min<uint64>(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>())));
/* Send stats for the last 2 quarters. */
for (uint i = 0; i < 2; i++) {
p->Send_uint64(company->old_economy[i].company_value);
p->Send_uint16(company->old_economy[i].performance_history);
p->Send_uint16(min(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>()));
p->Send_uint16(static_cast<uint16>(std::min<uint64>(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>())));
}
this->SendPacket(p);
+4 -4
View File
@@ -31,7 +31,7 @@
/** The draw buffer must be able to contain the chat message, client name and the "[All]" message,
* some spaces and possible translations of [All] to other languages. */
assert_compile((int)DRAW_STRING_BUFFER >= (int)NETWORK_CHAT_LENGTH + NETWORK_NAME_LENGTH + 40);
static_assert((int)DRAW_STRING_BUFFER >= (int)NETWORK_CHAT_LENGTH + NETWORK_NAME_LENGTH + 40);
/** Spacing between chat lines. */
static const uint NETWORK_CHAT_LINE_SPACING = 3;
@@ -154,7 +154,7 @@ void NetworkUndrawChatMessage()
int width = _chatmsg_box.width;
int height = _chatmsg_box.height;
if (y < 0) {
height = max(height + y, min(_chatmsg_box.height, _screen.height));
height = std::max(height + y, std::min(_chatmsg_box.height, _screen.height));
y = 0;
}
if (x + width >= _screen.width) {
@@ -214,7 +214,7 @@ void NetworkDrawChatMessage()
int width = _chatmsg_box.width;
int height = _chatmsg_box.height;
if (y < 0) {
height = max(height + y, min(_chatmsg_box.height, _screen.height));
height = std::max(height + y, std::min(_chatmsg_box.height, _screen.height));
y = 0;
}
if (x + width >= _screen.width) {
@@ -235,7 +235,7 @@ void NetworkDrawChatMessage()
string_height += GetStringLineCount(STR_JUST_RAW_STRING, width - 1) * FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING;
}
string_height = min(string_height, MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));
string_height = std::min<uint>(string_height, MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));
int top = _screen.height - _chatmsg_box.y - string_height - 2;
int bottom = _screen.height - _chatmsg_box.y - 2;
+22 -18
View File
@@ -68,7 +68,7 @@ struct PacketReader : LoadFilter {
assert(this->read_bytes == 0);
size_t in_packet = p->size - p->pos;
size_t to_write = min((size_t)(this->bufe - this->buf), in_packet);
size_t to_write = std::min<size_t>(this->bufe - this->buf, in_packet);
const byte *pbuf = p->buffer + p->pos;
this->written_bytes += in_packet;
@@ -93,7 +93,7 @@ struct PacketReader : LoadFilter {
size_t Read(byte *rbuf, size_t size) override
{
/* Limit the amount to read to whatever we still have. */
size_t ret_size = size = min(this->written_bytes - this->read_bytes, size);
size_t ret_size = size = std::min(this->written_bytes - this->read_bytes, size);
this->read_bytes += ret_size;
const byte *rbufe = rbuf + ret_size;
@@ -103,7 +103,7 @@ struct PacketReader : LoadFilter {
this->bufe = this->buf + CHUNK;
}
size_t to_write = min(this->bufe - this->buf, rbufe - rbuf);
size_t to_write = std::min(this->bufe - this->buf, rbufe - rbuf);
memcpy(rbuf, this->buf, to_write);
rbuf += to_write;
this->buf += to_write;
@@ -211,16 +211,24 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
default: errorno = NETWORK_ERROR_GENERAL; break;
}
/* This means we fucked up and the server closed the connection */
if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
res != NETWORK_RECV_STATUS_SERVER_BANNED) {
if (res == NETWORK_RECV_STATUS_SERVER_ERROR || res == NETWORK_RECV_STATUS_SERVER_FULL ||
res == NETWORK_RECV_STATUS_SERVER_BANNED) {
/* This means the server closed the connection. Emergency save is
* already created if this was appropriate during handling of the
* disconnect. */
this->CloseConnection(res);
} else {
/* This means we as client made a boo-boo. */
SendError(errorno);
/* Close connection before we make an emergency save, as the save can
* take a bit of time; better that the server doesn't stall while we
* are doing the save, and already disconnects us. */
this->CloseConnection(res);
ClientNetworkEmergencySave();
}
ClientNetworkEmergencySave();
_switch_mode = SM_MENU;
this->CloseConnection(res);
_networking = false;
}
@@ -323,7 +331,7 @@ const char *_network_join_server_password = nullptr;
const char *_network_join_company_password = nullptr;
/** Make sure the server ID length is the same as a md5 hash. */
assert_compile(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
static_assert(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
/***********
* Sending functions
@@ -540,7 +548,7 @@ bool ClientNetworkGameSocketHandler::IsConnected()
* DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
************/
extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
{
@@ -681,7 +689,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
STR_NETWORK_ERROR_TIMEOUT_MAP, // NETWORK_ERROR_TIMEOUT_MAP
STR_NETWORK_ERROR_TIMEOUT_JOIN, // NETWORK_ERROR_TIMEOUT_JOIN
};
assert_compile(lengthof(network_error_strings) == NETWORK_ERROR_END);
static_assert(lengthof(network_error_strings) == NETWORK_ERROR_END);
NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
@@ -866,7 +874,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
/* The map is done downloading, load it */
ClearErrorMessages();
bool load_success = SafeLoad(nullptr, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
/* Long savegame loads shouldn't affect the lag calculation! */
this->last_packet = _realtime_tick;
@@ -992,11 +1000,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
break;
/* For speaking to company or giving money, we need the company-name */
case NETWORK_ACTION_GIVE_MONEY:
if (!Company::IsValidID(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
FALLTHROUGH;
/* For speaking to company, we need the company-name */
case NETWORK_ACTION_CHAT_COMPANY: {
StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
SetDParam(0, ci_to->client_playas);
+2 -2
View File
@@ -39,7 +39,7 @@ static CommandCallback * const _callback_table[] = {
/* 0x11 */ CcTerraform,
/* 0x12 */ CcAI,
/* 0x13 */ CcCloneVehicle,
/* 0x14 */ CcGiveMoney,
/* 0x14 */ nullptr,
/* 0x15 */ CcCreateGroup,
/* 0x16 */ CcFoundRandomTown,
/* 0x17 */ CcRoadStop,
@@ -298,7 +298,7 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
cp->company = (CompanyID)p->Recv_uint8();
cp->cmd = p->Recv_uint32();
if (!IsValidCommand(cp->cmd)) return "invalid command";
if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command";
if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
cp->p1 = p->Recv_uint32();
+33 -18
View File
@@ -23,6 +23,10 @@
#include <zlib.h>
#endif
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
#include "../safeguards.h"
extern bool HasScenario(const ContentInfo *ci, bool md5sum);
@@ -217,7 +221,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(uint count, const Con
* A packet begins with the packet size and a byte for the type.
* Then this packet adds a uint16 for the count in this packet.
* The rest of the packet can be used for the IDs. */
uint p_count = min(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
uint p_count = std::min<uint>(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID);
p->Send_uint16(p_count);
@@ -289,6 +293,13 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin
{
bytes = 0;
#ifdef __EMSCRIPTEN__
/* Emscripten is loaded via an HTTPS connection. As such, it is very
* difficult to make HTTP connections. So always use the TCP method of
* downloading content. */
fallback = true;
#endif
ContentIDList content;
for (const ContentInfo *ci : this->infos) {
if (!ci->IsSelected() || ci->state == ContentInfo::ALREADY_HERE) continue;
@@ -352,7 +363,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const Co
* A packet begins with the packet size and a byte for the type.
* Then this packet adds a uint16 for the count in this packet.
* The rest of the packet can be used for the IDs. */
uint p_count = min(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
uint p_count = std::min<uint>(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT);
p->Send_uint16(p_count);
@@ -374,14 +385,14 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const Co
* @return a statically allocated buffer with the filename or
* nullptr when no filename could be made.
*/
static char *GetFullFilename(const ContentInfo *ci, bool compressed)
static std::string GetFullFilename(const ContentInfo *ci, bool compressed)
{
Subdirectory dir = GetContentInfoSubDir(ci->type);
if (dir == NO_DIRECTORY) return nullptr;
if (dir == NO_DIRECTORY) return {};
static char buf[MAX_PATH];
FioGetFullPath(buf, lastof(buf), SP_AUTODOWNLOAD_DIR, dir, ci->filename);
strecat(buf, compressed ? ".tar.gz" : ".tar", lastof(buf));
std::string buf = FioGetDirectory(SP_AUTODOWNLOAD_DIR, dir);
buf += ci->filename;
buf += compressed ? ".tar.gz" : ".tar";
return buf;
}
@@ -397,13 +408,13 @@ static bool GunzipFile(const ContentInfo *ci)
bool ret = true;
/* Need to open the file with fopen() to support non-ASCII on Windows. */
FILE *ftmp = fopen(GetFullFilename(ci, true), "rb");
FILE *ftmp = fopen(GetFullFilename(ci, true).c_str(), "rb");
if (ftmp == nullptr) return false;
/* Duplicate the handle, and close the FILE*, to avoid double-closing the handle later. */
gzFile fin = gzdopen(dup(fileno(ftmp)), "rb");
fclose(ftmp);
FILE *fout = fopen(GetFullFilename(ci, false), "wb");
FILE *fout = fopen(GetFullFilename(ci, false).c_str(), "wb");
if (fin == nullptr || fout == nullptr) {
ret = false;
@@ -498,8 +509,8 @@ bool ClientNetworkContentSocketHandler::BeforeDownload()
if (this->curInfo->filesize != 0) {
/* The filesize is > 0, so we are going to download it */
const char *filename = GetFullFilename(this->curInfo, true);
if (filename == nullptr || (this->curFile = fopen(filename, "wb")) == nullptr) {
std::string filename = GetFullFilename(this->curInfo, true);
if (filename.empty() || (this->curFile = fopen(filename.c_str(), "wb")) == nullptr) {
/* Unless that fails of course... */
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD);
ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR);
@@ -521,20 +532,25 @@ void ClientNetworkContentSocketHandler::AfterDownload()
this->curFile = nullptr;
if (GunzipFile(this->curInfo)) {
unlink(GetFullFilename(this->curInfo, true));
unlink(GetFullFilename(this->curInfo, true).c_str());
Subdirectory sd = GetContentInfoSubDir(this->curInfo->type);
if (sd == NO_DIRECTORY) NOT_REACHED();
TarScanner ts;
ts.AddFile(sd, GetFullFilename(this->curInfo, false));
std::string fname = GetFullFilename(this->curInfo, false);
ts.AddFile(sd, fname);
if (this->curInfo->type == CONTENT_TYPE_BASE_MUSIC) {
/* Music can't be in a tar. So extract the tar! */
ExtractTar(GetFullFilename(this->curInfo, false), BASESET_DIR);
unlink(GetFullFilename(this->curInfo, false));
ExtractTar(fname, BASESET_DIR);
unlink(fname.c_str());
}
#ifdef __EMSCRIPTEN__
EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
#endif
this->OnDownloadComplete(this->curInfo->id);
} else {
ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_EXTRACT, INVALID_STRING_ID, WL_ERROR);
@@ -727,6 +743,7 @@ public:
void OnConnect(SOCKET s) override
{
assert(_network_content_client.sock == INVALID_SOCKET);
_network_content_client.lastActivity = _realtime_tick;
_network_content_client.isConnecting = false;
_network_content_client.sock = s;
_network_content_client.Reopen();
@@ -739,8 +756,6 @@ public:
*/
void ClientNetworkContentSocketHandler::Connect()
{
this->lastActivity = _realtime_tick;
if (this->sock != INVALID_SOCKET || this->isConnecting) return;
this->isConnecting = true;
new NetworkContentConnecter(NetworkAddress(NETWORK_CONTENT_SERVER_HOST, NETWORK_CONTENT_SERVER_PORT, AF_UNSPEC));
@@ -888,7 +903,7 @@ void ClientNetworkContentSocketHandler::ToggleSelectedState(const ContentInfo *c
*/
void ClientNetworkContentSocketHandler::ReverseLookupDependency(ConstContentVector &parents, const ContentInfo *child) const
{
for (const ContentInfo * const &ci : this->infos) {
for (const ContentInfo *ci : this->infos) {
if (ci == child) continue;
for (uint i = 0; i < ci->dependency_count; i++) {
+5 -5
View File
@@ -577,8 +577,8 @@ public:
}
case WID_NCL_MATRIX:
resize->height = SETTING_BUTTON_HEIGHT;
size->height = 6 * resize->height;
resize->height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
size->height = 10 * resize->height;
break;
}
}
@@ -628,7 +628,7 @@ public:
const NWidgetBase *nwi_name = this->GetWidget<NWidgetBase>(WID_NCL_NAME);
const NWidgetBase *nwi_type = this->GetWidget<NWidgetBase>(WID_NCL_TYPE);
int line_height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL);
int line_height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL);
/* Fill the matrix with the information */
int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1 + (this->resize.step_height - line_height) / 2;
@@ -879,7 +879,7 @@ public:
break;
case WKC_PAGEDOWN:
/* scroll down a page */
this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.size() - 1);
this->list_pos = std::min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.size() - 1);
break;
case WKC_HOME:
/* jump to beginning */
@@ -953,7 +953,7 @@ public:
{
if (this->auto_select && !rci->IsSelected()) _network_content_client.ToggleSelectedState(rci);
this->content.ForceRebuild();
this->InvalidateData();
this->InvalidateData(0, false);
}
void OnDownloadComplete(ContentID cid) override
-6
View File
@@ -175,21 +175,15 @@ void NetworkAfterNewGRFScan()
/* Don't know the GRF, so mark game incompatible and the (possibly)
* already resolved name for this GRF (another server has sent the
* name of the GRF already. */
c->name->Release();
c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true);
c->name->AddRef();
c->status = GCS_NOT_FOUND;
/* If we miss a file, we're obviously incompatible. */
item->info.compatible = false;
} else {
c->filename = f->filename;
c->name->Release();
c->name = f->name;
c->name->AddRef();
c->info->Release();
c->info = f->info;
c->info->AddRef();
c->status = GCS_UNKNOWN;
}
}
+44 -84
View File
@@ -40,6 +40,9 @@
#include "../safeguards.h"
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
static void ShowNetworkStartServerWindow();
static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
@@ -53,15 +56,6 @@ static const StringID _connection_types_dropdown[] = {
INVALID_STRING_ID
};
/**
* Advertisement options in the server list
*/
static const StringID _lan_internet_types_dropdown[] = {
STR_NETWORK_SERVER_LIST_ADVERTISED_NO,
STR_NETWORK_SERVER_LIST_ADVERTISED_YES,
INVALID_STRING_ID
};
static std::vector<StringID> _language_dropdown;
void SortNetworkLanguages()
@@ -130,7 +124,7 @@ public:
/* First initialise some variables... */
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
child_wid->SetupSmallestSize(w, init_array);
this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
}
/* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */
@@ -476,6 +470,14 @@ public:
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
this->SetFocusedWidget(WID_NG_FILTER);
/* As the master-server doesn't support "websocket" servers yet, we
* let "os/emscripten/pre.js" hardcode a list of servers people can
* join. This means the serverlist is curated for now, but it is the
* best we can offer. */
#ifdef __EMSCRIPTEN__
EM_ASM(if (window["openttd_server_list"]) openttd_server_list());
#endif
this->last_joined = NetworkGameListAddItem(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
this->server = this->last_joined;
if (this->last_joined != nullptr) NetworkUDPQueryServer(this->last_joined->address);
@@ -493,24 +495,9 @@ public:
this->last_sorting = this->servers.GetListing();
}
void SetStringParameters(int widget) const override
{
switch (widget) {
case WID_NG_CONN_BTN:
SetDParam(0, _lan_internet_types_dropdown[_settings_client.network.lan_internet]);
break;
}
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
switch (widget) {
case WID_NG_CONN_BTN:
*size = maxdim(*size, maxdim(GetStringBoundingBox(_lan_internet_types_dropdown[0]), GetStringBoundingBox(_lan_internet_types_dropdown[1])));
size->width += padding.width + GetMinSizing(NWST_STEP, 11U);;
size->height += padding.height;
break;
case WID_NG_MATRIX:
resize->height = SETTING_BUTTON_HEIGHT;
size->height = 5 * resize->height;
@@ -550,10 +537,6 @@ public:
SetDParamMaxValue(0, 5);
*size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT));
break;
case WID_NG_DETAILS_SPACER:
size->height = 20 + 10 * FONT_HEIGHT_NORMAL;
break;
}
}
@@ -563,7 +546,7 @@ public:
case WID_NG_MATRIX: {
uint16 y = r.top;
const int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.size());
const int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.size());
for (int i = this->vscroll->GetPosition(); i < max; ++i) {
const NetworkGameList *ngl = this->servers[i];
@@ -616,6 +599,13 @@ public:
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);
#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();
}
@@ -665,7 +655,9 @@ public:
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
y += FONT_HEIGHT_NORMAL;
SetDParamStr(0, sel->address.GetAddressAsString());
char network_addr_buffer[NETWORK_HOSTNAME_LENGTH + 6 + 7];
sel->address.GetAddressAsString(network_addr_buffer, lastof(network_addr_buffer));
SetDParamStr(0, network_addr_buffer);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address
y += FONT_HEIGHT_NORMAL;
@@ -697,10 +689,6 @@ public:
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
break;
case WID_NG_CONN_BTN: // 'Connection' droplist
ShowDropDownMenu(this, _lan_internet_types_dropdown, _settings_client.network.lan_internet, WID_NG_CONN_BTN, 0, 0); // do it for widget WID_NSS_CONN_BTN
break;
case WID_NG_NAME: // Sort by name
case WID_NG_CLIENTS: // Sort by connected clients
case WID_NG_MAPSIZE: // Sort by map size
@@ -745,11 +733,12 @@ public:
break;
}
case WID_NG_FIND: // Find server automatically
switch (_settings_client.network.lan_internet) {
case 0: NetworkUDPSearchGame(); break;
case 1: NetworkUDPQueryMasterServer(); break;
}
case WID_NG_SEARCH_INTERNET:
NetworkUDPQueryMasterServer();
break;
case WID_NG_SEARCH_LAN:
NetworkUDPSearchGame();
break;
case WID_NG_ADD: // Add a server
@@ -787,20 +776,6 @@ public:
}
}
void OnDropdownSelect(int widget, int index) override
{
switch (widget) {
case WID_NG_CONN_BTN:
_settings_client.network.lan_internet = index;
break;
default:
NOT_REACHED();
}
this->SetDirty();
}
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
@@ -838,7 +813,7 @@ public:
case WKC_PAGEDOWN:
/* scroll down a page */
if (this->list_pos == SLP_INVALID) return ES_HANDLED;
this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.size() - 1);
this->list_pos = std::min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.size() - 1);
break;
case WKC_HOME:
/* jump to beginning */
@@ -930,7 +905,7 @@ GUIGameServerList::FilterFunction * const NetworkGameWindow::filter_funcs[] = {
static NWidgetBase *MakeResizableHeader(int *biggest_index)
{
*biggest_index = max<int>(*biggest_index, WID_NG_INFO);
*biggest_index = std::max<int>(*biggest_index, WID_NG_INFO);
return new NWidgetServerListHeader();
}
@@ -947,9 +922,6 @@ static const NWidgetPart _nested_network_game_widgets[] = {
/* LEFT SIDE */
NWidget(NWID_VERTICAL), SetPIP(0, 7, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_CONNECTION), SetSizingType(NWST_STEP), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NG_CONN_BTN),
SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NG_FILTER), SetMinimalSize(251, 12), SetFill(1, 0), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
@@ -1008,7 +980,8 @@ static const NWidgetPart _nested_network_game_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 7, 4),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_FIND), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_FIND_SERVER, STR_NETWORK_SERVER_LIST_FIND_SERVER_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_SEARCH_INTERNET), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET, STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_SEARCH_LAN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN, STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_ADD), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_ADD_SERVER, STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_START), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_START_SERVER, STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_CANCEL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
@@ -1276,8 +1249,8 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 6, 10),
NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_ADVERTISED_LABEL, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_ADVERTISED_TOOLTIP),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_LANGUAGE_SPOKEN, STR_NULL),
@@ -1576,7 +1549,7 @@ struct NetworkLobbyWindow : public Window {
NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
/* Clear the information so removed companies don't remain */
memset(this->company_info, 0, sizeof(this->company_info));
for (auto &company : this->company_info) company = {};
break;
}
}
@@ -1660,8 +1633,7 @@ NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company)
}
/* The window below gives information about the connected clients
* and also makes able to give money to them, kick them (if server)
* and stuff like that. */
* and also makes able to kick them (if server) and stuff like that. */
extern void DrawCompanyIcon(CompanyID cid, int x, int y);
@@ -1693,11 +1665,6 @@ static void ClientList_Ban(const NetworkClientInfo *ci)
NetworkServerKickOrBanIP(ci->client_id, true, nullptr);
}
static void ClientList_GiveMoney(const NetworkClientInfo *ci)
{
ShowNetworkGiveMoneyWindow(ci->client_playas);
}
static void ClientList_SpeakToClient(const NetworkClientInfo *ci)
{
ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, ci->client_id);
@@ -1754,13 +1721,6 @@ struct NetworkClientListPopupWindow : Window {
}
this->AddAction(STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, &ClientList_SpeakToAll);
if (_network_own_client_id != ci->client_id) {
/* We are no spectator and the company we want to give money to is no spectator and money gifts are allowed. */
if (Company::IsValidID(_local_company) && Company::IsValidID(ci->client_playas) && _settings_game.economy.give_money) {
this->AddAction(STR_NETWORK_CLIENTLIST_GIVE_MONEY, &ClientList_GiveMoney);
}
}
/* A server can kick clients (but not himself). */
if (_network_server && _network_own_client_id != ci->client_id) {
this->AddAction(STR_NETWORK_CLIENTLIST_KICK, &ClientList_Kick);
@@ -1919,14 +1879,14 @@ struct NetworkClientListWindow : Window {
{
if (widget != WID_CL_PANEL) return;
this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT;
this->server_client_width = std::max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT;
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
this->line_height = max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
this->line_height = std::max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
this->line_height = GetMinSizing(NWST_STEP, this->line_height);
uint width = 100; // Default width
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
width = max(width, GetStringBoundingBox(ci->client_name).width);
width = std::max(width, GetStringBoundingBox(ci->client_name).width);
}
this->line_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT;
@@ -2097,18 +2057,18 @@ struct NetworkJoinStatusWindow : Window {
/* Account for the statuses */
uint width = 0;
for (uint i = 0; i < NETWORK_JOIN_STATUS_END; i++) {
width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_1 + i).width);
width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_1 + i).width);
}
/* For the number of waiting (other) players */
SetDParamMaxValue(0, MAX_CLIENTS);
width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_WAITING).width);
width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_WAITING).width);
/* Account for downloading ~ 10 MiB */
SetDParamMaxDigits(0, 8);
SetDParamMaxDigits(1, 8);
width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1).width);
width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_2).width);
width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1).width);
width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_2).width);
/* Give a bit more clearing for the widest strings than strictly needed */
size->width = width + WD_FRAMERECT_LEFT + WD_FRAMERECT_BOTTOM + 10;
-1
View File
@@ -16,7 +16,6 @@
#include "network_type.h"
void ShowNetworkNeedPassword(NetworkPasswordType npt);
void ShowNetworkGiveMoneyWindow(CompanyID company);
void ShowNetworkChatQueryWindow(DestType type, int dest);
void ShowJoinStatusWindow();
void ShowNetworkGameWindow();
+20 -13
View File
@@ -41,9 +41,9 @@ DECLARE_POSTFIX_INCREMENT(ClientID)
static ClientID _network_client_id = CLIENT_ID_FIRST;
/** Make very sure the preconditions given in network_type.h are actually followed */
assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
static_assert(MAX_CLIENT_SLOTS > MAX_CLIENTS);
/** Yes... */
assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
static_assert(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
/** The pool with clients. */
NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket");
@@ -153,6 +153,16 @@ struct PacketWriter : SaveFilter {
this->current = nullptr;
}
/** Prepend the current packet to the queue. */
void PrependQueue()
{
if (this->current == nullptr) return;
this->current->next = this->packets;
this->packets = this->current;
this->current = nullptr;
}
void Write(byte *buf, size_t size) override
{
/* We want to abort the saving when the socket is closed. */
@@ -164,7 +174,7 @@ struct PacketWriter : SaveFilter {
byte *bufe = buf + size;
while (buf != bufe) {
size_t to_write = min(SEND_MTU - this->current->size, bufe - buf);
size_t to_write = std::min<size_t>(SEND_MTU - this->current->size, bufe - buf);
memcpy(this->current->buffer + this->current->size, buf, to_write);
this->current->size += (PacketSize)to_write;
buf += to_write;
@@ -193,9 +203,9 @@ struct PacketWriter : SaveFilter {
this->AppendQueue();
/* Fast-track the size to the client. */
Packet *p = new Packet(PACKET_SERVER_MAP_SIZE);
p->Send_uint32((uint32)this->total_size);
this->cs->NetworkTCPSocketHandler::SendPacket(p);
this->current = new Packet(PACKET_SERVER_MAP_SIZE);
this->current->Send_uint32((uint32)this->total_size);
this->PrependQueue();
}
};
@@ -213,7 +223,7 @@ ServerNetworkGameSocketHandler::ServerNetworkGameSocketHandler(SOCKET s) : Netwo
/* The Socket and Info pools need to be the same in size. After all,
* each Socket will be associated with at most one Info object. As
* such if the Socket was allocated the Info object can as well. */
assert_compile(NetworkClientSocketPool::MAX_SIZE == NetworkClientInfoPool::MAX_SIZE);
static_assert(NetworkClientSocketPool::MAX_SIZE == NetworkClientInfoPool::MAX_SIZE);
}
/**
@@ -301,7 +311,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
/* We can't go over the MAX_CLIENTS limit here. However, the
* pool must have place for all clients and ourself. */
assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1);
static_assert(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1);
assert(!accept || ServerNetworkGameSocketHandler::CanAllocateItem());
return accept;
}
@@ -1372,9 +1382,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
NetworkClientInfo *ci = this->GetInfo();
switch (action) {
case NETWORK_ACTION_GIVE_MONEY:
if (!Company::IsValidID(ci->client_playas)) break;
FALLTHROUGH;
case NETWORK_ACTION_CHAT:
case NETWORK_ACTION_CHAT_CLIENT:
case NETWORK_ACTION_CHAT_COMPANY:
@@ -1800,7 +1807,7 @@ void NetworkServer_Tick(bool send_frame)
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
/* We allow a number of bytes per frame, but only to the burst amount
* to be available for packet receiving at any particular time. */
cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame,
cs->receive_limit = std::min<int>(cs->receive_limit + _settings_client.network.bytes_per_frame,
_settings_client.network.bytes_per_frame_burst);
/* Check if the speed of the client is what we can expect from a client */
@@ -1952,7 +1959,7 @@ void NetworkServerShowStatusToConsole()
"ready",
"active"
};
assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
static_assert(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
NetworkClientInfo *ci = cs->GetInfo();
+13 -4
View File
@@ -74,18 +74,23 @@ enum NetworkPasswordType {
NETWORK_COMPANY_PASSWORD, ///< The password of the company.
};
/** Destination of our chat messages. */
/**
* Destination of our chat messages.
* @warning The values of the enum items are part of the admin network API. Only append at the end.
*/
enum DestType {
DESTTYPE_BROADCAST, ///< Send message/notice to all clients (All)
DESTTYPE_TEAM, ///< Send message/notice to everyone playing the same company (Team)
DESTTYPE_CLIENT, ///< Send message/notice to only a certain client (Private)
};
/** Actions that can be used for NetworkTextMessage */
/**
* Actions that can be used for NetworkTextMessage.
* @warning The values of the enum items are part of the admin network API. Only append at the end.
*/
enum NetworkAction {
NETWORK_ACTION_JOIN,
NETWORK_ACTION_LEAVE,
NETWORK_ACTION_KICKED,
NETWORK_ACTION_SERVER_MESSAGE,
NETWORK_ACTION_CHAT,
NETWORK_ACTION_CHAT_COMPANY,
@@ -95,9 +100,13 @@ enum NetworkAction {
NETWORK_ACTION_COMPANY_SPECTATOR,
NETWORK_ACTION_COMPANY_JOIN,
NETWORK_ACTION_COMPANY_NEW,
NETWORK_ACTION_KICKED,
};
/** The error codes we send around in the protocols. */
/**
* The error codes we send around in the protocols.
* @warning The values of the enum items are part of the admin network API. Only append at the end.
*/
enum NetworkErrorCode {
NETWORK_ERROR_GENERAL, // Try to use this one like never
+10 -18
View File
@@ -244,7 +244,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ
uint8 in_reply_count = 0;
size_t packet_len = 0;
DEBUG(net, 6, "[udp] newgrf data request from %s", client_addr->GetAddressAsString());
DEBUG(net, 6, "[udp] newgrf data request from %s", client_addr->GetAddressAsString().c_str());
num_grfs = p->Recv_uint8 ();
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
@@ -263,7 +263,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ
* the current list and do not send the other data.
* The name could be an empty string, if so take the filename. */
packet_len += sizeof(c.grfid) + sizeof(c.md5sum) +
min(strlen(f->GetName()) + 1, (size_t)NETWORK_GRF_NAME_LENGTH);
std::min(strlen(f->GetName()) + 1, (size_t)NETWORK_GRF_NAME_LENGTH);
if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply
break;
}
@@ -307,7 +307,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd
/* Just a fail-safe.. should never happen */
if (_network_udp_server) return;
DEBUG(net, 4, "[udp] server response from %s", client_addr->GetAddressAsString());
DEBUG(net, 4, "[udp] server response from %s", client_addr->GetAddressAsString().c_str());
/* Find next item */
item = NetworkGameListAddItem(*client_addr);
@@ -407,7 +407,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd
uint8 num_grfs;
uint i;
DEBUG(net, 6, "[udp] newgrf data reply from %s", client_addr->GetAddressAsString());
DEBUG(net, 6, "[udp] newgrf data reply from %s", client_addr->GetAddressAsString().c_str());
num_grfs = p->Recv_uint8 ();
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
@@ -426,9 +426,9 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd
/* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple.
* If it exists and not resolved yet, then name of the fake GRF is
* overwritten with the name from the reply. */
GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
if (unknown_name != nullptr && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
AddGRFTextToList(&unknown_name->text, name);
GRFTextWrapper unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
if (unknown_name && strcmp(GetGRFStringFromGRFText(unknown_name), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
AddGRFTextToList(unknown_name, name);
}
}
}
@@ -441,21 +441,13 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo
/* Don't know the GRF, so mark game incompatible and the (possibly)
* already resolved name for this GRF (another server has sent the
* name of the GRF already */
config->name->Release();
config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true);
config->name->AddRef();
config->status = GCS_NOT_FOUND;
} else {
config->filename = f->filename;
config->name->Release();
config->name = f->name;
config->name->AddRef();
config->info->Release();
config->info = f->info;
config->info->AddRef();
config->url->Release();
config->url = f->url;
config->url->AddRef();
}
SetBit(config->flags, GCF_COPY);
}
@@ -485,7 +477,7 @@ void NetworkUDPQueryMasterServer()
_udp_client_socket->SendPacket(&p, &out_addr, true);
DEBUG(net, 2, "[udp] master server queried at %s", out_addr.GetAddressAsString());
DEBUG(net, 2, "[udp] master server queried at %s", out_addr.GetAddressAsString().c_str());
}
/** Find all servers */
@@ -549,8 +541,8 @@ static void NetworkUDPAdvertiseThread()
if (_session_key == 0 && session_key_retries++ == 2) {
DEBUG(net, 0, "[udp] advertising to the master server is failing");
DEBUG(net, 0, "[udp] we are not receiving the session key from the server");
DEBUG(net, 0, "[udp] please allow udp packets from %s to you to be delivered", out_addr.GetAddressAsString(false));
DEBUG(net, 0, "[udp] please allow udp packets from you to %s to be delivered", out_addr.GetAddressAsString(false));
DEBUG(net, 0, "[udp] please allow udp packets from %s to you to be delivered", out_addr.GetAddressAsString(false).c_str());
DEBUG(net, 0, "[udp] please allow udp packets from you to %s to be delivered", out_addr.GetAddressAsString(false).c_str());
}
if (_session_key != 0 && _network_advertise_retries == 0) {
DEBUG(net, 0, "[udp] advertising to the master server is failing");