diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 4010f7a6ad..b807a8e7a5 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -721,7 +721,7 @@ const char* NetworkBase::FormatChat(NetworkPlayer* fromplayer, const char* text) return formatted; } -void NetworkBase::SendPacketToClients(NetworkPacket& packet, bool front, bool gameCmd) +void NetworkBase::SendPacketToClients(const NetworkPacket& packet, bool front, bool gameCmd) { for (auto& client_connection : client_connection_list) { @@ -742,7 +742,8 @@ void NetworkBase::SendPacketToClients(NetworkPacket& packet, bool front, bool ga continue; } } - client_connection->QueuePacket(NetworkPacket::Duplicate(packet), front); + auto packetCopy = packet; + client_connection->QueuePacket(std::move(packetCopy), front); } } @@ -1207,16 +1208,17 @@ void NetworkBase::Client_Send_RequestGameState(uint32_t tick) } log_verbose("Requesting gamestate from server for tick %u", tick); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::RequestGameState) << tick; + + NetworkPacket packet; + packet << static_cast(NetworkCommand::RequestGameState) << tick; _serverConnection->QueuePacket(std::move(packet)); } void NetworkBase::Client_Send_TOKEN() { log_verbose("requesting token"); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Token); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Token); _serverConnection->AuthStatus = NETWORK_AUTH_REQUESTED; _serverConnection->QueuePacket(std::move(packet)); } @@ -1224,15 +1226,15 @@ void NetworkBase::Client_Send_TOKEN() void NetworkBase::Client_Send_AUTH( const std::string& name, const std::string& password, const std::string& pubkey, const std::vector& signature) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Auth); - packet->WriteString(network_get_version().c_str()); - packet->WriteString(name.c_str()); - packet->WriteString(password.c_str()); - packet->WriteString(pubkey.c_str()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Auth); + packet.WriteString(network_get_version().c_str()); + packet.WriteString(name.c_str()); + packet.WriteString(password.c_str()); + packet.WriteString(pubkey.c_str()); assert(signature.size() <= static_cast(UINT32_MAX)); - *packet << static_cast(signature.size()); - packet->Write(signature.data(), signature.size()); + packet << static_cast(signature.size()); + packet.Write(signature.data(), signature.size()); _serverConnection->AuthStatus = NETWORK_AUTH_REQUESTED; _serverConnection->QueuePacket(std::move(packet)); } @@ -1240,21 +1242,21 @@ void NetworkBase::Client_Send_AUTH( void NetworkBase::Client_Send_MAPREQUEST(const std::vector& objects) { log_verbose("client requests %u objects", uint32_t(objects.size())); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::MapRequest) << static_cast(objects.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::MapRequest) << static_cast(objects.size()); for (const auto& object : objects) { log_verbose("client requests object %s", object.c_str()); - packet->Write(reinterpret_cast(object.c_str()), 8); + packet.Write(reinterpret_cast(object.c_str()), 8); } _serverConnection->QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_TOKEN(NetworkConnection& connection) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Token) << static_cast(connection.Challenge.size()); - packet->Write(connection.Challenge.data(), connection.Challenge.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Token) << static_cast(connection.Challenge.size()); + packet.Write(connection.Challenge.data(), connection.Challenge.size()); connection.QueuePacket(std::move(packet)); } @@ -1265,9 +1267,9 @@ void NetworkBase::Server_Send_OBJECTS_LIST( if (objects.empty()) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::ObjectsList) << static_cast(0) - << static_cast(objects.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::ObjectsList) << static_cast(0) + << static_cast(objects.size()); connection.QueuePacket(std::move(packet)); } @@ -1277,13 +1279,13 @@ void NetworkBase::Server_Send_OBJECTS_LIST( { const auto* object = objects[i]; - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::ObjectsList) << static_cast(i) - << static_cast(objects.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::ObjectsList) << static_cast(i) + << static_cast(objects.size()); log_verbose("Object %.8s (checksum %x)", object->ObjectEntry.name, object->ObjectEntry.checksum); - packet->Write(reinterpret_cast(object->ObjectEntry.name), 8); - *packet << object->ObjectEntry.checksum << object->ObjectEntry.flags; + packet.Write(reinterpret_cast(object->ObjectEntry.name), 8); + packet << object->ObjectEntry.checksum << object->ObjectEntry.flags; connection.QueuePacket(std::move(packet)); } @@ -1292,8 +1294,8 @@ void NetworkBase::Server_Send_OBJECTS_LIST( void NetworkBase::Server_Send_SCRIPTS(NetworkConnection& connection) const { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Scripts); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Scripts); # ifdef ENABLE_SCRIPTING using namespace OpenRCT2::Scripting; @@ -1310,18 +1312,18 @@ void NetworkBase::Server_Send_SCRIPTS(NetworkConnection& connection) const } log_verbose("Server sends %u scripts", pluginsToSend.size()); - *packet << static_cast(pluginsToSend.size()); + packet << static_cast(pluginsToSend.size()); for (const auto& plugin : pluginsToSend) { const auto& metadata = plugin->GetMetadata(); log_verbose("Script %s", metadata.Name.c_str()); const auto& code = plugin->GetCode(); - *packet << static_cast(code.size()); - packet->Write(reinterpret_cast(code.c_str()), code.size()); + packet << static_cast(code.size()); + packet.Write(reinterpret_cast(code.c_str()), code.size()); } # else - *packet << static_cast(0); + packet << static_cast(0); # endif connection.QueuePacket(std::move(packet)); } @@ -1330,8 +1332,8 @@ void NetworkBase::Client_Send_HEARTBEAT(NetworkConnection& connection) const { log_verbose("Sending heartbeat"); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Heartbeat); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Heartbeat); connection.QueuePacket(std::move(packet)); } @@ -1364,11 +1366,11 @@ void NetworkBase::Server_Send_AUTH(NetworkConnection& connection) { new_playerid = connection.Player->Id; } - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Auth) << static_cast(connection.AuthStatus) << new_playerid; + NetworkPacket packet; + packet << static_cast(NetworkCommand::Auth) << static_cast(connection.AuthStatus) << new_playerid; if (connection.AuthStatus == NETWORK_AUTH_BADVERSION) { - packet->WriteString(network_get_version().c_str()); + packet.WriteString(network_get_version().c_str()); } connection.QueuePacket(std::move(packet)); if (connection.AuthStatus != NETWORK_AUTH_OK && connection.AuthStatus != NETWORK_AUTH_REQUIREPASSWORD) @@ -1408,16 +1410,16 @@ void NetworkBase::Server_Send_MAP(NetworkConnection* connection) for (size_t i = 0; i < out_size; i += chunksize) { size_t datasize = std::min(chunksize, out_size - i); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Map) << static_cast(out_size) << static_cast(i); - packet->Write(&header[i], datasize); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Map) << static_cast(out_size) << static_cast(i); + packet.Write(&header[i], datasize); if (connection) { connection->QueuePacket(std::move(packet)); } else { - SendPacketToClients(*packet); + SendPacketToClients(packet); } } free(header); @@ -1478,22 +1480,22 @@ uint8_t* NetworkBase::save_for_network(size_t& out_size, const std::vector packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Chat); - packet->WriteString(text); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Chat); + packet.WriteString(text); _serverConnection->QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_CHAT(const char* text, const std::vector& playerIds) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Chat); - packet->WriteString(text); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Chat); + packet.WriteString(text); if (playerIds.empty()) { // Empty players / default value means send to all players - SendPacketToClients(*packet); + SendPacketToClients(packet); } else { @@ -1502,7 +1504,7 @@ void NetworkBase::Server_Send_CHAT(const char* text, const std::vector& auto conn = GetPlayerConnection(playerId); if (conn != nullptr && !conn->IsDisconnected) { - conn->QueuePacket(NetworkPacket::Duplicate(*packet)); + conn->QueuePacket(packet); } } } @@ -1510,7 +1512,7 @@ void NetworkBase::Server_Send_CHAT(const char* text, const std::vector& void NetworkBase::Client_Send_GAME_ACTION(const GameAction* action) { - std::unique_ptr packet(NetworkPacket::Allocate()); + NetworkPacket packet; uint32_t networkId = 0; networkId = ++_actionId; @@ -1525,26 +1527,26 @@ void NetworkBase::Client_Send_GAME_ACTION(const GameAction* action) DataSerialiser stream(true); action->Serialise(stream); - *packet << static_cast(NetworkCommand::GameAction) << gCurrentTicks << action->GetType() << stream; + packet << static_cast(NetworkCommand::GameAction) << gCurrentTicks << action->GetType() << stream; _serverConnection->QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_GAME_ACTION(const GameAction* action) { - std::unique_ptr packet(NetworkPacket::Allocate()); + NetworkPacket packet; DataSerialiser stream(true); action->Serialise(stream); - *packet << static_cast(NetworkCommand::GameAction) << gCurrentTicks << action->GetType() << stream; + packet << static_cast(NetworkCommand::GameAction) << gCurrentTicks << action->GetType() << stream; - SendPacketToClients(*packet); + SendPacketToClients(packet); } void NetworkBase::Server_Send_TICK() { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Tick) << gCurrentTicks << scenario_rand_state().s0; + NetworkPacket packet; + packet << static_cast(NetworkCommand::Tick) << gCurrentTicks << scenario_rand_state().s0; uint32_t flags = 0; // Simple counter which limits how often a sprite checksum gets sent. // This can get somewhat expensive, so we don't want to push it every tick in release, @@ -1558,75 +1560,75 @@ void NetworkBase::Server_Send_TICK() } // Send flags always, so we can understand packet structure on the other end, // and allow for some expansion. - *packet << flags; + packet << flags; if (flags & NETWORK_TICK_FLAG_CHECKSUMS) { rct_sprite_checksum checksum = sprite_checksum(); - packet->WriteString(checksum.ToString().c_str()); + packet.WriteString(checksum.ToString().c_str()); } - SendPacketToClients(*packet); + SendPacketToClients(packet); } void NetworkBase::Server_Send_PLAYERINFO(int32_t playerId) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::PlayerInfo) << gCurrentTicks; + NetworkPacket packet; + packet << static_cast(NetworkCommand::PlayerInfo) << gCurrentTicks; auto* player = GetPlayerByID(playerId); if (player == nullptr) return; - player->Write(*packet); - SendPacketToClients(*packet); + player->Write(packet); + SendPacketToClients(packet); } void NetworkBase::Server_Send_PLAYERLIST() { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::PlayerList) << gCurrentTicks << static_cast(player_list.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::PlayerList) << gCurrentTicks << static_cast(player_list.size()); for (auto& player : player_list) { - player->Write(*packet); + player->Write(packet); } - SendPacketToClients(*packet); + SendPacketToClients(packet); } void NetworkBase::Client_Send_PING() { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Ping); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Ping); _serverConnection->QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_PING() { last_ping_sent_time = platform_get_ticks(); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Ping); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Ping); for (auto& client_connection : client_connection_list) { client_connection->PingTime = platform_get_ticks(); } - SendPacketToClients(*packet, true); + SendPacketToClients(packet, true); } void NetworkBase::Server_Send_PINGLIST() { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::PingList) << static_cast(player_list.size()); + NetworkPacket packet; + packet << static_cast(NetworkCommand::PingList) << static_cast(player_list.size()); for (auto& player : player_list) { - *packet << player->Id << player->Ping; + packet << player->Id << player->Ping; } - SendPacketToClients(*packet); + SendPacketToClients(packet); } void NetworkBase::Server_Send_SETDISCONNECTMSG(NetworkConnection& connection, const char* msg) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::DisconnectMessage); - packet->WriteString(msg); + NetworkPacket packet; + packet << static_cast(NetworkCommand::DisconnectMessage); + packet.WriteString(msg); connection.QueuePacket(std::move(packet)); } @@ -1646,8 +1648,8 @@ json_t* NetworkBase::GetServerInfoAsJson() const void NetworkBase::Server_Send_GAMEINFO(NetworkConnection& connection) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::GameInfo); + NetworkPacket packet; + packet << static_cast(NetworkCommand::GameInfo); # ifndef DISABLE_HTTP json_t* obj = GetServerInfoAsJson(); @@ -1658,8 +1660,8 @@ void NetworkBase::Server_Send_GAMEINFO(NetworkConnection& connection) json_object_set_new(jsonProvider, "website", json_string(gConfigNetwork.provider_website.c_str())); json_object_set_new(obj, "provider", jsonProvider); - packet->WriteString(json_dumps(obj, 0)); - *packet << _serverState.gamestateSnapshotsEnabled; + packet.WriteString(json_dumps(obj, 0)); + packet << _serverState.gamestateSnapshotsEnabled; json_decref(obj); # endif @@ -1668,39 +1670,39 @@ void NetworkBase::Server_Send_GAMEINFO(NetworkConnection& connection) void NetworkBase::Server_Send_SHOWERROR(NetworkConnection& connection, rct_string_id title, rct_string_id message) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::ShowError) << title << message; + NetworkPacket packet; + packet << static_cast(NetworkCommand::ShowError) << title << message; connection.QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_GROUPLIST(NetworkConnection& connection) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::GroupList) << static_cast(group_list.size()) << default_group; + NetworkPacket packet; + packet << static_cast(NetworkCommand::GroupList) << static_cast(group_list.size()) << default_group; for (auto& group : group_list) { - group->Write(*packet); + group->Write(packet); } connection.QueuePacket(std::move(packet)); } void NetworkBase::Server_Send_EVENT_PLAYER_JOINED(const char* playerName) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Event); - *packet << static_cast(SERVER_EVENT_PLAYER_JOINED); - packet->WriteString(playerName); - SendPacketToClients(*packet); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Event); + packet << static_cast(SERVER_EVENT_PLAYER_JOINED); + packet.WriteString(playerName); + SendPacketToClients(packet); } void NetworkBase::Server_Send_EVENT_PLAYER_DISCONNECTED(const char* playerName, const char* reason) { - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::Event); - *packet << static_cast(SERVER_EVENT_PLAYER_DISCONNECTED); - packet->WriteString(playerName); - packet->WriteString(reason); - SendPacketToClients(*packet); + NetworkPacket packet; + packet << static_cast(NetworkCommand::Event); + packet << static_cast(SERVER_EVENT_PLAYER_DISCONNECTED); + packet.WriteString(playerName); + packet.WriteString(reason); + SendPacketToClients(packet); } bool NetworkBase::ProcessConnection(NetworkConnection& connection) @@ -2240,11 +2242,11 @@ void NetworkBase::Server_Handle_REQUEST_GAMESTATE(NetworkConnection& connection, dataSize = snapshotMemory.GetLength() - bytesSent; } - std::unique_ptr gameStateChunk(NetworkPacket::Allocate()); - *gameStateChunk << static_cast(NetworkCommand::GameState) << tick << length << bytesSent << dataSize; - gameStateChunk->Write(static_cast(snapshotMemory.GetData()) + bytesSent, dataSize); + NetworkPacket packetGameStateChunk; + packetGameStateChunk << static_cast(NetworkCommand::GameState) << tick << length << bytesSent << dataSize; + packetGameStateChunk.Write(static_cast(snapshotMemory.GetData()) + bytesSent, dataSize); - connection.QueuePacket(std::move(gameStateChunk)); + connection.QueuePacket(std::move(packetGameStateChunk)); bytesSent += dataSize; } @@ -3208,8 +3210,8 @@ void NetworkBase::Client_Handle_EVENT([[maybe_unused]] NetworkConnection& connec void NetworkBase::Client_Send_GAMEINFO() { log_verbose("requesting gameinfo"); - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << static_cast(NetworkCommand::GameInfo); + NetworkPacket packet; + packet << static_cast(NetworkCommand::GameInfo); _serverConnection->QueuePacket(std::move(packet)); } diff --git a/src/openrct2/network/NetworkBase.h b/src/openrct2/network/NetworkBase.h index ad8eed136e..0f2f1fd0b5 100644 --- a/src/openrct2/network/NetworkBase.h +++ b/src/openrct2/network/NetworkBase.h @@ -113,7 +113,7 @@ public: // Client void ProcessPlayerInfo(); void ProcessDisconnectedClients(); static const char* FormatChat(NetworkPlayer* fromplayer, const char* text); - void SendPacketToClients(NetworkPacket& packet, bool front = false, bool gameCmd = false); + void SendPacketToClients(const NetworkPacket& packet, bool front = false, bool gameCmd = false); bool CheckSRAND(uint32_t tick, uint32_t srand0); bool CheckDesynchronizaton(); void RequestStateSnapshot(); diff --git a/src/openrct2/network/NetworkConnection.h b/src/openrct2/network/NetworkConnection.h index 0dcd379e73..bdfb8697cd 100644 --- a/src/openrct2/network/NetworkConnection.h +++ b/src/openrct2/network/NetworkConnection.h @@ -16,7 +16,7 @@ # include "NetworkTypes.h" # include "Socket.h" -# include +# include # include # include @@ -41,7 +41,13 @@ public: ~NetworkConnection(); int32_t ReadPacket(); - void QueuePacket(std::unique_ptr packet, bool front = false); + void QueuePacket(NetworkPacket&& packet, bool front = false); + void QueuePacket(const NetworkPacket& packet, bool front = false) + { + auto copy = packet; + return QueuePacket(std::move(copy)); + } + void SendQueuedPackets(); void ResetLastPacketTime(); bool ReceivedPacketRecently(); @@ -51,7 +57,7 @@ public: void SetLastDisconnectReason(const rct_string_id string_id, void* args = nullptr); private: - std::list> _outboundPackets; + std::deque _outboundPackets; uint32_t _lastPacketTime = 0; utf8* _lastDisconnectReason = nullptr;