From b1d43f837a2c1a75c70f72e46abf2be584886d85 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 23 Feb 2013 19:24:59 +0100 Subject: Core/Vehicles: Fixed crash in RemovePendingEventsForSeat - changed _pendingJoinEvents container from deque to list as deque invalidates all iterators pointing to the container (including .end()) when performing erase --- src/server/game/Entities/Vehicle/Vehicle.cpp | 42 ++++++---------------------- src/server/game/Entities/Vehicle/Vehicle.h | 14 ++++------ 2 files changed, 14 insertions(+), 42 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 951b55d9160..4f41e74f4d7 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -436,10 +436,6 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) // exits the vehicle will dismiss. That's why the actual adding the passenger to the vehicle is scheduled // asynchronously, so it can be cancelled easily in case the vehicle is uninstalled meanwhile. SeatMap::iterator seat; - VehicleJoinEvent* e = new VehicleJoinEvent(this, unit); - unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0)); - _pendingJoinEvents.push_back(e); - if (seatId < 0) // no specific seat requirement { for (seat = Seats.begin(); seat != Seats.end(); ++seat) @@ -447,23 +443,22 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) break; if (seat == Seats.end()) // no available seat - { - CancelJoinEvent(e); return false; - } - e->Seat = seat; + VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat); + _pendingJoinEvents.push_back(e); + unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0)); } else { seat = Seats.find(seatId); if (seat == Seats.end()) - { - CancelJoinEvent(e); return false; - } - e->Seat = seat; + VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat); + _pendingJoinEvents.push_back(e); + unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0)); + if (seat->second.Passenger) { Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger); @@ -687,25 +682,6 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o) x = (inx + iny * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation())); } -/** - * @fn void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) - * - * @brief Aborts delayed @VehicleJoinEvent objects. - * Implies that the related unit will not be boarding the vehicle after all. - * - * @author Machiavelli - * @date 17-2-2013 - * - * @param [in,out] e The VehicleJoinEvent* to process. - */ - -void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) -{ - ASSERT(_pendingJoinEvents.back() == e); - e->to_Abort = true; - _pendingJoinEvents.pop_back(); -} - /** * @fn void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) * @@ -721,7 +697,7 @@ void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) { - for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr) + for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr) { if (*itr == e) { @@ -744,7 +720,7 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) void Vehicle::RemovePendingEventsForSeat(int8 seatId) { - for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();) + for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();) { if ((*itr)->Seat->first == seatId) { diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 4f3d2eea4ec..38c5a39f67d 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -23,7 +23,7 @@ #include "Object.h" #include "VehicleDefines.h" #include "Unit.h" -#include +#include struct VehicleEntry; class Unit; @@ -63,12 +63,8 @@ class Vehicle : public TransportBase void RelocatePassengers(); void RemoveAllPassengers(); void Dismiss(); - void TeleportVehicle(float x, float y, float z, float ang); bool IsVehicleInUse() { return Seats.begin() != Seats.end(); } - void SetLastShootPos(Position const& pos) { m_lastShootPos.Relocate(pos); } - Position GetLastShootPos() { return m_lastShootPos; } - SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones. VehicleSeatEntry const* GetSeatForPassenger(Unit* passenger); @@ -94,7 +90,6 @@ class Vehicle : public TransportBase /// This method transforms supplied global coordinates into local offsets void CalculatePassengerOffset(float& x, float& y, float& z, float& o); - void CancelJoinEvent(VehicleJoinEvent* e); void RemovePendingEvent(VehicleJoinEvent* e); void RemovePendingEventsForSeat(int8 seatId); @@ -105,15 +100,16 @@ class Vehicle : public TransportBase uint32 _creatureEntry; ///< Can be different than the entry of _me in case of players Status _status; ///< Internal variable for sanity checks - Position m_lastShootPos; - std::deque _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers + + typedef std::list PendingJoinEventContainer; + PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers }; class VehicleJoinEvent : public BasicEvent { friend class Vehicle; protected: - VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {} + VehicleJoinEvent(Vehicle* v, Unit* u, SeatMap::iterator seat) : Target(v), Passenger(u), Seat(seat) {} ~VehicleJoinEvent() { Target->RemovePendingEvent(this); } bool Execute(uint64, uint32); void Abort(uint64); -- cgit v1.2.3