From 1824ce17b27d8d66b5753a1bf92ad58c882f6dc4 Mon Sep 17 00:00:00 2001 From: Hual Date: Mon, 4 Dec 2023 15:44:58 +0200 Subject: [PATCH] Optimize batch packets & RPCs using RakNet list commands. --- SDK/include/network.hpp | 9 + SDK/include/player.hpp | 13 ++ Server/Components/Actors/actor.hpp | 12 +- Server/Components/Actors/actors_main.cpp | 2 +- .../LegacyNetwork/legacy_network_impl.hpp | 159 ++++++++++++++++++ Server/Components/Vehicles/vehicle.cpp | 26 +-- Server/Components/Vehicles/vehicles_impl.hpp | 22 +-- Server/Source/player.cpp | 10 ++ Server/Source/player_impl.hpp | 25 +-- Server/Source/player_pool.hpp | 20 ++- Shared/Network/packet.hpp | 19 +-- lib/RakNet | 2 +- 12 files changed, 254 insertions(+), 65 deletions(-) diff --git a/SDK/include/network.hpp b/SDK/include/network.hpp index 37eba30f0..76fb0828b 100644 --- a/SDK/include/network.hpp +++ b/SDK/include/network.hpp @@ -348,6 +348,15 @@ struct INetwork : public IExtensible /// Update server parameters virtual void update() = 0; + + /// Attempt to broadcast an RPC to a list of players on this network + /// @param id The RPC ID for the current network + /// @param data The data span with the length in BITS + /// @param exceptPeer send RPC to everyone except this peer + /// @param dispatchEvents dispatch RPC related events + virtual bool broadcastPacket(Span data, int channel, const FlatPtrHashSet& players, const IPlayer* exceptPeer = nullptr, bool dispatchEvents = true) = 0; + + virtual bool broadcastRPC(int id, Span data, int channel, const FlatPtrHashSet& players, const IPlayer* exceptPeer, bool dispatchEvents) = 0; }; /// A component interface which allows for writing a network component diff --git a/SDK/include/player.hpp b/SDK/include/player.hpp index dd039185d..12bd9e197 100644 --- a/SDK/include/player.hpp +++ b/SDK/include/player.hpp @@ -1068,6 +1068,19 @@ struct IPlayerPool : public IExtensible, public IReadOnlyPool /// @param dispatchEvents dispatch RPC related events virtual void broadcastRPC(int id, Span data, int channel, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) = 0; + /// Attempt to broadcast an packet derived from NetworkPacketBase to all peers + /// @param data The data span with the length in BITS + /// @param skipFrom send packet to everyone except this player + /// @param dispatchEvents dispatch packet related events + virtual void broadcastPacket(Span data, int channel, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) = 0; + + /// Attempt to broadcast an RPC derived from NetworkPacketBase to all peers + /// @param id The RPC ID for the current network + /// @param data The data span with the length in BITS + /// @param skipFrom send RPC to everyone except this peer + /// @param dispatchEvents dispatch RPC related events + virtual void broadcastRPC(int id, Span data, int channel, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) = 0; + /// Check if player name is valid. virtual bool isNameValid(StringView name) const = 0; diff --git a/Server/Components/Actors/actor.hpp b/Server/Components/Actors/actor.hpp index 78357c8a9..11de50bda 100644 --- a/Server/Components/Actors/actor.hpp +++ b/Server/Components/Actors/actor.hpp @@ -48,6 +48,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy bool* validateAnimations_; ICustomModelsComponent*& modelsComponent_; IFixesComponent* fixesComponent_; + IPlayerPool& players_; void restream() { @@ -103,7 +104,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy } } - Actor(int skin, Vector3 pos, float angle, bool* allAnimationLibraries, bool* validateAnimations, ICustomModelsComponent*& modelsComponent, IFixesComponent* fixesComponent) + Actor(int skin, Vector3 pos, float angle, bool* allAnimationLibraries, bool* validateAnimations, ICustomModelsComponent*& modelsComponent, IFixesComponent* fixesComponent, IPlayerPool& players) : virtualWorld_(0) , skin_(skin) , invulnerable_(true) @@ -116,6 +117,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy , validateAnimations_(validateAnimations) , modelsComponent_(modelsComponent) , fixesComponent_(fixesComponent) + , players_(players) { } @@ -125,7 +127,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy NetCode::RPC::SetActorHealthForPlayer RPC; RPC.ActorID = poolID; RPC.Health = health_; - PacketHelper::broadcastToSome(RPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(RPC, players_, streamedFor_.entries()); } float getHealth() const override @@ -196,7 +198,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy NetCode::RPC::ClearActorAnimationsForPlayer RPC; RPC.ActorID = poolID; - PacketHelper::broadcastToSome(RPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(RPC, players_, streamedFor_.entries()); } bool isStreamedInForPlayer(const IPlayer& player) const override @@ -264,7 +266,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy NetCode::RPC::SetActorPosForPlayer RPC; RPC.ActorID = poolID; RPC.Pos = position; - PacketHelper::broadcastToSome(RPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(RPC, players_, streamedFor_.entries()); } GTAQuat getRotation() const override @@ -279,7 +281,7 @@ class Actor final : public IActor, public PoolIDProvider, public NoCopy NetCode::RPC::SetActorFacingAngleForPlayer RPC; RPC.ActorID = poolID; RPC.Angle = angle_; - PacketHelper::broadcastToSome(RPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(RPC, players_, streamedFor_.entries()); } void setSkin(int id) override diff --git a/Server/Components/Actors/actors_main.cpp b/Server/Components/Actors/actors_main.cpp index 474d75f90..4036dce9e 100644 --- a/Server/Components/Actors/actors_main.cpp +++ b/Server/Components/Actors/actors_main.cpp @@ -145,7 +145,7 @@ class ActorsComponent final : public IActorsComponent, public PlayerConnectEvent IActor* create(int skin, Vector3 pos, float angle) override { - return storage.emplace(skin, pos, angle, core->getConfig().getBool("game.use_all_animations"), core->getConfig().getBool("game.validate_animations"), modelsComponent, fixesComponent_); + return storage.emplace(skin, pos, angle, core->getConfig().getBool("game.use_all_animations"), core->getConfig().getBool("game.validate_animations"), modelsComponent, fixesComponent_, core->getPlayers()); } void free() override diff --git a/Server/Components/LegacyNetwork/legacy_network_impl.hpp b/Server/Components/LegacyNetwork/legacy_network_impl.hpp index 0db5a0916..4afa71aac 100644 --- a/Server/Components/LegacyNetwork/legacy_network_impl.hpp +++ b/Server/Components/LegacyNetwork/legacy_network_impl.hpp @@ -137,6 +137,85 @@ class RakNetLegacyNetwork final : public Network, public CoreEventHandler, publi return rakNetServer.Send((const char*)bs.GetData(), bs.GetNumberOfUnreadBits(), RakNet::HIGH_PRIORITY, reliability, channel, RakNet::UNASSIGNED_PLAYER_ID, true); } + bool broadcastPacket(Span data, int channel, const FlatPtrHashSet& players, const IPlayer* exceptPeer, bool dispatchEvents) override + { + { + int playersSize = players.size(); + if (players.size() == 2) + { + IPlayer* first = *players.begin(); + IPlayer* second = *(players.begin()++); + if (first == exceptPeer || second == exceptPeer) + { + --playersSize; + } + } + if (playersSize == 1) + { + IPlayer* player = *players.begin(); + if (player == exceptPeer) + { + return false; + } + } + } + + // Don't use constructor because it takes bytes; we want bits + NetworkBitStream bs; + bs.SetData(data.data()); + bs.SetWriteOffset(data.size()); + bs.SetReadOffset(0); + + if (dispatchEvents) + { + uint8_t type; + if (bs.readUINT8(type)) + { + if (!outEventDispatcher.stopAtFalse([type, &bs](NetworkOutEventHandler* handler) + { + bs.SetReadOffset(8); // Ignore packet ID + return handler->onSendPacket(nullptr, type, bs); + })) + { + return false; + } + + if (!packetOutEventDispatcher.stopAtFalse(type, [&bs](SingleNetworkOutEventHandler* handler) + { + bs.SetReadOffset(8); // Ignore packet ID + return handler->onSend(nullptr, bs); + })) + { + return false; + } + } + } + + RakNet::PlayerID* playerIds = new RakNet::PlayerID[players.size()]; + int currentId = 0; + for (IPlayer* player : players) + { + if (player != exceptPeer) + { + const PeerNetworkData& netData = player->getNetworkData(); + if (netData.network == this) + { + const PeerNetworkData::NetworkID& nid = netData.networkID; + const RakNet::PlayerID rid { unsigned(nid.address.v4), nid.port }; + playerIds[currentId++] = rid; + } + } + } + + const RakNet::PacketReliability reliability = (channel == OrderingChannel_Reliable) ? RakNet::RELIABLE : ((channel == OrderingChannel_Unordered) ? RakNet::UNRELIABLE : RakNet::UNRELIABLE_SEQUENCED); + const bool res = rakNetServer.SendToList((const char*)bs.GetData(), bs.GetNumberOfBytesUsed(), RakNet::HIGH_PRIORITY, reliability, channel, playerIds, currentId); + if (!res) + { + delete[] playerIds; + } + return res; + } + bool sendPacket(IPlayer& peer, Span data, int channel, bool dispatchEvents) override { const PeerNetworkData& netData = peer.getNetworkData(); @@ -232,6 +311,86 @@ class RakNetLegacyNetwork final : public Network, public CoreEventHandler, publi return rakNetServer.RPC(id, (const char*)bs.GetData(), bs.GetNumberOfUnreadBits(), RakNet::HIGH_PRIORITY, reliability, channel, RakNet::UNASSIGNED_PLAYER_ID, true, false, RakNet::UNASSIGNED_NETWORK_ID, nullptr); } + bool broadcastRPC(int id, Span data, int channel, const FlatPtrHashSet& players, const IPlayer* exceptPeer, bool dispatchEvents) override + { + if (id == INVALID_PACKET_ID) + { + return false; + } + + { + int playersSize = players.size(); + if (players.size() == 2) + { + IPlayer* first = *players.begin(); + IPlayer* second = *(players.begin()++); + if (first == exceptPeer || second == exceptPeer) + { + --playersSize; + } + } + if (playersSize == 1) + { + IPlayer* player = *players.begin(); + if (player == exceptPeer) + { + return false; + } + } + } + + // Don't use constructor because it takes bytes; we want bits + NetworkBitStream bs; + bs.SetData(data.data()); + bs.SetWriteOffset(data.size()); + bs.SetReadOffset(0); + + if (dispatchEvents) + { + if (!outEventDispatcher.stopAtFalse([id, &bs](NetworkOutEventHandler* handler) + { + bs.resetReadPointer(); + return handler->onSendRPC(nullptr, id, bs); + })) + { + return false; + } + + if (!rpcOutEventDispatcher.stopAtFalse(id, [&bs](SingleNetworkOutEventHandler* handler) + { + bs.resetReadPointer(); + return handler->onSend(nullptr, bs); + })) + { + return false; + } + } + + RakNet::PlayerID* playerIds = new RakNet::PlayerID[players.size()]; + int currentId = 0; + for (IPlayer* player : players) + { + if (player != exceptPeer) + { + const PeerNetworkData& netData = player->getNetworkData(); + if (netData.network == this) + { + const PeerNetworkData::NetworkID& nid = netData.networkID; + const RakNet::PlayerID rid { unsigned(nid.address.v4), nid.port }; + playerIds[currentId++] = rid; + } + } + } + + const RakNet::PacketReliability reliability = (channel == OrderingChannel_Unordered) ? RakNet::RELIABLE : RakNet::RELIABLE_ORDERED; + const bool res = rakNetServer.RPC(id, (const char*)bs.GetData(), bs.GetNumberOfBitsUsed(), RakNet::HIGH_PRIORITY, reliability, channel, playerIds, currentId, false, RakNet::UNASSIGNED_NETWORK_ID); + if (!res) + { + delete[] playerIds; + } + return res; + } + bool sendRPC(IPlayer& peer, int id, Span data, int channel, bool dispatchEvents) override { if (id == INVALID_PACKET_ID) diff --git a/Server/Components/Vehicles/vehicle.cpp b/Server/Components/Vehicles/vehicle.cpp index b39c7f74d..ddf27354e 100644 --- a/Server/Components/Vehicles/vehicle.cpp +++ b/Server/Components/Vehicles/vehicle.cpp @@ -415,7 +415,7 @@ void Vehicle::setPlate(StringView plate) NetCode::RPC::SetVehiclePlate plateRPC; plateRPC.VehicleID = poolID; plateRPC.plate = numberPlate; - PacketHelper::broadcastToSome(plateRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(plateRPC, pool->getPlayers(), streamedFor_.entries()); } const StringView Vehicle::getPlate() @@ -434,7 +434,7 @@ void Vehicle::setColour(int col1, int col2) colourRPC.EventType = VehicleSCMEvent_SetColour; colourRPC.Arg1 = col1; colourRPC.Arg2 = col2; - PacketHelper::broadcastToSome(colourRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(colourRPC, pool->getPlayers(), streamedFor_.entries()); } Pair Vehicle::getColour() const @@ -462,7 +462,7 @@ void Vehicle::setDamageStatus(int PanelStatus, int DoorStatus, uint8_t LightStat static_cast&>(pool->getEventDispatcher()).dispatch(&VehicleEventHandler::onVehicleDamageStatusUpdate, *lock.entry, *vehicleUpdater); } - PacketHelper::broadcastToSome(damageStatus, streamedFor_.entries(), vehicleUpdater); + PacketHelper::broadcastToSome(damageStatus, pool->getPlayers(), streamedFor_.entries(), vehicleUpdater); } void Vehicle::getDamageStatus(int& PanelStatus, int& DoorStatus, int& LightStatus, int& TyreStatus) @@ -481,7 +481,7 @@ void Vehicle::setPaintJob(int paintjob) paintRPC.EventType = VehicleSCMEvent_SetPaintjob; paintRPC.VehicleID = poolID; paintRPC.Arg1 = paintjob; - PacketHelper::broadcastToSome(paintRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(paintRPC, pool->getPlayers(), streamedFor_.entries()); } int Vehicle::getPaintJob() @@ -510,7 +510,7 @@ void Vehicle::addComponent(int component) modRPC.EventType = VehicleSCMEvent_AddComponent; modRPC.VehicleID = poolID; modRPC.Arg1 = component; - PacketHelper::broadcastToSome(modRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(modRPC, pool->getPlayers(), streamedFor_.entries()); } int Vehicle::getComponentInSlot(int slot) @@ -538,7 +538,7 @@ void Vehicle::removeComponent(int component) NetCode::RPC::RemoveVehicleComponent modRPC; modRPC.VehicleID = poolID; modRPC.Component = component; - PacketHelper::broadcastToSome(modRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(modRPC, pool->getPlayers(), streamedFor_.entries()); } void Vehicle::putPlayer(IPlayer& player, int SeatID) @@ -588,7 +588,7 @@ void Vehicle::setHealth(float Health) NetCode::RPC::SetVehicleHealth setVehicleHealthRPC; setVehicleHealthRPC.VehicleID = poolID; setVehicleHealthRPC.health = Health; - PacketHelper::broadcastToSome(setVehicleHealthRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(setVehicleHealthRPC, pool->getPlayers(), streamedFor_.entries()); } void Vehicle::setInterior(int InteriorID) @@ -597,7 +597,7 @@ void Vehicle::setInterior(int InteriorID) NetCode::RPC::LinkVehicleToInterior linkVehicleToInteriorRPC; linkVehicleToInteriorRPC.VehicleID = poolID; linkVehicleToInteriorRPC.InteriorID = InteriorID; - PacketHelper::broadcastToSome(linkVehicleToInteriorRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(linkVehicleToInteriorRPC, pool->getPlayers(), streamedFor_.entries()); } int Vehicle::getInterior() @@ -612,7 +612,7 @@ void Vehicle::setZAngle(float angle) NetCode::RPC::SetVehicleZAngle setVehicleZAngleRPC; setVehicleZAngleRPC.VehicleID = poolID; setVehicleZAngleRPC.angle = angle; - PacketHelper::broadcastToSome(setVehicleZAngleRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(setVehicleZAngleRPC, pool->getPlayers(), streamedFor_.entries()); } float Vehicle::getZAngle() @@ -627,7 +627,7 @@ void Vehicle::setParams(const VehicleParams& params) NetCode::RPC::SetVehicleParams vehicleRPC; vehicleRPC.VehicleID = poolID; vehicleRPC.params = params; - PacketHelper::broadcastToSome(vehicleRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(vehicleRPC, pool->getPlayers(), streamedFor_.entries()); } // Set the vehicle's parameters for a specific player. @@ -655,7 +655,7 @@ void Vehicle::setPosition(Vector3 position) NetCode::RPC::SetVehiclePosition setVehiclePosition; setVehiclePosition.VehicleID = poolID; setVehiclePosition.position = position; - PacketHelper::broadcastToSome(setVehiclePosition, streamedFor_.entries()); + PacketHelper::broadcastToSome(setVehiclePosition, pool->getPlayers(), streamedFor_.entries()); } Vector3 Vehicle::getPosition() const @@ -741,7 +741,7 @@ void Vehicle::attachTrailer(IVehicle& trailer) NetCode::RPC::AttachTrailer trailerRPC; trailerRPC.TrailerID = this->trailer->poolID; trailerRPC.VehicleID = poolID; - PacketHelper::broadcastToSome(trailerRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(trailerRPC, pool->getPlayers(), streamedFor_.entries()); } void Vehicle::detachTrailer() @@ -750,7 +750,7 @@ void Vehicle::detachTrailer() { NetCode::RPC::DetachTrailer trailerRPC; trailerRPC.VehicleID = poolID; - PacketHelper::broadcastToSome(trailerRPC, streamedFor_.entries()); + PacketHelper::broadcastToSome(trailerRPC, pool->getPlayers(), streamedFor_.entries()); trailer->setCab(nullptr); trailer = nullptr; detaching = true; diff --git a/Server/Components/Vehicles/vehicles_impl.hpp b/Server/Components/Vehicles/vehicles_impl.hpp index 492e3378d..e020c44aa 100644 --- a/Server/Components/Vehicles/vehicles_impl.hpp +++ b/Server/Components/Vehicles/vehicles_impl.hpp @@ -20,6 +20,7 @@ class VehiclesComponent final : public IVehiclesComponent, public CoreEventHandl { private: ICore* core = nullptr; + IPlayerPool* players = nullptr; MarkedPoolStorage storage; DefaultEventDispatcher eventDispatcher; StaticArray preloadModels; @@ -246,7 +247,7 @@ class VehiclesComponent final : public IVehiclesComponent, public CoreEventHandl enterExitRPC.EventType = VehicleSCMEvent_EnterExitModShop; enterExitRPC.Arg1 = scmEvent.Arg1; enterExitRPC.Arg2 = scmEvent.Arg2; - PacketHelper::broadcastToSome(enterExitRPC, vehicle.streamedForPlayers(), &peer); + PacketHelper::broadcastToSome(enterExitRPC, self.core->getPlayers(), vehicle.streamedForPlayers(), &peer); break; } } @@ -294,7 +295,7 @@ class VehiclesComponent final : public IVehiclesComponent, public CoreEventHandl public: IPlayerPool& getPlayers() { - return core->getPlayers(); + return *players; } IEventDispatcher& getEventDispatcher() override @@ -331,10 +332,10 @@ class VehiclesComponent final : public IVehiclesComponent, public CoreEventHandl { if (core) { - core->getPlayers().getPlayerUpdateDispatcher().removeEventHandler(this); - core->getPlayers().getPlayerConnectDispatcher().removeEventHandler(this); - core->getPlayers().getPlayerChangeDispatcher().removeEventHandler(this); - core->getPlayers().getPoolEventDispatcher().removeEventHandler(this); + getPlayers().getPlayerUpdateDispatcher().removeEventHandler(this); + getPlayers().getPlayerConnectDispatcher().removeEventHandler(this); + getPlayers().getPlayerChangeDispatcher().removeEventHandler(this); + getPlayers().getPoolEventDispatcher().removeEventHandler(this); NetCode::RPC::OnPlayerEnterVehicle::removeEventHandler(*core, &playerEnterVehicleHandler); NetCode::RPC::OnPlayerExitVehicle::removeEventHandler(*core, &playerExitVehicleHandler); NetCode::RPC::SetVehicleDamageStatus::removeEventHandler(*core, &vehicleDamageStatusHandler); @@ -346,11 +347,12 @@ class VehiclesComponent final : public IVehiclesComponent, public CoreEventHandl void onLoad(ICore* core) override { this->core = core; + this->players = &core->getPlayers(); core->getEventDispatcher().addEventHandler(this); - core->getPlayers().getPlayerUpdateDispatcher().addEventHandler(this); - core->getPlayers().getPlayerConnectDispatcher().addEventHandler(this); - core->getPlayers().getPlayerChangeDispatcher().addEventHandler(this); - core->getPlayers().getPoolEventDispatcher().addEventHandler(this); + getPlayers().getPlayerUpdateDispatcher().addEventHandler(this); + getPlayers().getPlayerConnectDispatcher().addEventHandler(this); + getPlayers().getPlayerChangeDispatcher().addEventHandler(this); + getPlayers().getPoolEventDispatcher().addEventHandler(this); NetCode::RPC::OnPlayerEnterVehicle::addEventHandler(*core, &playerEnterVehicleHandler); NetCode::RPC::OnPlayerExitVehicle::addEventHandler(*core, &playerExitVehicleHandler); NetCode::RPC::SetVehicleDamageStatus::addEventHandler(*core, &vehicleDamageStatusHandler); diff --git a/Server/Source/player.cpp b/Server/Source/player.cpp index 76eaeeb81..dda44a5bc 100644 --- a/Server/Source/player.cpp +++ b/Server/Source/player.cpp @@ -374,3 +374,13 @@ void Player::ban(StringView reason) pool_.core.getConfig().writeBans(); kick(); } + +void Player::broadcastRPCToStreamed(int id, Span data, int channel, bool skipFrom) const +{ + pool_.broadcastRPC(id, data, channel, streamedForPlayers(), skipFrom ? this : nullptr); +} + +void Player::broadcastPacketToStreamed(Span data, int channel, bool skipFrom) const +{ + pool_.broadcastPacket(data, channel, streamedForPlayers(), skipFrom ? this : nullptr); +} diff --git a/Server/Source/player_impl.hpp b/Server/Source/player_impl.hpp index 211d4bca7..21e7585e3 100644 --- a/Server/Source/player_impl.hpp +++ b/Server/Source/player_impl.hpp @@ -386,32 +386,11 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy /// Attempt to broadcast an RPC derived from NetworkPacketBase to the player's streamed peers /// @param packet The packet to send - void broadcastRPCToStreamed(int id, Span data, int channel, bool skipFrom = false) const override - { - for (IPlayer* player : streamedForPlayers()) - { - if (skipFrom && player == this) - { - continue; - } - player->sendRPC(id, data, channel); - } - } + void broadcastRPCToStreamed(int id, Span data, int channel, bool skipFrom = false) const override; /// Attempt to broadcast a packet derived from NetworkPacketBase to the player's streamed peers /// @param packet The packet to send - void broadcastPacketToStreamed(Span data, int channel, bool skipFrom = true) const override - { - for (IPlayer* p : streamedFor_.entries()) - { - Player* player = static_cast(p); - if (skipFrom && player == this) - { - continue; - } - player->sendPacket(data, channel); - } - } + void broadcastPacketToStreamed(Span data, int channel, bool skipFrom = true) const override; inline bool shouldSendSyncPacket(Player* other) const { diff --git a/Server/Source/player_pool.hpp b/Server/Source/player_pool.hpp index 7f5b32445..cecf0db63 100644 --- a/Server/Source/player_pool.hpp +++ b/Server/Source/player_pool.hpp @@ -1649,6 +1649,22 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public } } + void broadcastRPC(int id, Span data, int channel, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) override + { + for (INetwork* network : networks) + { + network->broadcastRPC(id, data, channel, players, skipFrom, dispatchEvents); + } + } + + void broadcastPacket(Span data, int channel, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) override + { + for (INetwork* network : networks) + { + network->broadcastPacket(data, channel, players, skipFrom, dispatchEvents); + } + } + void broadcastRPC(int id, Span data, int channel, const IPlayer* skipFrom = nullptr, bool dispatchEvents = true) override { for (INetwork* network : networks) @@ -1708,7 +1724,7 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public playerJoinPacket.Col = player.colour_; playerJoinPacket.IsNPC = player.isBot_; playerJoinPacket.Name = StringView(player.name_); - PacketHelper::broadcastToSome(playerJoinPacket, storage.entries(), &peer); + PacketHelper::broadcastToSome(playerJoinPacket, *this, storage.entries(), &peer); for (IPlayer* other : storage.entries()) { @@ -2187,7 +2203,7 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public IVehicle* vehicle = vehiclesComponent->get(player->unoccupiedSync_.VehicleID); if (vehicle) { - PacketHelper::broadcastToSome(player->unoccupiedSync_, vehicle->streamedForPlayers(), player); + PacketHelper::broadcastToSome(player->unoccupiedSync_, *this, vehicle->streamedForPlayers(), player); } } } diff --git a/Shared/Network/packet.hpp b/Shared/Network/packet.hpp index ef601ee03..eeffc7afe 100644 --- a/Shared/Network/packet.hpp +++ b/Shared/Network/packet.hpp @@ -67,19 +67,18 @@ struct PacketHelper { /// @param players The list of peers to send the packet to /// @param skipFrom The player to skip in the list of peers template ::value>> - static void broadcastToSome(const Packet& packet, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr) + static void broadcastToSome(const Packet& packet, IPlayerPool& pool, const FlatPtrHashSet& players, const IPlayer* skipFrom = nullptr) { NetworkBitStream bs; packet.write(bs); - for (IPlayer* peer : players) { - if (peer != skipFrom) { - if constexpr (Packet::PacketType == NetworkPacketType::RPC) { - peer->sendRPC(Packet::PacketID, Span(bs.GetData(), bs.GetNumberOfBitsUsed()), Packet::PacketChannel); - } else if constexpr (Packet::PacketType == NetworkPacketType::Packet) { - peer->sendPacket(Span(bs.GetData(), bs.GetNumberOfBitsUsed()), Packet::PacketChannel); - } - } - } + if constexpr (Packet::PacketType == NetworkPacketType::RPC) + { + pool.broadcastRPC(Packet::PacketID, Span(bs.GetData(), bs.GetNumberOfBitsUsed()), Packet::PacketChannel, players, skipFrom); + } + else if constexpr (Packet::PacketType == NetworkPacketType::Packet) + { + pool.broadcastPacket(Span(bs.GetData(), bs.GetNumberOfBitsUsed()), Packet::PacketChannel, players, skipFrom); + } } /// Attempt to send a packet derived from NetworkPacketBase to the players that a player is streamed for diff --git a/lib/RakNet b/lib/RakNet index 2d8588b62..ed87dc8c4 160000 --- a/lib/RakNet +++ b/lib/RakNet @@ -1 +1 @@ -Subproject commit 2d8588b62b9b9b4a1dc772d6c7275dc9053bbdbe +Subproject commit ed87dc8c4f18ae9ef25127090167ef1be6e8f9db