Merge branch 'master' into jgrpp

# Conflicts:
#	src/company_cmd.cpp
#	src/lang/japanese.txt
#	src/network/core/config.h
#	src/network/core/packet.cpp
#	src/network/core/tcp.cpp
#	src/network/network_content.cpp
#	src/network/network_server.cpp
#	src/network/network_udp.cpp
#	src/toolbar_gui.cpp
#	src/vehicle_gui_base.h
This commit is contained in:
Jonathan G Rennison
2021-04-25 22:03:49 +01:00
98 changed files with 1370 additions and 1193 deletions

View File

@@ -30,8 +30,24 @@ static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The defau
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 SEND_MTU = 1460; ///< Number of bytes we can pack in a single packet
static const uint16 SEND_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single packet (conservative)
static const uint16 UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
static const uint16 UDP_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single UDP packet (conservative)
/*
* 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.
*
* Packets up to 32 KiB have the high bit not set:
* 00000000 00000000 0bbbbbbb aaaaaaaa -> aaaaaaaa 0bbbbbbb
* Send_uint16(GB(size, 0, 15)
*
* Packets up to 1 GiB, first uint16 has high bit set so it knows to read a
* next uint16 for the remaining bits of the size.
* 00dddddd cccccccc bbbbbbbb aaaaaaaa -> cccccccc 10dddddd aaaaaaaa bbbbbbbb
* 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 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?
@@ -48,14 +64,14 @@ static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maxim
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 = SEND_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than SEND_MTU including header (3 bytes)
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_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 SEND_MTU bytes.
* 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_SHORT = 59;

View File

@@ -21,6 +21,7 @@
/**
* Create a packet that is used to read from a network socket.
* @param cs The socket handler associated with the socket we are reading from.
* @param limit The maximum size of packets to accept.
* @param initial_read_size The initial amount of data to transfer from the socket into the
* packet. This defaults to just the required bytes to determine the
* packet's size. That default is the wanted for streams such as TCP
@@ -29,7 +30,7 @@
* loose some the data of the packet, so there you pass the maximum
* size for the packet you expect from the network.
*/
Packet::Packet(NetworkSocketHandler *cs, size_t initial_read_size) : pos(0)
Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) : pos(0), limit(limit)
{
assert(cs != nullptr);
@@ -39,9 +40,13 @@ Packet::Packet(NetworkSocketHandler *cs, size_t initial_read_size) : pos(0)
/**
* Creates a packet to send
* @param type of the packet to send
* @param type The type of the packet to send
* @param limit The maximum number of bytes the packet may have. Default is COMPAT_MTU.
* Be careful of compatibility with older clients/servers when changing
* the limit as it might break things if the other side is not expecting
* much larger packets than what they support.
*/
Packet::Packet(PacketType type) : pos(0), cs(nullptr)
Packet::Packet(PacketType type, size_t limit) : pos(0), limit(limit), cs(nullptr)
{
this->ResetState(type);
}
@@ -77,7 +82,7 @@ void Packet::PrepareToSend()
*/
bool Packet::CanWriteToPacket(size_t bytes_to_write)
{
return this->Size() + bytes_to_write < SHRT_MAX;
return this->Size() + bytes_to_write < this->limit;
}
/*
@@ -181,7 +186,7 @@ void Packet::Send_string(const char *data)
*/
size_t Packet::Send_bytes(const byte *begin, const byte *end)
{
size_t amount = std::min<size_t>(end - begin, SHRT_MAX - this->Size());
size_t amount = std::min<size_t>(end - begin, this->limit - this->Size());
this->buffer.insert(this->buffer.end(), begin, begin + amount);
return amount;
}
@@ -267,7 +272,7 @@ bool Packet::ParsePacketSize()
/* If the size of the packet is less than the bytes required for the size and type of
* the packet, or more than the allowed limit, then something is wrong with the packet.
* In those cases the packet can generally be regarded as containing garbage data. */
if (size < sizeof(PacketSize) + sizeof(PacketType)) return false;
if (size < sizeof(PacketSize) + sizeof(PacketType) || size > this->limit) return false;
this->buffer.resize(size);
this->pos = sizeof(PacketSize);

View File

@@ -26,10 +26,11 @@ typedef uint8 PacketType; ///< Identifier for the packet
* Internal entity of a packet. As everything is sent as a packet,
* all network communication will need to call the functions that
* populate the packet.
* Every packet can be at most SEND_MTU bytes. Overflowing this
* limit will give an assertion when sending (i.e. writing) the
* packet. Reading past the size of the packet when receiving
* will return all 0 values and "" in case of the string.
* Every packet can be at most a limited number bytes set in the
* constructor. Overflowing this limit will give an assertion when
* sending (i.e. writing) the packet. Reading past the size of the
* packet when receiving will return all 0 values and "" in case of
* the string.
*
* --- Points of attention ---
* - all > 1 byte integral values are written in little endian,
@@ -46,13 +47,15 @@ private:
PacketSize pos;
/** The buffer of this packet. */
std::vector<byte> buffer;
/** The limit for the packet size. */
size_t limit;
/** Socket we're associated with. */
NetworkSocketHandler *cs;
public:
Packet(NetworkSocketHandler *cs, size_t initial_read_size = sizeof(PacketSize));
Packet(PacketType type);
Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = sizeof(PacketSize));
Packet(PacketType type, size_t limit = COMPAT_MTU);
void ResetState(PacketType type);

View File

@@ -61,6 +61,21 @@ void NetworkTCPSocketHandler::SendPacket(std::unique_ptr<Packet> packet)
this->packet_queue.push_back(std::move(packet));
}
/**
* This function puts the packet in the send-queue and it is send as
* soon as possible. This is the next tick, or maybe one tick later
* if the OS-network-buffer is full)
* @param packet the packet to send
*/
void NetworkTCPSocketHandler::SendPrependPacket(std::unique_ptr<Packet> packet)
{
assert(packet != nullptr);
packet->PrepareToSend();
this->packet_queue.push_front(std::move(packet));
}
/**
* Sends all the buffered packets out for this client. It stops when:
* 1) all packets are send (queue is empty)
@@ -123,7 +138,7 @@ std::unique_ptr<Packet> NetworkTCPSocketHandler::ReceivePacket()
if (!this->IsConnected()) return nullptr;
if (this->packet_recv == nullptr) {
this->packet_recv.reset(new Packet(this));
this->packet_recv.reset(new Packet(this, SHRT_MAX));
}
Packet *p = this->packet_recv.get();

View File

@@ -43,7 +43,8 @@ public:
bool IsConnected() const { return this->sock != INVALID_SOCKET; }
NetworkRecvStatus CloseConnection(bool error = true) override;
virtual void SendPacket(std::unique_ptr<Packet> packet);
void SendPacket(std::unique_ptr<Packet> packet);
void SendPrependPacket(std::unique_ptr<Packet> packet);
void SendPacket(Packet *packet)
{

View File

@@ -86,7 +86,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a
{
if (this->sockets.size() == 0) this->Listen();
const uint MTU = short_mtu ? SEND_MTU_SHORT : SEND_MTU;
const uint MTU = short_mtu ? UDP_MTU_SHORT : UDP_MTU;
if (p->Size() > MTU) {
p->PrepareToSend();
@@ -155,7 +155,8 @@ void NetworkUDPSocketHandler::ReceivePackets()
struct sockaddr_storage client_addr;
memset(&client_addr, 0, sizeof(client_addr));
Packet p(this, SEND_MTU);
/* The limit is UDP_MTU, but also allocate that much as we need to read the whole packet in one go. */
Packet p(this, UDP_MTU, UDP_MTU);
socklen_t client_len = sizeof(client_addr);
/* Try to receive anything */
@@ -506,7 +507,7 @@ void NetworkUDPSocketHandler::Receive_EX_MULTI(Packet *p, NetworkAddress *client
DEBUG(net, 6, "[udp] merged multi-part packet from %s: " OTTD_PRINTFHEX64 ", %u bytes",
NetworkAddressDumper().GetAddressAsString(client_addr), token, total_payload);
Packet merged(this, 0);
Packet merged(this, SHRT_MAX, 0);
merged.ReserveBuffer(total_payload);
for (auto &frag : fs.fragments) {
merged.Send_binary(frag.data(), frag.size());

View File

@@ -548,9 +548,10 @@ void ParseGameConnectionString(const char **company, const char **port, char *co
/* Register the login */
_network_clients_connected++;
SetWindowDirty(WC_CLIENT_LIST, 0);
ServerNetworkGameSocketHandler *cs = new ServerNetworkGameSocketHandler(s);
cs->client_address = address; // Save the IP of the client
InvalidateWindowData(WC_CLIENT_LIST, 0);
}
/**
@@ -743,7 +744,7 @@ void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const c
static void NetworkInitGameInfo()
{
if (StrEmpty(_settings_client.network.server_name)) {
seprintf(_settings_client.network.server_name, lastof(_settings_client.network.server_name), "Unnamed Server");
strecpy(_settings_client.network.server_name, "Unnamed Server", lastof(_settings_client.network.server_name));
}
/* The server is a client too */

View File

@@ -560,8 +560,8 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi
/* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
* are bigger than the MTU, just ignore the message. Better safe than sorry. It should
* never occur though as the longest strings are chat messages, which are still 30%
* smaller than SEND_MTU. */
if (strlen(origin) + strlen(string) + 2 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY;
* smaller than COMPAT_MTU. */
if (strlen(origin) + strlen(string) + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
@@ -610,7 +610,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
for (uint i = 0; i < CMD_END; i++) {
const char *cmdname = GetCommandName(i);
/* Should SEND_MTU be exceeded, start a new packet
/* Should COMPAT_MTU be exceeded, start a new packet
* (magic 5: 1 bool "more data" and one uint16 "command id", one
* byte for string '\0' termination and 1 bool "no more data" */
if (p->CanWriteToPacket(strlen(cmdname) + 5)) {

View File

@@ -411,7 +411,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyInformationQuery()
_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
Packet *p = new Packet(PACKET_CLIENT_COMPANY_INFO);
Packet *p = new Packet(PACKET_CLIENT_COMPANY_INFO, SHRT_MAX);
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -423,7 +423,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
Packet *p = new Packet(PACKET_CLIENT_JOIN);
Packet *p = new Packet(PACKET_CLIENT_JOIN, SHRT_MAX);
p->Send_string(_openttd_revision);
p->Send_uint32(_openttd_newgrf_version);
p->Send_string(_settings_client.network.client_name); // Client name
@@ -436,7 +436,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
/** Tell the server we got all the NewGRFs. */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
{
Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED);
Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED, SHRT_MAX);
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -447,7 +447,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password)
{
Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD);
Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _server_password_game_seed));
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@@ -459,7 +459,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *p
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char *password)
{
Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD);
Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@@ -471,7 +471,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const char *password)
{
Packet *p = new Packet(PACKET_CLIENT_SETTINGS_PASSWORD);
Packet *p = new Packet(PACKET_CLIENT_SETTINGS_PASSWORD, SHRT_MAX);
if (StrEmpty(password)) {
p->Send_string("");
} else {
@@ -486,7 +486,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
{
my_client->status = STATUS_MAP_WAIT;
Packet *p = new Packet(PACKET_CLIENT_GETMAP);
Packet *p = new Packet(PACKET_CLIENT_GETMAP, SHRT_MAX);
#if defined(WITH_ZSTD)
p->Send_bool(true);
#else
@@ -501,7 +501,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMapOk()
{
my_client->status = STATUS_ACTIVE;
Packet *p = new Packet(PACKET_CLIENT_MAP_OK);
Packet *p = new Packet(PACKET_CLIENT_MAP_OK, SHRT_MAX);
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -509,7 +509,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMapOk()
/** Send an acknowledgement from the server's ticks. */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendAck()
{
Packet *p = new Packet(PACKET_CLIENT_ACK);
Packet *p = new Packet(PACKET_CLIENT_ACK, SHRT_MAX);
p->Send_uint32(_frame_counter);
p->Send_uint8 (my_client->token);
@@ -523,7 +523,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendAck()
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
{
Packet *p = new Packet(PACKET_CLIENT_COMMAND);
Packet *p = new Packet(PACKET_CLIENT_COMMAND, SHRT_MAX);
my_client->NetworkGameSocketHandler::SendCommand(p, cp);
my_client->SendPacket(p);
@@ -534,7 +534,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacke
NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data)
{
if (!my_client) return NETWORK_RECV_STATUS_CONN_LOST;
Packet *p = new Packet(PACKET_CLIENT_CHAT);
Packet *p = new Packet(PACKET_CLIENT_CHAT, SHRT_MAX);
p->Send_uint8 (action);
p->Send_uint8 (type);
@@ -549,7 +549,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action,
/** Send an error-packet over the network */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode errorno)
{
Packet *p = new Packet(PACKET_CLIENT_ERROR);
Packet *p = new Packet(PACKET_CLIENT_ERROR, SHRT_MAX);
p->Send_uint8(errorno);
my_client->SendPacket(p);
@@ -560,7 +560,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode err
NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncLog(const std::string &log)
{
for (size_t offset = 0; offset < log.size();) {
Packet *p = new Packet(PACKET_CLIENT_DESYNC_LOG);
Packet *p = new Packet(PACKET_CLIENT_DESYNC_LOG, SHRT_MAX);
size_t size = std::min<size_t>(log.size() - offset, SHRT_MAX - 2 - p->Size());
p->Send_uint16(size);
p->Send_binary(log.data() + offset, size);
@@ -574,7 +574,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncLog(const std::strin
/** Send an error-packet over the network */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncMessage(const char *msg)
{
Packet *p = new Packet(PACKET_CLIENT_DESYNC_MSG);
Packet *p = new Packet(PACKET_CLIENT_DESYNC_MSG, SHRT_MAX);
p->Send_uint32(_date);
p->Send_uint16(_date_fract);
p->Send_uint8(_tick_skip_counter);
@@ -589,7 +589,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncMessage(const char *
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const char *password)
{
Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD);
Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
my_client->SendPacket(p);
@@ -602,7 +602,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const char *pa
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name)
{
Packet *p = new Packet(PACKET_CLIENT_SET_NAME);
Packet *p = new Packet(PACKET_CLIENT_SET_NAME, SHRT_MAX);
p->Send_string(name);
my_client->SendPacket(p);
@@ -614,7 +614,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name)
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
{
Packet *p = new Packet(PACKET_CLIENT_QUIT);
Packet *p = new Packet(PACKET_CLIENT_QUIT, SHRT_MAX);
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@@ -627,7 +627,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, const char *command)
{
Packet *p = new Packet(PACKET_CLIENT_RCON);
Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed));
p->Send_string(command);
my_client->SendPacket(p);
@@ -641,7 +641,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, con
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const char *password)
{
Packet *p = new Packet(PACKET_CLIENT_MOVE);
Packet *p = new Packet(PACKET_CLIENT_MOVE, SHRT_MAX);
p->Send_uint8(company);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
my_client->SendPacket(p);
@@ -760,7 +760,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
ci->client_playas = playas;
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -779,7 +779,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1176,7 +1176,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Pack
delete ci;
}
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1204,7 +1204,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id);
}
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
/* If we come here it means we could not locate the client.. strange :s */
return NETWORK_RECV_STATUS_OKAY;
@@ -1221,7 +1221,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_JOIN(Packet *p)
NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
}
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
return NETWORK_RECV_STATUS_OKAY;
}

View File

@@ -221,9 +221,9 @@ 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 = std::min<uint>(count, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
uint p_count = std::min<uint>(count, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID);
Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID, TCP_MTU);
p->Send_uint16(p_count);
for (uint i = 0; i < p_count; i++) {
@@ -247,13 +247,13 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo
this->Connect();
const uint max_per_packet = std::min<uint>(255, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
const uint max_per_packet = std::min<uint>(255, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))) - 1;
uint offset = 0;
while (cv->size() > offset) {
Packet *p = new Packet(send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID);
Packet *p = new Packet(send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID, TCP_MTU);
const uint to_send = std::min<uint>(cv->size() - offset, max_per_packet);
p->Send_uint8(to_send);
@@ -370,9 +370,9 @@ 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 = std::min<uint>(count, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
uint p_count = std::min<uint>(count, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT);
Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT, TCP_MTU);
p->Send_uint16(p_count);
for (uint i = 0; i < p_count; i++) {

File diff suppressed because it is too large Load Diff

View File

@@ -62,7 +62,8 @@ struct PacketWriter : SaveFilter {
ServerNetworkGameSocketHandler *cs; ///< Socket we are associated with.
std::unique_ptr<Packet> current; ///< The packet we're currently writing to.
size_t total_size; ///< Total size of the compressed savegame.
std::deque<std::unique_ptr<Packet>> packets; ///< Packet queue of the savegame; send these "slowly" to the client.
std::vector<std::unique_ptr<Packet>> packets; ///< Packet queue of the savegame; send these "slowly" to the client.
std::vector<std::unique_ptr<Packet>> prepend_packets; ///< Packet queue of the savegame; send these "slowly" to the client.
std::mutex mutex; ///< Mutex for making threaded saving safe.
std::condition_variable exit_sig; ///< Signal for threaded destruction of this packet writer.
@@ -84,6 +85,7 @@ struct PacketWriter : SaveFilter {
/* This must all wait until the Destroy function is called. */
this->packets.clear();
this->prepend_packets.clear();
this->current.reset();
}
@@ -114,30 +116,28 @@ struct PacketWriter : SaveFilter {
}
/**
* Checks whether there are packets.
* It's not 100% threading safe, but this is only asked for when checking
* whether there still is something to send. Then another call will be made
* to actually get the Packet, which will be the only one popping packets
* and thus eventually setting this on false.
* Transfer all packets from here to the network's queue while holding
* the lock on our mutex.
* @param socket The network socket to write to.
* @return True iff the last packet of the map has been sent.
*/
bool HasPackets()
bool TransferToNetworkQueue(ServerNetworkGameSocketHandler *socket)
{
std::lock_guard<std::mutex> lock(this->mutex);
return !this->packets.empty();
}
for (auto &p : this->prepend_packets) {
socket->SendPrependPacket(std::move(p));
}
bool last_packet = false;
for (auto &p : this->packets) {
if (p->GetPacketType() == PACKET_SERVER_MAP_DONE) last_packet = true;
socket->SendPacket(std::move(p));
}
this->prepend_packets.clear();
this->packets.clear();
/**
* Pop a single created packet from the queue with packets.
*/
std::unique_ptr<Packet> PopPacket()
{
std::lock_guard<std::mutex> lock(this->mutex);
if (this->packets.empty()) return nullptr;
std::unique_ptr<Packet> p = std::move(this->packets.front());
this->packets.pop_front();
return p;
return last_packet;
}
/** Append the current packet to the queue. */
@@ -153,7 +153,7 @@ struct PacketWriter : SaveFilter {
{
if (this->current == nullptr) return;
this->packets.push_front(std::move(this->current));
this->prepend_packets.push_back(std::move(this->current));
}
void Write(byte *buf, size_t size) override
@@ -161,7 +161,7 @@ struct PacketWriter : SaveFilter {
/* We want to abort the saving when the socket is closed. */
if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
if (this->current == nullptr) this->current.reset(new Packet(PACKET_SERVER_MAP_DATA));
if (this->current == nullptr) this->current.reset(new Packet(PACKET_SERVER_MAP_DATA, SHRT_MAX));
std::lock_guard<std::mutex> lock(this->mutex);
@@ -172,7 +172,7 @@ struct PacketWriter : SaveFilter {
if (!this->current->CanWriteToPacket(1)) {
this->AppendQueue();
if (buf != bufe) this->current.reset(new Packet(PACKET_SERVER_MAP_DATA));
if (buf != bufe) this->current.reset(new Packet(PACKET_SERVER_MAP_DATA, SHRT_MAX));
}
}
@@ -190,11 +190,11 @@ struct PacketWriter : SaveFilter {
this->AppendQueue();
/* Add a packet stating that this is the end to the queue. */
this->current.reset(new Packet(PACKET_SERVER_MAP_DONE));
this->current.reset(new Packet(PACKET_SERVER_MAP_DONE, SHRT_MAX));
this->AppendQueue();
/* Fast-track the size to the client. */
this->current.reset(new Packet(PACKET_SERVER_MAP_SIZE));
this->current.reset(new Packet(PACKET_SERVER_MAP_SIZE, SHRT_MAX));
this->current->Send_uint32((uint32)this->total_size);
this->PrependQueue();
}
@@ -296,14 +296,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
extern byte _network_clients_connected;
_network_clients_connected--;
DeleteWindowById(WC_CLIENT_LIST_POPUP, this->client_id);
SetWindowDirty(WC_CLIENT_LIST, 0);
this->SendPackets(true);
delete this->GetInfo();
delete this;
InvalidateWindowData(WC_CLIENT_LIST, 0);
return status;
}
@@ -357,7 +356,7 @@ static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientInfo *ci)
{
if (ci->client_id != INVALID_CLIENT_ID) {
Packet *p = new Packet(PACKET_SERVER_CLIENT_INFO);
Packet *p = new Packet(PACKET_SERVER_CLIENT_INFO, SHRT_MAX);
p->Send_uint32(ci->client_id);
p->Send_uint8 (ci->client_playas);
p->Send_string(ci->client_name);
@@ -404,7 +403,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
Packet *p;
for (const Company *company : Company::Iterate()) {
p = new Packet(PACKET_SERVER_COMPANY_INFO);
p = new Packet(PACKET_SERVER_COMPANY_INFO, SHRT_MAX);
p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
p->Send_bool (true);
@@ -419,7 +418,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
this->SendPacket(p);
}
p = new Packet(PACKET_SERVER_COMPANY_INFO);
p = new Packet(PACKET_SERVER_COMPANY_INFO, SHRT_MAX);
p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
p->Send_bool (false);
@@ -436,7 +435,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason)
{
char str[100];
Packet *p = new Packet(PACKET_SERVER_ERROR);
Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX);
p->Send_uint8(error);
if (reason != nullptr) p->Send_string(reason);
@@ -482,7 +481,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
NetworkRecvStatus ServerNetworkGameSocketHandler::SendDesyncLog(const std::string &log)
{
for (size_t offset = 0; offset < log.size();) {
Packet *p = new Packet(PACKET_SERVER_DESYNC_LOG);
Packet *p = new Packet(PACKET_SERVER_DESYNC_LOG, SHRT_MAX);
size_t size = std::min<size_t>(log.size() - offset, SHRT_MAX - 2 - p->Size());
p->Send_uint16(size);
p->Send_binary(log.data() + offset, size);
@@ -496,7 +495,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendDesyncLog(const std::strin
/** Send the check for the NewGRFs. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
{
Packet *p = new Packet(PACKET_SERVER_CHECK_NEWGRFS);
Packet *p = new Packet(PACKET_SERVER_CHECK_NEWGRFS, SHRT_MAX);
const GRFConfig *c;
uint grf_count = 0;
@@ -523,7 +522,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword()
/* Reset 'lag' counters */
this->last_frame = this->last_frame_server = _frame_counter;
Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD);
Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD, SHRT_MAX);
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->server_hash_bits);
p->Send_string(_settings_client.network.network_id);
this->SendPacket(p);
@@ -540,7 +539,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
/* Reset 'lag' counters */
this->last_frame = this->last_frame_server = _frame_counter;
Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD);
Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD, SHRT_MAX);
p->Send_uint32(_settings_game.game_creation.generation_seed);
p->Send_string(_settings_client.network.network_id);
this->SendPacket(p);
@@ -561,7 +560,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
_network_game_info.clients_on++;
p = new Packet(PACKET_SERVER_WELCOME);
p = new Packet(PACKET_SERVER_WELCOME, SHRT_MAX);
p->Send_uint32(this->client_id);
p->Send_uint32(_settings_game.game_creation.generation_seed);
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->server_hash_bits);
@@ -592,7 +591,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait()
if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++;
}
p = new Packet(PACKET_SERVER_WAIT);
p = new Packet(PACKET_SERVER_WAIT, SHRT_MAX);
p->Send_uint8(waiting);
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@@ -628,8 +627,6 @@ void ServerNetworkGameSocketHandler::CheckNextClientToSendMap(NetworkClientSocke
/** This sends the map to the client */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
{
static uint sent_packets; // How many packets we did send successfully last time
if (this->status < STATUS_AUTHORIZED) {
/* Illegal call, return error and ignore the packet */
return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
@@ -639,7 +636,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
this->savegame = new PacketWriter(this);
/* Now send the _frame_counter and how many packets are coming */
Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN);
Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN, SHRT_MAX);
p->Send_uint32(_frame_counter);
this->SendPacket(p);
@@ -649,8 +646,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
this->last_frame = _frame_counter;
this->last_frame_server = _frame_counter;
sent_packets = 4; // We start with trying 4 packets
/* Make a dump of the current game */
SaveModeFlags flags = SMF_NET_SERVER;
if (this->supports_zstd) flags |= SMF_ZSTD_OK;
@@ -658,25 +653,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
}
if (this->status == STATUS_MAP) {
bool last_packet = false;
bool has_packets = true;
for (uint i = 0; i < sent_packets; i++) {
std::unique_ptr<Packet> p = this->savegame->PopPacket();
if (p == nullptr) {
has_packets = false;
break;
}
last_packet = p->GetPacketType() == PACKET_SERVER_MAP_DONE;
this->SendPacket(std::move(p));
if (last_packet) {
/* There is no more data, so break the for */
break;
}
}
bool last_packet = this->savegame->TransferToNetworkQueue(this);
if (last_packet) {
/* Done reading, make sure saving is done as well */
this->savegame->Destroy();
@@ -688,25 +665,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
this->CheckNextClientToSendMap();
}
switch (this->SendPackets()) {
case SPS_CLOSED:
return NETWORK_RECV_STATUS_CONN_LOST;
case SPS_ALL_SENT:
/* All are sent, increase the sent_packets */
if (has_packets) sent_packets *= 2;
break;
case SPS_PARTLY_SENT:
/* Only a part is sent; leave the transmission state. */
break;
case SPS_NONE_SENT:
/* Not everything is sent, decrease the sent_packets */
if (sent_packets > 1) sent_packets /= 2;
break;
}
}
return NETWORK_RECV_STATUS_OKAY;
}
@@ -717,7 +675,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id)
{
Packet *p = new Packet(PACKET_SERVER_JOIN);
Packet *p = new Packet(PACKET_SERVER_JOIN, SHRT_MAX);
p->Send_uint32(client_id);
@@ -728,7 +686,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id)
/** Tell the client that they may run to a particular frame. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame()
{
Packet *p = new Packet(PACKET_SERVER_FRAME);
Packet *p = new Packet(PACKET_SERVER_FRAME, SHRT_MAX);
p->Send_uint32(_frame_counter);
p->Send_uint32(_frame_counter_max);
#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
@@ -752,7 +710,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame()
/** Request the client to sync. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync()
{
Packet *p = new Packet(PACKET_SERVER_SYNC);
Packet *p = new Packet(PACKET_SERVER_SYNC, SHRT_MAX);
p->Send_uint32(_frame_counter);
p->Send_uint32(_sync_seed_1);
@@ -770,7 +728,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync()
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
{
Packet *p = new Packet(PACKET_SERVER_COMMAND);
Packet *p = new Packet(PACKET_SERVER_COMMAND, SHRT_MAX);
this->NetworkGameSocketHandler::SendCommand(p, cp);
p->Send_uint32(cp->frame);
@@ -792,7 +750,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action,
{
if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(PACKET_SERVER_CHAT);
Packet *p = new Packet(PACKET_SERVER_CHAT, SHRT_MAX);
p->Send_uint8 (action);
p->Send_uint32(client_id);
@@ -811,7 +769,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action,
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
{
Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT);
Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT, SHRT_MAX);
p->Send_uint32(client_id);
p->Send_uint8 (errorno);
@@ -826,7 +784,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id)
{
Packet *p = new Packet(PACKET_SERVER_QUIT);
Packet *p = new Packet(PACKET_SERVER_QUIT, SHRT_MAX);
p->Send_uint32(client_id);
@@ -837,7 +795,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id)
/** Tell the client we're shutting down. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown()
{
Packet *p = new Packet(PACKET_SERVER_SHUTDOWN);
Packet *p = new Packet(PACKET_SERVER_SHUTDOWN, SHRT_MAX);
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -845,7 +803,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown()
/** Tell the client we're starting a new game. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
{
Packet *p = new Packet(PACKET_SERVER_NEWGAME);
Packet *p = new Packet(PACKET_SERVER_NEWGAME, SHRT_MAX);
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -857,7 +815,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command)
{
Packet *p = new Packet(PACKET_SERVER_RCON);
Packet *p = new Packet(PACKET_SERVER_RCON, SHRT_MAX);
p->Send_uint16(colour);
p->Send_string(command);
@@ -872,7 +830,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour,
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, CompanyID company_id)
{
Packet *p = new Packet(PACKET_SERVER_MOVE);
Packet *p = new Packet(PACKET_SERVER_MOVE, SHRT_MAX);
p->Send_uint32(client_id);
p->Send_uint8(company_id);
@@ -883,7 +841,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, C
/** Send an update about the company password states. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
{
Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE);
Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE, SHRT_MAX);
p->Send_uint16(_network_company_passworded);
this->SendPacket(p);
@@ -893,7 +851,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
/** Send an update about the max company/spectator counts. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
{
Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE);
Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE, SHRT_MAX);
p->Send_uint8(_settings_client.network.max_companies);
p->Send_uint8(_settings_client.network.max_spectators);
@@ -903,7 +861,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
NetworkRecvStatus ServerNetworkGameSocketHandler::SendSettingsAccessUpdate(bool ok)
{
Packet *p = new Packet(PACKET_SERVER_SETTINGS_ACCESS);
Packet *p = new Packet(PACKET_SERVER_SETTINGS_ACCESS, SHRT_MAX);
p->Send_bool(ok);
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@@ -1123,6 +1081,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *
this->GetClientName(client_name, lastof(client_name));
NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, nullptr, this->client_id);
InvalidateWindowData(WC_CLIENT_LIST, 0);
/* Mark the client as pre-active, and wait for an ACK
* so we know he is done loading and in sync with us */
@@ -2193,6 +2152,8 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
InvalidateWindowData(WC_CLIENT_LIST, 0);
}
/**

View File

@@ -233,7 +233,7 @@ void ServerNetworkUDPSocketHandler::Reply_CLIENT_FIND_SERVER_extended(Packet *p,
uint16 flags = p->Recv_uint16();
uint16 version = p->Recv_uint16();
Packet packet(PACKET_UDP_EX_SERVER_RESPONSE);
Packet packet(PACKET_UDP_EX_SERVER_RESPONSE, SHRT_MAX);
this->SendNetworkGameInfoExtended(&packet, ngi, flags, version);
/* Let the client know that we are here */
@@ -297,10 +297,10 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, Networ
/**
* A client has requested the names of some NewGRFs.
*
* Replying this can be tricky as we have a limit of SEND_MTU bytes
* Replying this can be tricky as we have a limit of UDP_MTU bytes
* in the reply packet and we can send up to 100 bytes per NewGRF
* (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name).
* As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
* As UDP_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
* could be that a packet overflows. To stop this we only reply
* with the first N NewGRFs so that if the first N + 1 NewGRFs
* would be sent, the packet overflows.
@@ -371,7 +371,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ
* The name could be an empty string, if so take the filename. */
size_t required_length = sizeof(info.ident.grfid) + sizeof(info.ident.md5sum) +
std::min(strlen(info.name) + 1, (size_t)NETWORK_GRF_NAME_LENGTH);
if (packet_len + required_length > SEND_MTU_SHORT - 4) { // 4 is 3 byte header + grf count in reply
if (packet_len + required_length > UDP_MTU_SHORT - 4) { // 4 is 3 byte header + grf count in reply
flush_response();
}
packet_len += required_length;