diff --git a/Server/Components/Vehicles/vehicle.cpp b/Server/Components/Vehicles/vehicle.cpp index f07118a93..4ac9c5316 100644 --- a/Server/Components/Vehicles/vehicle.cpp +++ b/Server/Components/Vehicles/vehicle.cpp @@ -91,7 +91,7 @@ void Vehicle::streamInForPlayer(IPlayer& player) // Attempt to attach trailer to cab if both vehicles are streamed in. // We are streaming in the trailer. Check if cab is streamed. - if (!towing && cab && cab->isStreamedInForPlayer(player)) + if (cab && cab->isStreamedInForPlayer(player)) { NetCode::RPC::AttachTrailer trailerRPC; trailerRPC.TrailerID = poolID; @@ -100,7 +100,7 @@ void Vehicle::streamInForPlayer(IPlayer& player) } // We are streaming in the cab. Check if trailer is streamed. - if (towing && trailer && trailer->isStreamedInForPlayer(player)) + if (trailer && trailer->isStreamedInForPlayer(player)) { NetCode::RPC::AttachTrailer trailerRPC; trailerRPC.TrailerID = trailer->poolID; @@ -216,16 +216,36 @@ bool Vehicle::updateFromDriverSync(const VehicleDriverSyncPacket& vehicleSync, I updateOccupied(); } - // Reset the detaching flag when trailer is detached on driver's client. - if (vehicleSync.TrailerID == 0) + if (vehicleSync.TrailerID) { + if (trailer) + { + if (trailer->getID() != vehicleSync.TrailerID) + { + // The client instantly jumped from one trailer to another one. Probably a cheat, so don't + // allow it. + return false; + } + } + else + { + // Got a new one that we didn't know about. + trailer = static_cast(pool->get(vehicleSync.TrailerID)); + if (trailer) + { + trailer->cab = this; + } + } + } + else + { + // Reset the detaching flag when trailer is detached on driver's client. detaching = false; // Client is reporting no trailer (probably lost it) but server thinks there's still one. Detaching it server side. if (trailer && Time::now() - trailer->trailerUpdateTime > Seconds(0)) { trailer->cab = nullptr; - towing = false; trailer = nullptr; } } @@ -264,7 +284,7 @@ bool Vehicle::updateFromUnoccupied(const VehicleUnoccupiedSyncPacket& unoccupied return handler->onUnoccupiedVehicleUpdate(*this, player, data); }); - if (cab && !towing) + if (cab) { cab->detachTrailer(); cab = nullptr; @@ -312,16 +332,13 @@ bool Vehicle::updateFromTrailerSync(const VehicleTrailerSyncPacket& trailerSync, { if (cab && cab->trailer == this) { - cab->towing = false; cab->trailer = nullptr; } // Don't call attach RPC here. Client will attach it because trailerId is sent in driver sync. // https://github.com/openmultiplayer/server-beta/issues/181 vehicle->trailer = this; - vehicle->towing = true; cab = vehicle; - towing = false; trailerUpdateTime = Time::now(); } @@ -681,7 +698,6 @@ void Vehicle::_respawn() driver = nullptr; trailer = nullptr; cab = nullptr; - towing = false; detaching = false; params = VehicleParams {}; } @@ -711,7 +727,6 @@ void Vehicle::attachTrailer(IVehicle& trailer) return; } this->trailer = static_cast(&trailer); - towing = true; this->trailer->setCab(this); this->trailer->trailerUpdateTime = Time::now(); NetCode::RPC::AttachTrailer trailerRPC; @@ -722,14 +737,13 @@ void Vehicle::attachTrailer(IVehicle& trailer) void Vehicle::detachTrailer() { - if (trailer && towing) + if (trailer) { NetCode::RPC::DetachTrailer trailerRPC; trailerRPC.VehicleID = poolID; PacketHelper::broadcastToSome(trailerRPC, streamedFor_.entries()); trailer->setCab(nullptr); trailer = nullptr; - towing = false; detaching = true; } } @@ -764,13 +778,14 @@ void Vehicle::setAngularVelocity(Vector3 velocity) Vehicle::~Vehicle() { - if (cab) + if (trailer) { - cab->detachTrailer(); + detachTrailer(); } - else if (trailer && towing) + if (cab) { - detachTrailer(); + cab->detachTrailer(); + cab = nullptr; } } diff --git a/Server/Components/Vehicles/vehicle.hpp b/Server/Components/Vehicles/vehicle.hpp index 427156cec..a1d776904 100644 --- a/Server/Components/Vehicles/vehicle.hpp +++ b/Server/Components/Vehicles/vehicle.hpp @@ -47,7 +47,6 @@ class Vehicle final : public IVehicle, public PoolIDProvider, public NoCopy int32_t bodyColour2 = -1; uint8_t landingGear = 1; bool respawning = false; - bool towing = false; bool detaching = false; FlatHashSet passengers; HybridString<16> numberPlate = StringView("XYZSR998"); @@ -60,11 +59,8 @@ class Vehicle final : public IVehicle, public PoolIDProvider, public NoCopy Vector3 velocity = Vector3(0.0f, 0.0f, 0.0f); Vector3 angularVelocity = Vector3(0.0f, 0.0f, 0.0f); TimePoint trailerUpdateTime; - union - { - Vehicle* trailer = nullptr; - Vehicle* cab; - }; + Vehicle* trailer = nullptr; + Vehicle* cab = nullptr; StaticArray carriages; VehicleParams params; uint8_t sirenState = 0; @@ -82,7 +78,6 @@ class Vehicle final : public IVehicle, public PoolIDProvider, public NoCopy void setCab(Vehicle* cab) { this->cab = cab; - towing = false; } /// Set vehicle to respawn without emitting onRespawn event @@ -357,25 +352,17 @@ class Vehicle final : public IVehicle, public PoolIDProvider, public NoCopy void detachTrailer() override; /// Checks if the current vehicle is a trailer. - bool isTrailer() const override { return !towing && cab != nullptr; } + bool isTrailer() const override { return cab != nullptr; } /// Get the current vehicle's attached trailer. IVehicle* getTrailer() const override { - if (!towing) - { - return nullptr; - } return trailer; } /// Get the current vehicle's cab. IVehicle* getCab() const override { - if (towing) - { - return nullptr; - } return cab; }