From b91c33dca569c557b8d93b986d76cd55d1e100af Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sat, 23 Feb 2013 15:12:39 +0100 Subject: Core/Vehicles: Fix a crash in VehicleJoinEvent::Execute Crash would happen if multiple events were scheduled for the same seat. Fixes #9255 --- src/server/game/Entities/Vehicle/Vehicle.cpp | 26 ++++++++++++++++++++++++++ src/server/game/Entities/Vehicle/Vehicle.h | 7 +++++-- 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 10d534f4568..924b52de044 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -701,6 +701,7 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o) void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) { + ASSERT(_pendingJoinEvents.back() == e); e->to_Abort = true; _pendingJoinEvents.pop_back(); } @@ -730,6 +731,29 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) } } +/** + * @fn void Vehicle::RemovePendingEventsForSeat(uint8 seatId) + * + * @brief Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called + * + * @author Machiavelli + * @date 23-2-2013 + * + * @param seatId Identifier for the seat. + */ + +void Vehicle::RemovePendingEventsForSeat(uint8 seatId) +{ + for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr) + { + if (uint8((*itr)->Seat->first) == seatId) + { + (*itr)->to_Abort = true; + _pendingJoinEvents.erase(itr); + } + } +} + /** * @fn bool VehicleJoinEvent::Execute(uint64, uint32) * @@ -750,6 +774,8 @@ bool VehicleJoinEvent::Execute(uint64, uint32) ASSERT(Passenger->IsInWorld()); ASSERT(Target->GetBase()->IsInWorld()); + Target->RemovePendingEventsForSeat(uint8(Seat->first)); + Passenger->m_vehicle = Target; Seat->second.Passenger = Passenger->GetGUID(); if (Seat->second.SeatInfo->CanEnterOrExit()) diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 40aea1a2d02..65aa6f2517b 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -94,6 +94,11 @@ 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(uint8 seatId); + + private: Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature. VehicleEntry const* _vehicleInfo; ///< DBC data for vehicle GuidSet vehiclePlayers; @@ -102,8 +107,6 @@ class Vehicle : public TransportBase Status _status; ///< Internal variable for sanity checks Position m_lastShootPos; std::deque _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers - void CancelJoinEvent(VehicleJoinEvent* e); - void RemovePendingEvent(VehicleJoinEvent* e); }; class VehicleJoinEvent : public BasicEvent -- cgit v1.2.3 From 7cab6d308aac9a13f5073d1762dc12676367f3a7 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sat, 23 Feb 2013 15:25:47 +0100 Subject: Core/Vehicles: Make RemovePendingEventsForSeat iterating crashsafe --- src/server/game/Entities/Vehicle/Vehicle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 924b52de044..20110a555cd 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -744,12 +744,13 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) void Vehicle::RemovePendingEventsForSeat(uint8 seatId) { - for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr) + for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();) { + std::deque::iterator cur = itr++; if (uint8((*itr)->Seat->first) == seatId) { (*itr)->to_Abort = true; - _pendingJoinEvents.erase(itr); + _pendingJoinEvents.erase(cur); } } } -- cgit v1.2.3 From daced24223ce60898535352d4a3efa6424ab2835 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 23 Feb 2013 16:05:08 +0100 Subject: Core/Vehicles: Really make RemovePendingEventsForSeat iterating crash safe --- src/server/game/Entities/Vehicle/Vehicle.cpp | 11 ++++++----- src/server/game/Entities/Vehicle/Vehicle.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 20110a555cd..951b55d9160 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -742,16 +742,17 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) * @param seatId Identifier for the seat. */ -void Vehicle::RemovePendingEventsForSeat(uint8 seatId) +void Vehicle::RemovePendingEventsForSeat(int8 seatId) { for (std::deque::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();) { - std::deque::iterator cur = itr++; - if (uint8((*itr)->Seat->first) == seatId) + if ((*itr)->Seat->first == seatId) { (*itr)->to_Abort = true; - _pendingJoinEvents.erase(cur); + _pendingJoinEvents.erase(itr++); } + else + ++itr; } } @@ -775,7 +776,7 @@ bool VehicleJoinEvent::Execute(uint64, uint32) ASSERT(Passenger->IsInWorld()); ASSERT(Target->GetBase()->IsInWorld()); - Target->RemovePendingEventsForSeat(uint8(Seat->first)); + Target->RemovePendingEventsForSeat(Seat->first); Passenger->m_vehicle = Target; Seat->second.Passenger = Passenger->GetGUID(); diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 65aa6f2517b..4f3d2eea4ec 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -96,7 +96,7 @@ class Vehicle : public TransportBase void CancelJoinEvent(VehicleJoinEvent* e); void RemovePendingEvent(VehicleJoinEvent* e); - void RemovePendingEventsForSeat(uint8 seatId); + void RemovePendingEventsForSeat(int8 seatId); private: Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature. -- cgit v1.2.3 From 56e32aac82fe6d18280f6202e3e44d6935fb4b4c Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 23 Feb 2013 18:15:49 +0100 Subject: SQL: Fix "No newline at end of file" in 194cc54f08d8b42c8c49d756e14273d917e1fcf2 --- sql/updates/world/2013_02_23_00_world_gameobject.sql | 2 +- src/server/game/Accounts/AccountMgr.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/sql/updates/world/2013_02_23_00_world_gameobject.sql b/sql/updates/world/2013_02_23_00_world_gameobject.sql index 039ee4c0c64..48694505704 100644 --- a/sql/updates/world/2013_02_23_00_world_gameobject.sql +++ b/sql/updates/world/2013_02_23_00_world_gameobject.sql @@ -1 +1 @@ -DELETE FROM `gameobject` WHERE `guid`=61090; \ No newline at end of file +DELETE FROM `gameobject` WHERE `guid`=61090; diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 572327a7bfc..8c08a9ae202 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2009 MaNGOS * -- cgit v1.2.3 From 22353a012ff506f9388355b0d464bfafaf610902 Mon Sep 17 00:00:00 2001 From: Spp Date: Sat, 23 Feb 2013 17:24:21 +0100 Subject: Core/RBAC: Fix mem leak --- src/server/game/Accounts/AccountMgr.cpp | 11 +++++++++++ src/server/game/Accounts/AccountMgr.h | 1 + 2 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 8c08a9ae202..596f7f5ceb9 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -27,7 +27,18 @@ AccountMgr::AccountMgr() { +} + +AccountMgr::~AccountMgr() +{ + for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) + delete itr->second; + + for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) + delete itr->second; + for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) + delete itr->second; } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 440e012f1fc..2c07172723d 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -45,6 +45,7 @@ class AccountMgr private: AccountMgr(); + ~AccountMgr(); public: AccountOpResult CreateAccount(std::string username, std::string password); -- cgit v1.2.3 From 49b609d2e478da5240a979f49ae3e3002dae49cb Mon Sep 17 00:00:00 2001 From: Spp Date: Sat, 23 Feb 2013 19:17:39 +0100 Subject: Core/Calendar: Fix mem leak and minor cosmetic changes --- src/server/game/Calendar/CalendarMgr.cpp | 87 ++++++++++++++++------------ src/server/game/Calendar/CalendarMgr.h | 16 ++--- src/server/game/Handlers/CalendarHandler.cpp | 8 +-- 3 files changed, 61 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 763e0132c10..5f73ee48380 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -40,6 +40,12 @@ CalendarMgr::CalendarMgr() CalendarMgr::~CalendarMgr() { + for (CalendarEventStore::iterator itr = _events.begin(); itr != _events.end(); ++itr) + delete *itr; + + for (CalendarEventInviteStore::iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + delete *itr2; } void CalendarMgr::LoadFromDB() @@ -153,7 +159,7 @@ void CalendarMgr::RemoveEvent(uint64 eventId, uint64 remover) PreparedStatement* stmt; MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()); - std::vector::iterator itr = _invites[eventId].begin(); + CalendarInviteStore::iterator itr = _invites[eventId].begin(); while (itr != _invites[eventId].end()) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE); @@ -187,7 +193,7 @@ void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, uint64 /*remover if (!calendarEvent) return; - std::vector::iterator itr = _invites[eventId].begin(); + CalendarInviteStore::iterator itr = _invites[eventId].begin(); for (; itr != _invites[eventId].end(); ++itr) if ((*itr)->GetInviteId() == inviteId) break; @@ -254,8 +260,8 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(uint64 guid) if ((*itr)->GetCreatorGUID() == guid) RemoveEvent((*itr)->GetEventId(), 0); // don't send mail if removing a character - std::vector playerInvites = GetPlayerInvites(guid); - for (std::vector::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + CalendarInviteStore playerInvites = GetPlayerInvites(guid); + for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); } @@ -265,14 +271,14 @@ void CalendarMgr::RemovePlayerGuildEventsAndSignups(uint64 guid, uint32 guildId) if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement())) RemoveEvent((*itr)->GetEventId(), guid); - std::vector playerInvites = GetPlayerInvites(guid); - for (std::vector::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + CalendarInviteStore playerInvites = GetPlayerInvites(guid); + for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId())) if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId) RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); } -CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) +CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) const { for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) if ((*itr)->GetEventId() == eventId) @@ -282,10 +288,10 @@ CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) return NULL; } -CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) +CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) const { - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteId() == inviteId) return *itr2; @@ -305,12 +311,10 @@ uint64 CalendarMgr::GetFreeEventId() { if (_freeEventIds.empty()) return ++_maxEventId; - else - { - uint64 eventId = _freeEventIds.front(); - _freeEventIds.pop_front(); - return eventId; - } + + uint64 eventId = _freeEventIds.front(); + _freeEventIds.pop_front(); + return eventId; } void CalendarMgr::FreeInviteId(uint64 id) @@ -325,20 +329,18 @@ uint64 CalendarMgr::GetFreeInviteId() { if (_freeInviteIds.empty()) return ++_maxInviteId; - else - { - uint64 inviteId = _freeInviteIds.front(); - _freeInviteIds.pop_front(); - return inviteId; - } + + uint64 inviteId = _freeInviteIds.front(); + _freeInviteIds.pop_front(); + return inviteId; } CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid) { CalendarEventStore events; - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteeGUID() == guid) events.insert(GetEvent(itr->first)); @@ -350,17 +352,17 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid) return events; } -std::vector CalendarMgr::GetEventInvites(uint64 eventId) +CalendarInviteStore const& CalendarMgr::GetEventInvites(uint64 eventId) { return _invites[eventId]; } -std::vector CalendarMgr::GetPlayerInvites(uint64 guid) +CalendarInviteStore CalendarMgr::GetPlayerInvites(uint64 guid) { - std::vector invites; + CalendarInviteStore invites; - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteeGUID() == guid) invites.push_back(*itr2); @@ -369,13 +371,22 @@ std::vector CalendarMgr::GetPlayerInvites(uint64 guid) uint32 CalendarMgr::GetPlayerNumPending(uint64 guid) { - std::vector const& invites = GetPlayerInvites(guid); + CalendarInviteStore const& invites = GetPlayerInvites(guid); uint32 pendingNum = 0; - for (std::vector::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) - // correct? - if ((*itr)->GetStatus() == CALENDAR_STATUS_INVITED || (*itr)->GetStatus() == CALENDAR_STATUS_TENTATIVE || (*itr)->GetStatus() == CALENDAR_STATUS_NOT_SIGNED_UP) - ++pendingNum; + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + { + switch ((*itr)->GetStatus()) + { + case CALENDAR_STATUS_INVITED: + case CALENDAR_STATUS_TENTATIVE: + case CALENDAR_STATUS_NOT_SIGNED_UP: + ++pendingNum; + break; + default: + break; + } + } return pendingNum; } @@ -531,7 +542,7 @@ void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEv if (!player) return; - std::vector const& eventInviteeList = _invites[calendarEvent.GetEventId()]; + CalendarInviteStore const& eventInviteeList = _invites[calendarEvent.GetEventId()]; WorldPacket data(SMSG_CALENDAR_SEND_EVENT, 60 + eventInviteeList.size() * 32); data << uint8(sendType); @@ -549,7 +560,7 @@ void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEv data << uint32(calendarEvent.GetGuildId()); data << uint32(eventInviteeList.size()); - for (std::vector::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) { CalendarInvite const* calendarInvite = (*itr); uint64 inviteeGuid = calendarInvite->GetInviteeGUID(); @@ -627,8 +638,8 @@ void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket packet, CalendarEven guild->BroadcastPacket(&packet); // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them) - std::vector invites = _invites[calendarEvent.GetEventId()]; - for (std::vector::iterator itr = invites.begin(); itr != invites.end(); ++itr) + CalendarInviteStore invites = _invites[calendarEvent.GetEventId()]; + for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr) if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID())) if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId())) player->SendDirectMessage(&packet); diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 3674e707399..d1b3d0a9dd6 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -261,9 +261,9 @@ struct CalendarEvent std::string _title; std::string _description; }; - +typedef std::vector CalendarInviteStore; typedef std::set CalendarEventStore; -typedef std::map > CalendarInviteStore; +typedef std::map CalendarEventInviteStore; class CalendarMgr { @@ -274,7 +274,7 @@ class CalendarMgr ~CalendarMgr(); CalendarEventStore _events; - CalendarInviteStore _invites; + CalendarEventInviteStore _invites; std::deque _freeEventIds; std::deque _freeInviteIds; @@ -284,14 +284,14 @@ class CalendarMgr public: void LoadFromDB(); - CalendarEvent* GetEvent(uint64 eventId); + CalendarEvent* GetEvent(uint64 eventId) const; CalendarEventStore const& GetEvents() const { return _events; } CalendarEventStore GetPlayerEvents(uint64 guid); - CalendarInvite* GetInvite(uint64 inviteId); - CalendarInviteStore const& GetInvites() const { return _invites; } - std::vector GetEventInvites(uint64 eventId); - std::vector GetPlayerInvites(uint64 guid); + CalendarInvite* GetInvite(uint64 inviteId) const; + CalendarEventInviteStore const& GetInvites() const { return _invites; } + CalendarInviteStore const& GetEventInvites(uint64 eventId); + CalendarInviteStore GetPlayerInvites(uint64 guid); void FreeEventId(uint64 id); uint64 GetFreeEventId(); diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 9dbc4bec199..86f943cf1bf 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -57,9 +57,9 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance - std::vector invites = sCalendarMgr->GetPlayerInvites(guid); + CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid); data << uint32(invites.size()); - for (std::vector::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) { data << uint64((*itr)->GetEventId()); data << uint64((*itr)->GetInviteId()); @@ -347,9 +347,9 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) newEvent->SetEventTime(time_t(time)); sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY); - std::vector invites = sCalendarMgr->GetEventInvites(eventId); + CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId); - for (std::vector::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId())); // should we change owner when somebody makes a copy of event owned by another person? -- cgit v1.2.3 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') 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