From ec4104ec6cc1a944762afd663a00dcbb15555718 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 6 Feb 2024 18:56:56 +0100 Subject: [PATCH 01/15] Codechange: do not pass the socket when the receiver already knows it --- src/network/network_server.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index f0eba6d005..683774858e 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -116,10 +116,9 @@ struct PacketWriter : SaveFilter { /** * 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 TransferToNetworkQueue(ServerNetworkGameSocketHandler *socket) + bool TransferToNetworkQueue() { /* Unsafe check for the queue being empty or not. */ if (this->packets.empty()) return false; @@ -128,7 +127,7 @@ struct PacketWriter : SaveFilter { while (!this->packets.empty()) { bool last_packet = this->packets.front()->GetPacketType() == PACKET_SERVER_MAP_DONE; - socket->SendPacket(std::move(this->packets.front())); + this->cs->SendPacket(std::move(this->packets.front())); this->packets.pop_front(); if (last_packet) return true; @@ -577,7 +576,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() } if (this->status == STATUS_MAP) { - bool last_packet = this->savegame->TransferToNetworkQueue(this); + bool last_packet = this->savegame->TransferToNetworkQueue(); if (last_packet) { Debug(net, 9, "client[{}] SendMap(): last_packet", this->client_id); From 3c488e1eb81e3ff7e4b90f03da533d6aa5019d9f Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 6 Feb 2024 18:59:58 +0100 Subject: [PATCH 02/15] Codechange: don't check things outside the lock, that could change while waiting on the lock --- src/network/network_server.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 683774858e..f79f0a7ff3 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -138,13 +138,13 @@ struct PacketWriter : SaveFilter { void Write(byte *buf, size_t size) override { + std::lock_guard lock(this->mutex); + /* 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 = std::make_unique(PACKET_SERVER_MAP_DATA, TCP_MTU); - std::lock_guard lock(this->mutex); - byte *bufe = buf + size; while (buf != bufe) { size_t written = this->current->Send_bytes(buf, bufe); @@ -161,11 +161,11 @@ struct PacketWriter : SaveFilter { void Finish() override { + std::lock_guard lock(this->mutex); + /* We want to abort the saving when the socket is closed. */ if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); - std::lock_guard lock(this->mutex); - /* Make sure the last packet is flushed. */ if (this->current != nullptr) this->packets.push_back(std::move(this->current)); From 6eff879e4906da99c9e8963e321bd21976c403ec Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sun, 4 Feb 2024 12:31:56 +0100 Subject: [PATCH 03/15] Codechange: pass the socket handler that is going to send the packet into the packet --- src/network/core/packet.cpp | 7 ++-- src/network/core/packet.h | 2 +- src/network/core/tcp_listen.h | 4 +-- src/network/network_admin.cpp | 52 +++++++++++++-------------- src/network/network_client.cpp | 30 ++++++++-------- src/network/network_content.cpp | 8 ++--- src/network/network_coordinator.cpp | 14 ++++---- src/network/network_query.cpp | 2 +- src/network/network_server.cpp | 54 ++++++++++++++--------------- src/network/network_stun.cpp | 2 +- src/network/network_turn.cpp | 2 +- src/network/network_udp.cpp | 4 +-- 12 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index d4cf165125..f314dc803c 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -38,13 +38,14 @@ Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) /** * Creates a packet to send + * @param cs The socket handler associated with the socket we are writing to; could be \c nullptr. * @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, size_t limit) : pos(0), limit(limit), cs(nullptr) +Packet::Packet(NetworkSocketHandler *cs, PacketType type, size_t limit) : pos(0), limit(limit), cs(cs) { /* Allocate space for the the size so we can write that in just before sending the packet. */ this->Send_uint16(0); @@ -57,7 +58,8 @@ Packet::Packet(PacketType type, size_t limit) : pos(0), limit(limit), cs(nullptr */ void Packet::PrepareToSend() { - assert(this->cs == nullptr); + /* Prevent this to be called twice and for packets that have been received. */ + assert(this->buffer[0] == 0 && this->buffer[1] == 0); this->buffer[0] = GB(this->Size(), 0, 8); this->buffer[1] = GB(this->Size(), 8, 8); @@ -243,7 +245,6 @@ size_t Packet::Size() const */ bool Packet::ParsePacketSize() { - assert(this->cs != nullptr); size_t size = (size_t)this->buffer[0]; size += (size_t)this->buffer[1] << 8; diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 9cedfd63e1..f403f37ae7 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -53,7 +53,7 @@ private: public: Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = sizeof(PacketSize)); - Packet(PacketType type, size_t limit = COMPAT_MTU); + Packet(NetworkSocketHandler *cs, PacketType type, size_t limit = COMPAT_MTU); /* Sending/writing of packets */ void PrepareToSend(); diff --git a/src/network/core/tcp_listen.h b/src/network/core/tcp_listen.h index 088cc7b8cd..6e6d95e5da 100644 --- a/src/network/core/tcp_listen.h +++ b/src/network/core/tcp_listen.h @@ -35,7 +35,7 @@ public: /* Check if the client is banned. */ for (const auto &entry : _network_ban_list) { if (address.IsInNetmask(entry)) { - Packet p(Tban_packet); + Packet p(nullptr, Tban_packet); p.PrepareToSend(); Debug(net, 2, "[{}] Banned ip tried to join ({}), refused", Tsocket::GetName(), entry); @@ -52,7 +52,7 @@ public: if (!Tsocket::AllowConnection()) { /* No more clients allowed? * Send to the client that we are full! */ - Packet p(Tfull_packet); + Packet p(nullptr, Tfull_packet); p.PrepareToSend(); if (p.TransferOut(send, s, 0) < 0) { diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 028acc4d72..84e14ea4d9 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -134,7 +134,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode error) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_ERROR); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_ERROR); p->Send_uint8(error); this->SendPacket(std::move(p)); @@ -149,7 +149,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er /** Send the protocol version to the admin. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_PROTOCOL); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_PROTOCOL); /* announce the protocol version */ p->Send_uint8(NETWORK_GAME_ADMIN_VERSION); @@ -169,7 +169,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol() /** Send a welcome message to the admin. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_WELCOME); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_WELCOME); p->Send_string(_settings_client.network.server_name); p->Send_string(GetNetworkRevisionString()); @@ -190,7 +190,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome() /** Tell the admin we started a new game. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_NEWGAME); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_NEWGAME); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -198,7 +198,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame() /** Tell the admin we're shutting down. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_SHUTDOWN); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_SHUTDOWN); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -206,7 +206,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown() /** Tell the admin the date. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_DATE); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_DATE); p->Send_uint32(TimerGameCalendar::date.base()); this->SendPacket(std::move(p)); @@ -220,7 +220,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate() */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID client_id) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CLIENT_JOIN); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CLIENT_JOIN); p->Send_uint32(client_id); this->SendPacket(std::move(p)); @@ -238,7 +238,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkC /* Only send data when we're a proper client, not just someone trying to query the server. */ if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY; - auto p = std::make_unique(ADMIN_PACKET_SERVER_CLIENT_INFO); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CLIENT_INFO); p->Send_uint32(ci->client_id); p->Send_string(cs == nullptr ? "" : const_cast(cs->client_address).GetHostname()); @@ -259,7 +259,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkC */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const NetworkClientInfo *ci) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CLIENT_UPDATE); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CLIENT_UPDATE); p->Send_uint32(ci->client_id); p->Send_string(ci->client_name); @@ -276,7 +276,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const Networ */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID client_id) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CLIENT_QUIT); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CLIENT_QUIT); p->Send_uint32(client_id); this->SendPacket(std::move(p)); @@ -291,7 +291,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID clien */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID client_id, NetworkErrorCode error) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CLIENT_ERROR); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CLIENT_ERROR); p->Send_uint32(client_id); p->Send_uint8 (error); @@ -306,7 +306,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID clie */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID company_id) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_NEW); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_NEW); p->Send_uint8(company_id); this->SendPacket(std::move(p)); @@ -320,7 +320,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID comp */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_INFO); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_INFO); p->Send_uint8 (c->index); SetDParam(0, c->index); @@ -345,7 +345,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_UPDATE); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_UPDATE); p->Send_uint8 (c->index); SetDParam(0, c->index); @@ -368,7 +368,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Compa */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason acrr) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_REMOVE); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_REMOVE); p->Send_uint8(company_id); p->Send_uint8(acrr); @@ -385,7 +385,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy() /* Get the income. */ Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0])); - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_ECONOMY); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_ECONOMY); p->Send_uint8(company->index); @@ -418,7 +418,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats() /* Go through all the companies. */ for (const Company *company : Company::Iterate()) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_COMPANY_STATS); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_COMPANY_STATS); /* Send the information. */ p->Send_uint8(company->index); @@ -447,7 +447,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats() */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CHAT); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CHAT); p->Send_uint8 (action); p->Send_uint8 (desttype); @@ -465,7 +465,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string_view command) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_RCON_END); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_RCON_END); p->Send_string(command); this->SendPacket(std::move(p)); @@ -480,7 +480,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, const std::string_view result) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_RCON); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_RCON); p->Send_uint16(colour); p->Send_string(result); @@ -539,7 +539,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string * smaller than COMPAT_MTU. */ if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY; - auto p = std::make_unique(ADMIN_PACKET_SERVER_CONSOLE); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CONSOLE); p->Send_string(origin); p->Send_string(string); @@ -554,7 +554,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_GAMESCRIPT); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_GAMESCRIPT); p->Send_string(json); this->SendPacket(std::move(p)); @@ -565,7 +565,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::str /** Send ping-reply (pong) to admin **/ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendPong(uint32_t d1) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_PONG); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_PONG); p->Send_uint32(d1); this->SendPacket(std::move(p)); @@ -576,7 +576,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendPong(uint32_t d1) /** Send the names of the commands. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames() { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CMD_NAMES); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CMD_NAMES); for (uint16_t i = 0; i < CMD_END; i++) { const char *cmdname = GetCommandName(static_cast(i)); @@ -588,7 +588,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames() p->Send_bool(false); this->SendPacket(std::move(p)); - p = std::make_unique(ADMIN_PACKET_SERVER_CMD_NAMES); + p = std::make_unique(this, ADMIN_PACKET_SERVER_CMD_NAMES); } p->Send_bool(true); @@ -610,7 +610,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames() */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID client_id, const CommandPacket &cp) { - auto p = std::make_unique(ADMIN_PACKET_SERVER_CMD_LOGGING); + auto p = std::make_unique(this, ADMIN_PACKET_SERVER_CMD_LOGGING); p->Send_uint32(client_id); p->Send_uint8 (cp.company); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 7d961ab005..ded54f0bae 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -344,7 +344,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin() _network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING; SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); - auto p = std::make_unique(PACKET_CLIENT_JOIN); + auto p = std::make_unique(my_client, PACKET_CLIENT_JOIN); p->Send_string(GetNetworkRevisionString()); p->Send_uint32(_openttd_newgrf_version); p->Send_string(_settings_client.network.client_name); // Client name @@ -359,7 +359,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk() { Debug(net, 9, "Client::SendNewGRFsOk()"); - auto p = std::make_unique(PACKET_CLIENT_NEWGRFS_CHECKED); + auto p = std::make_unique(my_client, PACKET_CLIENT_NEWGRFS_CHECKED); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -372,7 +372,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const std::st { Debug(net, 9, "Client::SendGamePassword()"); - auto p = std::make_unique(PACKET_CLIENT_GAME_PASSWORD); + auto p = std::make_unique(my_client, PACKET_CLIENT_GAME_PASSWORD); p->Send_string(password); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; @@ -386,7 +386,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std: { Debug(net, 9, "Client::SendCompanyPassword()"); - auto p = std::make_unique(PACKET_CLIENT_COMPANY_PASSWORD); + auto p = std::make_unique(my_client, PACKET_CLIENT_COMPANY_PASSWORD); p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed)); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; @@ -400,7 +400,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap() Debug(net, 9, "Client::status = MAP_WAIT"); my_client->status = STATUS_MAP_WAIT; - auto p = std::make_unique(PACKET_CLIENT_GETMAP); + auto p = std::make_unique(my_client, PACKET_CLIENT_GETMAP); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -413,7 +413,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMapOk() Debug(net, 9, "Client::status = ACTIVE"); my_client->status = STATUS_ACTIVE; - auto p = std::make_unique(PACKET_CLIENT_MAP_OK); + auto p = std::make_unique(my_client, PACKET_CLIENT_MAP_OK); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -423,7 +423,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendAck() { Debug(net, 9, "Client::SendAck()"); - auto p = std::make_unique(PACKET_CLIENT_ACK); + auto p = std::make_unique(my_client, PACKET_CLIENT_ACK); p->Send_uint32(_frame_counter); p->Send_uint8 (my_client->token); @@ -439,7 +439,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacke { Debug(net, 9, "Client::SendCommand(): cmd={}", cp.cmd); - auto p = std::make_unique(PACKET_CLIENT_COMMAND); + auto p = std::make_unique(my_client, PACKET_CLIENT_COMMAND); my_client->NetworkGameSocketHandler::SendCommand(*p, cp); my_client->SendPacket(std::move(p)); @@ -451,7 +451,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, { Debug(net, 9, "Client::SendChat(): action={}, type={}, dest={}", action, type, dest); - auto p = std::make_unique(PACKET_CLIENT_CHAT); + auto p = std::make_unique(my_client, PACKET_CLIENT_CHAT); p->Send_uint8 (action); p->Send_uint8 (type); @@ -468,7 +468,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode err { Debug(net, 9, "Client::SendError(): errorno={}", errorno); - auto p = std::make_unique(PACKET_CLIENT_ERROR); + auto p = std::make_unique(my_client, PACKET_CLIENT_ERROR); p->Send_uint8(errorno); my_client->SendPacket(std::move(p)); @@ -483,7 +483,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str { Debug(net, 9, "Client::SendSetPassword()"); - auto p = std::make_unique(PACKET_CLIENT_SET_PASSWORD); + auto p = std::make_unique(my_client, PACKET_CLIENT_SET_PASSWORD); p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed)); my_client->SendPacket(std::move(p)); @@ -498,7 +498,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const std::string { Debug(net, 9, "Client::SendSetName()"); - auto p = std::make_unique(PACKET_CLIENT_SET_NAME); + auto p = std::make_unique(my_client, PACKET_CLIENT_SET_NAME); p->Send_string(name); my_client->SendPacket(std::move(p)); @@ -512,7 +512,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit() { Debug(net, 9, "Client::SendQuit()"); - auto p = std::make_unique(PACKET_CLIENT_QUIT); + auto p = std::make_unique(my_client, PACKET_CLIENT_QUIT); my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; @@ -527,7 +527,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pa { Debug(net, 9, "Client::SendRCon()"); - auto p = std::make_unique(PACKET_CLIENT_RCON); + auto p = std::make_unique(my_client, PACKET_CLIENT_RCON); p->Send_string(pass); p->Send_string(command); my_client->SendPacket(std::move(p)); @@ -543,7 +543,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, co { Debug(net, 9, "Client::SendMove(): company={}", company); - auto p = std::make_unique(PACKET_CLIENT_MOVE); + auto p = std::make_unique(my_client, PACKET_CLIENT_MOVE); p->Send_uint8(company); p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed)); my_client->SendPacket(std::move(p)); diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index caa437f2fe..4f51ddbcd4 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -204,7 +204,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentType type) this->Connect(); - auto p = std::make_unique(PACKET_CONTENT_CLIENT_INFO_LIST); + auto p = std::make_unique(this, PACKET_CONTENT_CLIENT_INFO_LIST); p->Send_uint8 ((byte)type); p->Send_uint32(0xffffffff); p->Send_uint8 (1); @@ -240,7 +240,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(uint count, const Con * The rest of the packet can be used for the IDs. */ uint p_count = std::min(count, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16_t)) / sizeof(uint32_t)); - auto p = std::make_unique(PACKET_CONTENT_CLIENT_INFO_ID, TCP_MTU); + auto p = std::make_unique(this, PACKET_CONTENT_CLIENT_INFO_ID, TCP_MTU); p->Send_uint16(p_count); for (uint i = 0; i < p_count; i++) { @@ -268,7 +268,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo assert(cv->size() < (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8_t)) / (sizeof(uint8_t) + sizeof(uint32_t) + (send_md5sum ? MD5_HASH_BYTES : 0))); - auto p = std::make_unique(send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID, TCP_MTU); + auto p = std::make_unique(this, send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID, TCP_MTU); p->Send_uint8((uint8_t)cv->size()); for (const ContentInfo *ci : *cv) { @@ -365,7 +365,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const Co * The rest of the packet can be used for the IDs. */ uint p_count = std::min(count, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16_t)) / sizeof(uint32_t)); - auto p = std::make_unique(PACKET_CONTENT_CLIENT_CONTENT, TCP_MTU); + auto p = std::make_unique(this, PACKET_CONTENT_CLIENT_CONTENT, TCP_MTU); p->Send_uint16(p_count); for (uint i = 0; i < p_count; i++) { diff --git a/src/network/network_coordinator.cpp b/src/network/network_coordinator.cpp index 129b26f8fb..e7bd0fdb6c 100644 --- a/src/network/network_coordinator.cpp +++ b/src/network/network_coordinator.cpp @@ -458,7 +458,7 @@ void ClientNetworkCoordinatorSocketHandler::Register() this->Connect(); - auto p = std::make_unique(PACKET_COORDINATOR_SERVER_REGISTER); + auto p = std::make_unique(this, PACKET_COORDINATOR_SERVER_REGISTER); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_uint8(_settings_client.network.server_game_type); p->Send_uint16(_settings_client.network.server_port); @@ -480,7 +480,7 @@ void ClientNetworkCoordinatorSocketHandler::SendServerUpdate() { Debug(net, 6, "Sending server update to Game Coordinator"); - auto p = std::make_unique(PACKET_COORDINATOR_SERVER_UPDATE, TCP_MTU); + auto p = std::make_unique(this, PACKET_COORDINATOR_SERVER_UPDATE, TCP_MTU); p->Send_uint8(NETWORK_COORDINATOR_VERSION); SerializeNetworkGameInfo(*p, GetCurrentNetworkServerGameInfo(), this->next_update.time_since_epoch() != std::chrono::nanoseconds::zero()); @@ -498,7 +498,7 @@ void ClientNetworkCoordinatorSocketHandler::GetListing() _network_game_list_version++; - auto p = std::make_unique(PACKET_COORDINATOR_CLIENT_LISTING); + auto p = std::make_unique(this, PACKET_COORDINATOR_CLIENT_LISTING); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_uint8(NETWORK_GAME_INFO_VERSION); p->Send_string(_openttd_revision); @@ -530,7 +530,7 @@ void ClientNetworkCoordinatorSocketHandler::ConnectToServer(const std::string &i this->Connect(); - auto p = std::make_unique(PACKET_COORDINATOR_CLIENT_CONNECT); + auto p = std::make_unique(this, PACKET_COORDINATOR_CLIENT_CONNECT); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(invite_code); @@ -547,7 +547,7 @@ void ClientNetworkCoordinatorSocketHandler::ConnectFailure(const std::string &to /* Connecter will destroy itself. */ this->game_connecter = nullptr; - auto p = std::make_unique(PACKET_COORDINATOR_SERCLI_CONNECT_FAILED); + auto p = std::make_unique(this, PACKET_COORDINATOR_SERCLI_CONNECT_FAILED); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(token); p->Send_uint8(tracking_number); @@ -578,7 +578,7 @@ void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &to } else { /* The client informs the Game Coordinator about the success. The server * doesn't have to, as it is implied by the client telling. */ - auto p = std::make_unique(PACKET_COORDINATOR_CLIENT_CONNECTED); + auto p = std::make_unique(this, PACKET_COORDINATOR_CLIENT_CONNECTED); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(token); this->SendPacket(std::move(p)); @@ -606,7 +606,7 @@ void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &to */ void ClientNetworkCoordinatorSocketHandler::StunResult(const std::string &token, uint8_t family, bool result) { - auto p = std::make_unique(PACKET_COORDINATOR_SERCLI_STUN_RESULT); + auto p = std::make_unique(this, PACKET_COORDINATOR_SERCLI_STUN_RESULT); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(token); p->Send_uint8(family); diff --git a/src/network/network_query.cpp b/src/network/network_query.cpp index 34cbd09289..9f87a277f9 100644 --- a/src/network/network_query.cpp +++ b/src/network/network_query.cpp @@ -83,7 +83,7 @@ NetworkRecvStatus QueryNetworkGameSocketHandler::SendGameInfo() { Debug(net, 9, "Query::SendGameInfo()"); - this->SendPacket(std::make_unique(PACKET_CLIENT_GAME_INFO)); + this->SendPacket(std::make_unique(this, PACKET_CLIENT_GAME_INFO)); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index f79f0a7ff3..a1fbf09302 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -143,7 +143,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 = std::make_unique(PACKET_SERVER_MAP_DATA, TCP_MTU); + if (this->current == nullptr) this->current = std::make_unique(this->cs, PACKET_SERVER_MAP_DATA, TCP_MTU); byte *bufe = buf + size; while (buf != bufe) { @@ -152,7 +152,7 @@ struct PacketWriter : SaveFilter { if (!this->current->CanWriteToPacket(1)) { this->packets.push_back(std::move(this->current)); - if (buf != bufe) this->current = std::make_unique(PACKET_SERVER_MAP_DATA, TCP_MTU); + if (buf != bufe) this->current = std::make_unique(this->cs, PACKET_SERVER_MAP_DATA, TCP_MTU); } } @@ -170,10 +170,10 @@ struct PacketWriter : SaveFilter { if (this->current != nullptr) this->packets.push_back(std::move(this->current)); /* Add a packet stating that this is the end to the queue. */ - this->packets.push_back(std::make_unique(PACKET_SERVER_MAP_DONE)); + this->packets.push_back(std::make_unique(this->cs, PACKET_SERVER_MAP_DONE)); /* Fast-track the size to the client. */ - auto p = std::make_unique(PACKET_SERVER_MAP_SIZE); + auto p = std::make_unique(this->cs, PACKET_SERVER_MAP_SIZE); p->Send_uint32((uint32_t)this->total_size); this->packets.push_front(std::move(p)); } @@ -324,7 +324,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientIn Debug(net, 9, "client[{}] SendClientInfo(): client_id={}", this->client_id, ci->client_id); if (ci->client_id != INVALID_CLIENT_ID) { - auto p = std::make_unique(PACKET_SERVER_CLIENT_INFO); + auto p = std::make_unique(this, PACKET_SERVER_CLIENT_INFO); p->Send_uint32(ci->client_id); p->Send_uint8 (ci->client_playas); p->Send_string(ci->client_name); @@ -339,7 +339,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendGameInfo() { Debug(net, 9, "client[{}] SendGameInfo()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_GAME_INFO, TCP_MTU); + auto p = std::make_unique(this, PACKET_SERVER_GAME_INFO, TCP_MTU); SerializeNetworkGameInfo(*p, GetCurrentNetworkServerGameInfo()); this->SendPacket(std::move(p)); @@ -356,7 +356,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err { Debug(net, 9, "client[{}] SendError(): error={}", this->client_id, error); - auto p = std::make_unique(PACKET_SERVER_ERROR); + auto p = std::make_unique(this, PACKET_SERVER_ERROR); p->Send_uint8(error); if (!reason.empty()) p->Send_string(reason); @@ -401,7 +401,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() { Debug(net, 9, "client[{}] SendNewGRFCheck()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU); + auto p = std::make_unique(this, PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU); const GRFConfig *c; uint grf_count = 0; @@ -436,7 +436,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword() /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; - auto p = std::make_unique(PACKET_SERVER_NEED_GAME_PASSWORD); + auto p = std::make_unique(this, PACKET_SERVER_NEED_GAME_PASSWORD); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -459,7 +459,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword() /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; - auto p = std::make_unique(PACKET_SERVER_NEED_COMPANY_PASSWORD); + auto p = std::make_unique(this, PACKET_SERVER_NEED_COMPANY_PASSWORD); p->Send_uint32(_settings_game.game_creation.generation_seed); p->Send_string(_settings_client.network.network_id); this->SendPacket(std::move(p)); @@ -481,7 +481,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() _network_game_info.clients_on++; - auto p = std::make_unique(PACKET_SERVER_WELCOME); + auto p = std::make_unique(this, PACKET_SERVER_WELCOME); p->Send_uint32(this->client_id); p->Send_uint32(_settings_game.game_creation.generation_seed); p->Send_string(_settings_client.network.network_id); @@ -510,7 +510,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++; } - auto p = std::make_unique(PACKET_SERVER_WAIT); + auto p = std::make_unique(this, PACKET_SERVER_WAIT); p->Send_uint8(waiting); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; @@ -560,7 +560,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() this->savegame = std::make_shared(this); /* Now send the _frame_counter and how many packets are coming */ - auto p = std::make_unique(PACKET_SERVER_MAP_BEGIN); + auto p = std::make_unique(this, PACKET_SERVER_MAP_BEGIN); p->Send_uint32(_frame_counter); this->SendPacket(std::move(p)); @@ -603,7 +603,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id) { Debug(net, 9, "client[{}] SendJoin(): client_id={}", this->client_id, client_id); - auto p = std::make_unique(PACKET_SERVER_JOIN); + auto p = std::make_unique(this, PACKET_SERVER_JOIN); p->Send_uint32(client_id); @@ -614,7 +614,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id) /** Tell the client that they may run to a particular frame. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame() { - auto p = std::make_unique(PACKET_SERVER_FRAME); + auto p = std::make_unique(this, PACKET_SERVER_FRAME); p->Send_uint32(_frame_counter); p->Send_uint32(_frame_counter_max); #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME @@ -639,7 +639,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync() { Debug(net, 9, "client[{}] SendSync(), frame_counter={}, sync_seed_1={}", this->client_id, _frame_counter, _sync_seed_1); - auto p = std::make_unique(PACKET_SERVER_SYNC); + auto p = std::make_unique(this, PACKET_SERVER_SYNC); p->Send_uint32(_frame_counter); p->Send_uint32(_sync_seed_1); @@ -658,7 +658,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacke { Debug(net, 9, "client[{}] SendCommand(): cmd={}", this->client_id, cp.cmd); - auto p = std::make_unique(PACKET_SERVER_COMMAND); + auto p = std::make_unique(this, PACKET_SERVER_COMMAND); this->NetworkGameSocketHandler::SendCommand(*p, cp); p->Send_uint32(cp.frame); @@ -682,7 +682,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY; - auto p = std::make_unique(PACKET_SERVER_CHAT); + auto p = std::make_unique(this, PACKET_SERVER_CHAT); p->Send_uint8 (action); p->Send_uint32(client_id); @@ -707,7 +707,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendExternalChat(const std::st if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY; - auto p = std::make_unique(PACKET_SERVER_EXTERNAL_CHAT); + auto p = std::make_unique(this, PACKET_SERVER_EXTERNAL_CHAT); p->Send_string(source); p->Send_uint16(colour); @@ -727,7 +727,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_ { Debug(net, 9, "client[{}] SendErrorQuit(): client_id={}, errorno={}", this->client_id, client_id, errorno); - auto p = std::make_unique(PACKET_SERVER_ERROR_QUIT); + auto p = std::make_unique(this, PACKET_SERVER_ERROR_QUIT); p->Send_uint32(client_id); p->Send_uint8 (errorno); @@ -744,7 +744,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id) { Debug(net, 9, "client[{}] SendQuit(): client_id={}", this->client_id, client_id); - auto p = std::make_unique(PACKET_SERVER_QUIT); + auto p = std::make_unique(this, PACKET_SERVER_QUIT); p->Send_uint32(client_id); @@ -757,7 +757,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown() { Debug(net, 9, "client[{}] SendShutdown()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_SHUTDOWN); + auto p = std::make_unique(this, PACKET_SERVER_SHUTDOWN); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -767,7 +767,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame() { Debug(net, 9, "client[{}] SendNewGame()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_NEWGAME); + auto p = std::make_unique(this, PACKET_SERVER_NEWGAME); this->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } @@ -781,7 +781,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16_t colour { Debug(net, 9, "client[{}] SendRConResult()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_RCON); + auto p = std::make_unique(this, PACKET_SERVER_RCON); p->Send_uint16(colour); p->Send_string(command); @@ -798,7 +798,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, C { Debug(net, 9, "client[{}] SendMove(): client_id={}", this->client_id, client_id); - auto p = std::make_unique(PACKET_SERVER_MOVE); + auto p = std::make_unique(this, PACKET_SERVER_MOVE); p->Send_uint32(client_id); p->Send_uint8(company_id); @@ -811,7 +811,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate() { Debug(net, 9, "client[{}] SendCompanyUpdate()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_COMPANY_UPDATE); + auto p = std::make_unique(this, PACKET_SERVER_COMPANY_UPDATE); static_assert(sizeof(_network_company_passworded) <= sizeof(uint16_t)); p->Send_uint16(_network_company_passworded); @@ -824,7 +824,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate() { Debug(net, 9, "client[{}] SendConfigUpdate()", this->client_id); - auto p = std::make_unique(PACKET_SERVER_CONFIG_UPDATE); + auto p = std::make_unique(this, PACKET_SERVER_CONFIG_UPDATE); p->Send_uint8(_settings_client.network.max_companies); p->Send_string(_settings_client.network.server_name); diff --git a/src/network/network_stun.cpp b/src/network/network_stun.cpp index c606ff0c83..2acd438e56 100644 --- a/src/network/network_stun.cpp +++ b/src/network/network_stun.cpp @@ -92,7 +92,7 @@ std::unique_ptr ClientNetworkStunSocketHandler:: stun_handler->Connect(token, family); - auto p = std::make_unique(PACKET_STUN_SERCLI_STUN); + auto p = std::make_unique(stun_handler.get(), PACKET_STUN_SERCLI_STUN); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(token); p->Send_uint8(family); diff --git a/src/network/network_turn.cpp b/src/network/network_turn.cpp index c3dfa75a0b..6626ae057d 100644 --- a/src/network/network_turn.cpp +++ b/src/network/network_turn.cpp @@ -100,7 +100,7 @@ void ClientNetworkTurnSocketHandler::Connect() { auto turn_handler = std::make_unique(token, tracking_number, connection_string); - auto p = std::make_unique(PACKET_TURN_SERCLI_CONNECT); + auto p = std::make_unique(turn_handler.get(), PACKET_TURN_SERCLI_CONNECT); p->Send_uint8(NETWORK_COORDINATOR_VERSION); p->Send_string(ticket); diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 478e804eaf..88aaea538e 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -75,7 +75,7 @@ public: void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet &, NetworkAddress &client_addr) { - Packet packet(PACKET_UDP_SERVER_RESPONSE); + Packet packet(this, PACKET_UDP_SERVER_RESPONSE); this->SendPacket(packet, client_addr); Debug(net, 7, "Queried from {}", client_addr.GetHostname()); @@ -104,7 +104,7 @@ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket) for (NetworkAddress &addr : _broadcast_list) { Debug(net, 5, "Broadcasting to {}", addr.GetHostname()); - Packet p(PACKET_UDP_CLIENT_FIND_SERVER); + Packet p(socket, PACKET_UDP_CLIENT_FIND_SERVER); socket->SendPacket(p, addr, true, true); } } From 26d1d5d6e7d521bf3b77ad709ef8423643a6fb6d Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 13 Mar 2024 20:32:50 +0100 Subject: [PATCH 04/15] Codechange: move decision whether to check NewGRFs to SendNewGRFCheck, just like for sending game/company passwords --- src/network/network_server.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index a1fbf09302..943e3829cc 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -401,6 +401,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() { Debug(net, 9, "client[{}] SendNewGRFCheck()", this->client_id); + /* Invalid packet when status is STATUS_NEWGRFS_CHECK or higher */ + if (this->status >= STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + + Debug(net, 9, "client[{}] status = NEWGRFS_CHECK", this->client_id); + this->status = STATUS_NEWGRFS_CHECK; + + if (_grfconfig == nullptr) { + /* There are no NewGRFs, continue with the game password. */ + return this->SendNeedGamePassword(); + } + auto p = std::make_unique(this, PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU); const GRFConfig *c; uint grf_count = 0; @@ -922,14 +933,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p) /* Make sure companies to which people try to join are not autocleaned */ if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0; - Debug(net, 9, "client[{}] status = NEWGRFS_CHECK", this->client_id); - this->status = STATUS_NEWGRFS_CHECK; - - if (_grfconfig == nullptr) { - /* Continue asking for the game password. */ - return this->SendNeedGamePassword(); - } - return this->SendNewGRFCheck(); } From b6c75dec3a3b9526f4ccdfb6a8609a6f411aa52d Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 13 Mar 2024 21:15:25 +0100 Subject: [PATCH 05/15] Codechange: explicitly allow only one state in initial handshake/authorization --- src/network/network_server.cpp | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 943e3829cc..65cb5388ae 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -401,8 +401,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() { Debug(net, 9, "client[{}] SendNewGRFCheck()", this->client_id); - /* Invalid packet when status is STATUS_NEWGRFS_CHECK or higher */ - if (this->status >= STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_INACTIVE. */ + if (this->status != STATUS_INACTIVE) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); Debug(net, 9, "client[{}] status = NEWGRFS_CHECK", this->client_id); this->status = STATUS_NEWGRFS_CHECK; @@ -432,18 +432,19 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() /** Request the game password. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword() { - if (_settings_client.network.server_password.empty()) { - /* Do not actually need a game password, continue with the company password. */ - return this->SendNeedCompanyPassword(); - } - Debug(net, 9, "client[{}] SendNeedGamePassword()", this->client_id); - /* Invalid packet when status is STATUS_AUTH_GAME or higher */ - if (this->status >= STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_NEWGRFS_CHECK. */ + if (this->status != STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); Debug(net, 9, "client[{}] status = AUTH_GAME", this->client_id); this->status = STATUS_AUTH_GAME; + + if (_settings_client.network.server_password.empty()) { + /* Do not actually need a game password, continue with the company password. */ + return this->SendNeedCompanyPassword(); + } + /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; @@ -455,18 +456,19 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword() /** Request the company password. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword() { - NetworkClientInfo *ci = this->GetInfo(); - if (!Company::IsValidID(ci->client_playas) || _network_company_states[ci->client_playas].password.empty()) { - return this->SendWelcome(); - } - Debug(net, 9, "client[{}] SendNeedCompanyPassword()", this->client_id); - /* Invalid packet when status is STATUS_AUTH_COMPANY or higher */ - if (this->status >= STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_AUTH_GAME. */ + if (this->status != STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); Debug(net, 9, "client[{}] status = AUTH_COMPANY", this->client_id); this->status = STATUS_AUTH_COMPANY; + + NetworkClientInfo *ci = this->GetInfo(); + if (!Company::IsValidID(ci->client_playas) || _network_company_states[ci->client_playas].password.empty()) { + return this->SendWelcome(); + } + /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; @@ -482,11 +484,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() { Debug(net, 9, "client[{}] SendWelcome()", this->client_id); - /* Invalid packet when status is AUTH or higher */ - if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_AUTH_COMPANY. */ + if (this->status != STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); Debug(net, 9, "client[{}] status = AUTHORIZED", this->client_id); this->status = STATUS_AUTHORIZED; + /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; From 15d02f51ed61dd7ef26ea0fa84ab9c47424ecc2c Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sun, 28 Jan 2024 13:28:07 +0100 Subject: [PATCH 06/15] Codechange: use span to send bytes to Packet and add span recv function --- src/network/core/packet.cpp | 31 +++++++++++++++++++++++-------- src/network/core/packet.h | 3 ++- src/network/network_server.cpp | 9 ++++----- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index f314dc803c..5339c43677 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -176,16 +176,15 @@ void Packet::Send_buffer(const std::vector &data) /** * Send as many of the bytes as possible in the packet. This can mean * that it is possible that not all bytes are sent. To cope with this - * the function returns the amount of bytes that were actually sent. - * @param begin The begin of the buffer to send. - * @param end The end of the buffer to send. - * @return The number of bytes that were added to this packet. + * the function returns the span of bytes that were not sent. + * @param span The span describing the range of bytes to send. + * @return The span of bytes that were not written. */ -size_t Packet::Send_bytes(const byte *begin, const byte *end) +std::span Packet::Send_bytes(const std::span span) { - size_t amount = std::min(end - begin, this->limit - this->Size()); - this->buffer.insert(this->buffer.end(), begin, begin + amount); - return amount; + size_t amount = std::min(span.size(), this->limit - this->Size()); + this->buffer.insert(this->buffer.end(), span.data(), span.data() + amount); + return span.subspan(amount); } /* @@ -370,6 +369,22 @@ std::vector Packet::Recv_buffer() return data; } +/** + * Extract at most the length of the span bytes from the packet into the span. + * @param span The span to write the bytes to. + * @return The number of bytes that were actually read. + */ +size_t Packet::Recv_bytes(std::span span) +{ + auto tranfer_to_span = [](std::span destination, const char *source, size_t amount) { + size_t to_copy = std::min(amount, destination.size()); + std::copy(source, source + to_copy, destination.data()); + return to_copy; + }; + + return this->TransferOut(tranfer_to_span, span); +} + /** * Reads characters (bytes) from the packet until it finds a '\0', or reaches a * maximum of \c length characters. diff --git a/src/network/core/packet.h b/src/network/core/packet.h index f403f37ae7..ccb56738ff 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -66,7 +66,7 @@ public: void Send_uint64(uint64_t data); void Send_string(const std::string_view data); void Send_buffer(const std::vector &data); - size_t Send_bytes (const byte *begin, const byte *end); + std::span Send_bytes(const std::span span); /* Reading/receiving of packets */ bool HasPacketSizeData() const; @@ -82,6 +82,7 @@ public: uint32_t Recv_uint32(); uint64_t Recv_uint64(); std::vector Recv_buffer(); + size_t Recv_bytes(std::span span); std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); size_t RemainingBytesToTransfer() const; diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 65cb5388ae..2e6c51920e 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -145,14 +145,13 @@ struct PacketWriter : SaveFilter { if (this->current == nullptr) this->current = std::make_unique(this->cs, PACKET_SERVER_MAP_DATA, TCP_MTU); - byte *bufe = buf + size; - while (buf != bufe) { - size_t written = this->current->Send_bytes(buf, bufe); - buf += written; + std::span to_write(buf, size); + while (!to_write.empty()) { + to_write = this->current->Send_bytes(to_write); if (!this->current->CanWriteToPacket(1)) { this->packets.push_back(std::move(this->current)); - if (buf != bufe) this->current = std::make_unique(this->cs, PACKET_SERVER_MAP_DATA, TCP_MTU); + if (!to_write.empty()) this->current = std::make_unique(this->cs, PACKET_SERVER_MAP_DATA, TCP_MTU); } } From fe12d38024038f90b8e81259d457288f8046bc5f Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 13 Mar 2024 21:33:28 +0100 Subject: [PATCH 07/15] Codechange: split initiating of joining and identification of the client --- src/network/core/tcp_game.cpp | 2 ++ src/network/core/tcp_game.h | 24 +++++++++++++++++++----- src/network/network_client.cpp | 13 +++++++++++-- src/network/network_client.h | 1 + src/network/network_server.cpp | 23 ++++++++++++++++++++--- src/network/network_server.h | 2 ++ 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index 4bd32ec153..f1b4b05e2a 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -81,6 +81,7 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet &p) case PACKET_CLIENT_GAME_INFO: return this->Receive_CLIENT_GAME_INFO(p); case PACKET_SERVER_GAME_INFO: return this->Receive_SERVER_GAME_INFO(p); case PACKET_SERVER_CLIENT_INFO: return this->Receive_SERVER_CLIENT_INFO(p); + case PACKET_CLIENT_IDENTIFY: return this->Receive_CLIENT_IDENTIFY(p); case PACKET_SERVER_NEED_GAME_PASSWORD: return this->Receive_SERVER_NEED_GAME_PASSWORD(p); case PACKET_SERVER_NEED_COMPANY_PASSWORD: return this->Receive_SERVER_NEED_COMPANY_PASSWORD(p); case PACKET_CLIENT_GAME_PASSWORD: return this->Receive_CLIENT_GAME_PASSWORD(p); @@ -162,6 +163,7 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_ERROR(Packet &) { ret NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GAME_INFO(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GAME_INFO); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_GAME_INFO); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CLIENT_INFO); } +NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_IDENTIFY); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_NEED_GAME_PASSWORD); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_NEED_COMPANY_PASSWORD); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GAME_PASSWORD); } diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index ce031aa07b..7aed964d51 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -56,7 +56,10 @@ enum PacketGameType : uint8_t { * the map and other important data. */ - /* After the join step, the first is checking NewGRFs. */ + /* After the initial join, the next step is identification. */ + PACKET_CLIENT_IDENTIFY, ///< Client telling the server the client's name and requested company. + + /* After the identify step, the next is checking NewGRFs. */ PACKET_SERVER_CHECK_NEWGRFS, ///< Server sends NewGRF IDs and MD5 checksums for the client to check. PACKET_CLIENT_NEWGRFS_CHECKED, ///< Client acknowledges that it has all required NewGRFs. @@ -162,10 +165,13 @@ protected: /** * Try to join the server: - * string OpenTTD revision (norev000 if no revision). - * string Name of the client (max NETWORK_NAME_LENGTH). - * uint8_t ID of the company to play as (1..MAX_COMPANIES). - * uint8_t ID of the clients Language. + * string OpenTTD revision (norev000 if no revision). + * uint32_t NewGRF version (added in 1.2). + * string Name of the client (max NETWORK_NAME_LENGTH) (removed in 15). + * uint8_t ID of the company to play as (1..MAX_COMPANIES) (removed in 15). + * uint8_t ID of the clients Language (removed in 15). + * string Client's unique identifier (removed in 1.0). + * * @param p The packet that was just received. */ virtual NetworkRecvStatus Receive_CLIENT_JOIN(Packet &p); @@ -199,6 +205,14 @@ protected: */ virtual NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet &p); + /** + * The client tells the server about the identity of the client: + * string Name of the client (max NETWORK_NAME_LENGTH). + * uint8_t ID of the company to play as (1..MAX_COMPANIES). + * @param p The packet that was just received. + */ + virtual NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p); + /** * Indication to the client that the server needs a game password. * @param p The packet that was just received. diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index ded54f0bae..db56f0b209 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -347,9 +347,18 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin() auto p = std::make_unique(my_client, PACKET_CLIENT_JOIN); p->Send_string(GetNetworkRevisionString()); p->Send_uint32(_openttd_newgrf_version); + my_client->SendPacket(std::move(p)); + + return ClientNetworkGameSocketHandler::SendIdentify(); +} + +NetworkRecvStatus ClientNetworkGameSocketHandler::SendIdentify() +{ + Debug(net, 9, "Client::SendIdentify()"); + + auto p = std::make_unique(my_client, PACKET_CLIENT_IDENTIFY); p->Send_string(_settings_client.network.client_name); // Client name - p->Send_uint8 (_network_join.company); // PlayAs - p->Send_uint8 (0); // Used to be language + p->Send_uint8(_network_join.company); // PlayAs my_client->SendPacket(std::move(p)); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/network_client.h b/src/network/network_client.h index d314ddc41a..72da871700 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -71,6 +71,7 @@ protected: static NetworkRecvStatus SendNewGRFsOk(); static NetworkRecvStatus SendGetMap(); static NetworkRecvStatus SendMapOk(); + static NetworkRecvStatus SendIdentify(); void CheckConnection(); public: ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 2e6c51920e..72567c2ef9 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -400,8 +400,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() { Debug(net, 9, "client[{}] SendNewGRFCheck()", this->client_id); - /* Invalid packet when status is anything but STATUS_INACTIVE. */ - if (this->status != STATUS_INACTIVE) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_IDENTIFY. */ + if (this->status != STATUS_IDENTIFY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); Debug(net, 9, "client[{}] status = NEWGRFS_CHECK", this->client_id); this->status = STATUS_NEWGRFS_CHECK; @@ -891,6 +891,21 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p) return this->SendError(NETWORK_ERROR_WRONG_REVISION); } + Debug(net, 9, "client[{}] status = IDENTIFY", this->client_id); + this->status = STATUS_IDENTIFY; + + /* Reset 'lag' counters */ + this->last_frame = this->last_frame_server = _frame_counter; + + return NETWORK_RECV_STATUS_OKAY; +} + +NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet &p) +{ + if (this->status != STATUS_IDENTIFY) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); + + Debug(net, 9, "client[{}] Receive_CLIENT_IDENTIFY()", this->client_id); + std::string client_name = p.Recv_string(NETWORK_CLIENT_NAME_LENGTH); CompanyID playas = (Owner)p.Recv_uint8(); @@ -905,7 +920,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p) break; case COMPANY_SPECTATOR: // Spectator break; - default: // Join another company (companies 1-8 (index 0-7)) + default: // Join another company (companies 1..MAX_COMPANIES (index 0..(MAX_COMPANIES-1))) if (!Company::IsValidHumanID(playas)) { return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH); } @@ -1770,6 +1785,7 @@ void NetworkServer_Tick(bool send_frame) break; case NetworkClientSocket::STATUS_INACTIVE: + case NetworkClientSocket::STATUS_IDENTIFY: case NetworkClientSocket::STATUS_NEWGRFS_CHECK: case NetworkClientSocket::STATUS_AUTHORIZED: /* NewGRF check and authorized states should be handled almost instantly. @@ -1962,6 +1978,7 @@ void NetworkServerShowStatusToConsole() { static const char * const stat_str[] = { "inactive", + "identifing client", "checking NewGRFs", "authorizing (server password)", "authorizing (company password)", diff --git a/src/network/network_server.h b/src/network/network_server.h index bbf9817248..f67aeeb404 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -24,6 +24,7 @@ extern NetworkClientSocketPool _networkclientsocket_pool; class ServerNetworkGameSocketHandler : public NetworkClientSocketPool::PoolItem<&_networkclientsocket_pool>, public NetworkGameSocketHandler, public TCPListenHandler { protected: NetworkRecvStatus Receive_CLIENT_JOIN(Packet &p) override; + NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p) override; NetworkRecvStatus Receive_CLIENT_GAME_INFO(Packet &p) override; NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet &p) override; NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet &p) override; @@ -50,6 +51,7 @@ public: /** Status of a client */ enum ClientStatus { STATUS_INACTIVE, ///< The client is not connected nor active. + STATUS_IDENTIFY, ///< The client is identifying itself. STATUS_NEWGRFS_CHECK, ///< The client is checking NewGRFs. STATUS_AUTH_GAME, ///< The client is authorizing with game (server) password. STATUS_AUTH_COMPANY, ///< The client is authorizing with company password. From 4c0dca14113a78187adcc240fd02247fd27b653a Mon Sep 17 00:00:00 2001 From: merni-ns <66267867+merni-ns@users.noreply.github.com> Date: Sat, 16 Mar 2024 19:41:23 +0530 Subject: [PATCH 08/15] Codechange: [CI] Move Release CI build to MacOS runner (#12309) --- .github/workflows/ci-build.yml | 18 ++++++++++-------- .github/workflows/ci-macos.yml | 5 +++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 0cedad4c61..c823b92dfa 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -25,15 +25,10 @@ jobs: fail-fast: false matrix: include: - - name: Clang - Debug + - name: Clang compiler: clang-15 cxxcompiler: clang++-15 libraries: libsdl2-dev - - name: Clang - Release - compiler: clang-15 - cxxcompiler: clang++-15 - libraries: libsdl2-dev - extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF - name: GCC - SDL2 compiler: gcc cxxcompiler: g++ @@ -61,10 +56,16 @@ jobs: fail-fast: false matrix: include: - - arch: arm64 + - name: arm64 - Debug + arch: arm64 full_arch: arm64 + extra-cmake-parameters: -DCMAKE_BUILD=Debug + - name: arm64 - Release + arch: arm64 + full_arch: arm64 + extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF - name: Mac OS (${{ matrix.arch }}) + name: Mac OS (${{ matrix.name }}) uses: ./.github/workflows/ci-macos.yml secrets: inherit @@ -72,6 +73,7 @@ jobs: with: arch: ${{ matrix.arch }} full_arch: ${{ matrix.full_arch }} + extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }} windows: strategy: diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml index f4f30a606b..e6f5d623de 100644 --- a/.github/workflows/ci-macos.yml +++ b/.github/workflows/ci-macos.yml @@ -9,6 +9,10 @@ on: full_arch: required: true type: string + extra-cmake-parameters: + required: false + type: string + default: "" env: CTEST_OUTPUT_ON_FAILURE: 1 @@ -66,6 +70,7 @@ jobs: -DCMAKE_OSX_ARCHITECTURES=${{ inputs.full_arch }} \ -DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-osx \ -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + ${{ inputs.extra-cmake-parameters }} \ # EOF echo "::endgroup::" From 5f4f9334ce8aa0d1021b604be08628015b973bef Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 16 Mar 2024 15:39:57 +0100 Subject: [PATCH 09/15] Codefix f1e999ec: use RandomRange(l) instead of _random.Next(l) (#12274) --- src/pathfinder/yapf/yapf_ship.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index fa617d3e1f..709d4f2919 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -180,7 +180,7 @@ public: TrackdirBits dirs = follower.m_new_td_bits; const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir); if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree; - const int strip_amount = _random.Next(CountBits(dirs)); + const int strip_amount = RandomRange(CountBits(dirs)); for (int s = 0; s < strip_amount; ++s) RemoveFirstTrackdir(&dirs); return { follower.m_new_tile, FindFirstTrackdir(dirs) }; } From 7f49b6f25abf4cf1ac82f28b8801a2c72c4e6ba9 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 16 Mar 2024 16:49:03 +0100 Subject: [PATCH 10/15] Codefix: allow preview label on PRs against release branches too (#12310) --- .github/workflows/preview.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 97ab31955b..bfbe13cacc 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -7,6 +7,7 @@ on: - synchronize branches: - master + - release/** concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} From d7c5e9e8ab7fc877c619bb819a584c653a73d4b7 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Fri, 1 Mar 2024 13:32:13 +0000 Subject: [PATCH 11/15] Codechange: Where the ship comes from is already known This simplifies the handling of variables. `ChooseShipTrack` is called upon entering `tile`, and looking further back to the caller, it can be deduced that `v->tile` matches `src_tile`. With that said, `enterdir` can also be removed, as it's not used anywhere else. `CreateRandomPath` and `GetRandomFollowUpTrackdir` is being fed `src_tile` as it's 2nd parameter. This could be eliminated, as `v` is also being passed to it. Just use `v->tile` in those functions. --- src/pathfinder/yapf/yapf.h | 3 +-- src/pathfinder/yapf/yapf_ship.cpp | 20 +++++++++----------- src/ship_cmd.cpp | 9 +++------ 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h index ca7b4f02c9..186986ce57 100644 --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.h @@ -21,11 +21,10 @@ * Finds the best path for given ship using YAPF. * @param v the ship that needs to find a path * @param tile the tile to find the path from (should be next tile the ship is about to enter) - * @param enterdir diagonal direction which the ship will enter this new tile from * @param path_found [out] Whether a path has been found (true) or has been guessed (false) * @return the best trackdir for next turn or INVALID_TRACK if the path could not be found */ -Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, bool &path_found, ShipPathCache &path_cache); +Track YapfShipChooseTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache); /** * Returns true if it is better to reverse the ship before leaving depot using YAPF. diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index 709d4f2919..a4638879c5 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -188,9 +188,9 @@ public: } /** Creates a random path, avoids 90 degree turns. */ - static Trackdir CreateRandomPath(const Ship *v, TileIndex tile, Trackdir dir, ShipPathCache &path_cache, int path_length) + static Trackdir CreateRandomPath(const Ship *v, Trackdir dir, ShipPathCache &path_cache, int path_length) { - std::pair tile_dir = { tile, dir }; + std::pair tile_dir = { v->tile, dir }; for (int i = 0; i < path_length; ++i) { tile_dir = GetRandomFollowUpTileTrackdir(v, tile_dir.first, tile_dir.second); if (tile_dir.second == INVALID_TRACKDIR) break; @@ -204,10 +204,8 @@ public: return result; } - static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, bool &path_found, ShipPathCache &path_cache) + static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache) { - /* Move back to the old tile/trackdir (where ship is coming from). */ - const TileIndex src_tile = TileAddByDiagDir(tile, ReverseDiagDir(enterdir)); const Trackdir trackdir = v->GetVehicleTrackdir(); assert(IsValidTrackdir(trackdir)); @@ -218,7 +216,7 @@ public: if (high_level_path.empty()) { path_found = false; /* Make the ship move around aimlessly. This prevents repeated pathfinder calls and clearly indicates that the ship is lost. */ - return CreateRandomPath(v, src_tile, trackdir, path_cache, SHIP_LOST_PATH_LENGTH); + return CreateRandomPath(v, trackdir, path_cache, SHIP_LOST_PATH_LENGTH); } /* Try one time without restricting the search area, which generally results in better and more natural looking paths. @@ -228,7 +226,7 @@ public: Tpf pf(MAX_SHIP_PF_NODES); /* Set origin and destination nodes */ - pf.SetOrigin(src_tile, trackdirs); + pf.SetOrigin(v->tile, trackdirs); pf.SetDestination(v); const bool is_intermediate_destination = static_cast(high_level_path.size()) >= NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1; if (is_intermediate_destination) pf.SetIntermediateDestination(high_level_path.back()); @@ -241,7 +239,7 @@ public: path_found = pf.FindPath(v); Node *node = pf.GetBestNode(); if (attempt == 0 && !path_found) continue; // Try again with restricted search area. - if (!path_found || node == nullptr) return GetRandomFollowUpTileTrackdir(v, src_tile, trackdir).second; + if (!path_found || node == nullptr) return GetRandomFollowUpTileTrackdir(v, v->tile, trackdir).second; /* Return only the path within the current water region if an intermediate destination was returned. If not, cache the entire path * to the final destination tile. The low-level pathfinder might actually prefer a different docking tile in a nearby region. Without @@ -267,7 +265,7 @@ public: /* A empty path means we are already at the destination. The pathfinder shouldn't have been called at all. * Return a random reachable trackdir to hopefully nudge the ship out of this strange situation. */ - if (path_cache.empty()) return GetRandomFollowUpTileTrackdir(v, src_tile, trackdir).second; + if (path_cache.empty()) return GetRandomFollowUpTileTrackdir(v, v->tile, trackdir).second; /* Take out the last trackdir as the result. */ const Trackdir result = path_cache.front(); @@ -437,9 +435,9 @@ struct CYapfShip : CYapfTpath); break; + case VPF_YAPF: track = YapfShipChooseTrack(v, tile, path_found, v->path); break; default: NOT_REACHED(); } } @@ -821,7 +818,7 @@ static void ShipController(Ship *v) } /* Choose a direction, and continue if we find one */ - const Track track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks); + const Track track = ChooseShipTrack(v, gp.new_tile, tracks); if (track == INVALID_TRACK) return ReverseShip(v); const ShipSubcoordData &b = _ship_subcoord[diagdir][track]; From 818a57c9afb3ada0a3c4c6cdc0e9b11436603efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Sat, 16 Mar 2024 17:41:58 +0100 Subject: [PATCH 12/15] Codechange: Actually use LIT_NONE (#12314) --- src/table/settings/gui_settings.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 2abb58464f..23bd899334 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -336,9 +336,9 @@ cat = SC_BASIC var = gui.liveries type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 +def = LIT_ALL +min = LIT_NONE +max = LIT_ALL str = STR_CONFIG_SETTING_LIVERIES strhelp = STR_CONFIG_SETTING_LIVERIES_HELPTEXT strval = STR_CONFIG_SETTING_LIVERIES_NONE From 0058ebe47264dfadc400137776a9342ccb61c0f0 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 16 Mar 2024 19:37:32 +0000 Subject: [PATCH 13/15] Codechange: Check cheap station-facility-filter before expensive in-use-filter. (#12317) --- src/station_gui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 6926fa15f5..bc081bd685 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -260,8 +260,8 @@ protected: this->stations_per_cargo_type_no_rating = 0; for (const Station *st : Station::Iterate()) { - if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { - if (this->filter.facilities & st->facilities) { // only stations with selected facilities + if ((this->filter.facilities & st->facilities) != 0) { // only stations with selected facilities + if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { bool has_rating = false; /* Add to the station/cargo counts. */ for (CargoID j = 0; j < NUM_CARGO; j++) { From af1bd43b3048f925e1c82ce11c050920ab9b06c5 Mon Sep 17 00:00:00 2001 From: merni-ns <66267867+merni-ns@users.noreply.github.com> Date: Sun, 17 Mar 2024 01:18:12 +0530 Subject: [PATCH 14/15] Codefix 4c0dca1: [CI] Fix typo in workflow file (#12318) --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c823b92dfa..bc833cbc7c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -59,7 +59,7 @@ jobs: - name: arm64 - Debug arch: arm64 full_arch: arm64 - extra-cmake-parameters: -DCMAKE_BUILD=Debug + extra-cmake-parameters: -DCMAKE_BUILD_TYPE=Debug - name: arm64 - Release arch: arm64 full_arch: arm64 From bd7120bae41b6e7ac86c664c8220b59cd57242bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Sat, 16 Mar 2024 23:43:20 +0100 Subject: [PATCH 15/15] Fix #12316, 268e512: Support for enum storage type in GenerateWidget.cmake (#12321) --- cmake/scripts/GenerateWidget.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/scripts/GenerateWidget.cmake b/cmake/scripts/GenerateWidget.cmake index b6748422f5..ffa5e6edea 100644 --- a/cmake/scripts/GenerateWidget.cmake +++ b/cmake/scripts/GenerateWidget.cmake @@ -56,11 +56,14 @@ foreach(ENUM IN LISTS ENUM_LINES) endif() # Check for enum match - if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN} *\{") + if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN}( *: *[^ ]*)? *\{") # REGEX REPLACE does a REGEX MATCHALL and fails if an empty string is matched string(REGEX MATCH "[^ ]*" RESULT "${LINE}") string(REPLACE "${RESULT}" "" RM_INDENT "${LINE}") + string(REGEX MATCH " *: *[^ ]*" RESULT "${LINE}") + string(REPLACE "${RESULT}" "" LINE "${LINE}") + set(ACTIVE 1) if(ACTIVE_COMMENT GREATER 0) string(APPEND ${PLACE_HOLDER} "\n${COMMENT}")