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:
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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());
|
||||
|
@@ -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 */
|
||||
|
@@ -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)) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user