diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-11-21 12:25:22 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-11-21 12:25:22 +0100 |
commit | b888b1b09f71a8b8b4a9d45c804a1f164fb65ac3 (patch) | |
tree | ba507c4c1c5e8487bd223afbde44ecf9eeac162e /src/server/game/Calendar/CalendarMgr.cpp | |
parent | 8c072b93af3a4efcbde21cc85fedcf7fa48fa7b4 (diff) |
Core/Calendar: Implement different timezone support for ingame calendar
Closes #8390
Closes #29427
Diffstat (limited to 'src/server/game/Calendar/CalendarMgr.cpp')
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.cpp | 291 |
1 files changed, 180 insertions, 111 deletions
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index fdceaa3762e..66f8ab9cb27 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -24,12 +24,16 @@ #include "GuildMgr.h" #include "Log.h" #include "Mail.h" +#include "MapUtils.h" #include "ObjectAccessor.h" #include "Player.h" +#include "StringConvert.h" +#include "WorldSession.h" +#include "WowTime.h" #include <sstream> CalendarInvite::CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _responseTime(0), -_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note("") { } +_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note() { } CalendarInvite::~CalendarInvite() { @@ -184,7 +188,6 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover) CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); CharacterDatabasePreparedStatement* stmt; - MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()); CalendarInviteStore& eventInvites = _invites[calendarEvent->GetEventId()]; for (size_t i = 0; i < eventInvites.size(); ++i) @@ -197,7 +200,10 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover) // guild events only? check invite status here? // When an event is deleted, all invited (accepted/declined? - verify) guildies are notified via in-game mail. (wowwiki) if (!remover.IsEmpty() && invite->GetInviteeGUID() != remover) + { + MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody(ObjectAccessor::FindConnectedPlayer(invite->GetInviteeGUID()))); mail.SendMailTo(trans, MailReceiver(invite->GetInviteeGUID().GetCounter()), calendarEvent, MAIL_CHECK_MASK_COPIED); + } delete invite; } @@ -375,7 +381,7 @@ void CalendarMgr::DeleteOldEvents() } } -CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents) +CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents) const { CalendarEventStore result; for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) @@ -385,7 +391,7 @@ CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool include return result; } -CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) +CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) const { CalendarEventStore result; @@ -400,7 +406,7 @@ CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) return result; } -CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) +CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) const { CalendarEventStore events; @@ -419,12 +425,16 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) return events; } -CalendarInviteStore const& CalendarMgr::GetEventInvites(uint64 eventId) +CalendarInviteStore CalendarMgr::GetEventInvites(uint64 eventId) const { - return _invites[eventId]; + CalendarInviteStore invites; + if (CalendarInviteStore const* invitesStore = Trinity::Containers::MapGetValuePtr(_invites, eventId)) + invites = *invitesStore; + + return invites; } -CalendarInviteStore CalendarMgr::GetPlayerInvites(ObjectGuid guid) +CalendarInviteStore CalendarMgr::GetPlayerInvites(ObjectGuid guid) const { CalendarInviteStore invites; @@ -465,20 +475,17 @@ std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const return strm.str(); } -std::string CalendarEvent::BuildCalendarMailBody() const +std::string CalendarEvent::BuildCalendarMailBody(Player const* invitee) const { - WorldPacket data; - uint32 time; - std::ostringstream strm; + WowTime time; + time.SetUtcTimeFromUnixTime(_date); + if (invitee) + time += invitee->GetSession()->GetTimezoneOffset(); - // we are supposed to send PackedTime so i used WorldPacket to pack it - data.AppendPackedTime(_date); - data >> time; - strm << time; - return strm.str(); + return Trinity::ToString(time.GetPackedTime()); } -void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) +void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) const { CalendarEvent* calendarEvent = GetEvent(invite.GetEventId()); @@ -487,71 +494,103 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) uint8 level = player ? player->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(invitee); - WorldPackets::Calendar::CalendarInviteAdded packet; - packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0; - packet.InviteGuid = invitee; - packet.InviteID = calendarEvent ? invite.GetInviteId() : 0; - packet.Level = level; - packet.ResponseTime = invite.GetResponseTime(); - packet.Status = invite.GetStatus(); - packet.Type = calendarEvent ? calendarEvent->IsGuildEvent() : 0; // Correct ? - packet.ClearPending = calendarEvent ? !calendarEvent->IsGuildEvent() : true; // Correct ? + auto packetBuilder = [&](Player const* receiver) + { + WorldPackets::Calendar::CalendarInviteAdded packet; + packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0; + packet.InviteGuid = invitee; + packet.InviteID = calendarEvent ? invite.GetInviteId() : 0; + packet.Level = level; + packet.ResponseTime.SetUtcTimeFromUnixTime(invite.GetResponseTime()); + packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset(); + packet.Status = invite.GetStatus(); + packet.Type = calendarEvent ? calendarEvent->IsGuildEvent() : 0; // Correct ? + packet.ClearPending = calendarEvent ? !calendarEvent->IsGuildEvent() : true; // Correct ? + + receiver->SendDirectMessage(packet.Write()); + }; if (!calendarEvent) // Pre-invite { if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID())) - playerSender->SendDirectMessage(packet.Write()); + packetBuilder(playerSender); } else { if (calendarEvent->GetOwnerGUID() != invite.GetInviteeGUID()) // correct? - SendPacketToAllEventRelatives(packet.Write(), *calendarEvent); + for (Player* receiver : GetAllEventRelatives(*calendarEvent)) + packetBuilder(receiver); } } -void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) +void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) const { - WorldPackets::Calendar::CalendarEventUpdatedAlert packet; - packet.ClearPending = true; // FIXME - packet.Date = calendarEvent.GetDate(); - packet.Description = calendarEvent.GetDescription(); - packet.EventClubID = calendarEvent.GetGuildId(); - packet.EventID = calendarEvent.GetEventId(); - packet.EventName = calendarEvent.GetTitle(); - packet.EventType = calendarEvent.GetType(); - packet.Flags = calendarEvent.GetFlags(); - packet.LockDate = calendarEvent.GetLockDate(); // Always 0 ? - packet.OriginalDate = originalDate; - packet.TextureID = calendarEvent.GetTextureId(); + auto packetBuilder = [&](Player const* receiver) + { + WorldPackets::Calendar::CalendarEventUpdatedAlert packet; + packet.ClearPending = true; // FIXME + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += receiver->GetSession()->GetTimezoneOffset(); + packet.Description = calendarEvent.GetDescription(); + packet.EventClubID = calendarEvent.GetGuildId(); + packet.EventID = calendarEvent.GetEventId(); + packet.EventName = calendarEvent.GetTitle(); + packet.EventType = calendarEvent.GetType(); + packet.Flags = calendarEvent.GetFlags(); + packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ? + if (calendarEvent.GetLockDate()) + packet.LockDate += receiver->GetSession()->GetTimezoneOffset(); + packet.OriginalDate.SetUtcTimeFromUnixTime(originalDate); + packet.OriginalDate += receiver->GetSession()->GetTimezoneOffset(); + packet.TextureID = calendarEvent.GetTextureId(); - SendPacketToAllEventRelatives(packet.Write(), calendarEvent); + receiver->SendDirectMessage(packet.Write()); + }; + + for (Player* receiver : GetAllEventRelatives(calendarEvent)) + packetBuilder(receiver); } -void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) +void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const { - WorldPackets::Calendar::CalendarInviteStatus packet; - packet.ClearPending = true; // FIXME - packet.Date = calendarEvent.GetDate(); - packet.EventID = calendarEvent.GetEventId(); - packet.Flags = calendarEvent.GetFlags(); - packet.InviteGuid = invite.GetInviteeGUID(); - packet.ResponseTime = invite.GetResponseTime(); - packet.Status = invite.GetStatus(); + auto packetBuilder = [&](Player const* receiver) + { + WorldPackets::Calendar::CalendarInviteStatus packet; + packet.ClearPending = true; // FIXME + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += receiver->GetSession()->GetTimezoneOffset(); + packet.EventID = calendarEvent.GetEventId(); + packet.Flags = calendarEvent.GetFlags(); + packet.InviteGuid = invite.GetInviteeGUID(); + packet.ResponseTime.SetUtcTimeFromUnixTime(invite.GetResponseTime()); + packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset(); + packet.Status = invite.GetStatus(); - SendPacketToAllEventRelatives(packet.Write(), calendarEvent); + receiver->SendDirectMessage(packet.Write()); + }; + + for (Player* receiver : GetAllEventRelatives(calendarEvent)) + packetBuilder(receiver); } -void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) +void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) const { - WorldPackets::Calendar::CalendarEventRemovedAlert packet; - packet.ClearPending = true; // FIXME - packet.Date = calendarEvent.GetDate(); - packet.EventID = calendarEvent.GetEventId(); + auto packetBuilder = [&](Player const* receiver) + { + WorldPackets::Calendar::CalendarEventRemovedAlert packet; + packet.ClearPending = true; // FIXME + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += receiver->GetSession()->GetTimezoneOffset(); + packet.EventID = calendarEvent.GetEventId(); - SendPacketToAllEventRelatives(packet.Write(), calendarEvent); + receiver->SendDirectMessage(packet.Write()); + }; + + for (Player* receiver : GetAllEventRelatives(calendarEvent)) + packetBuilder(receiver); } -void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags) +void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags) const { WorldPackets::Calendar::CalendarInviteRemoved packet; packet.ClearPending = true; // FIXME @@ -562,7 +601,7 @@ void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEve SendPacketToAllEventRelatives(packet.Write(), calendarEvent); } -void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) +void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const { WorldPackets::Calendar::CalendarModeratorStatus packet; packet.ClearPending = true; // FIXME @@ -573,82 +612,94 @@ void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& cal SendPacketToAllEventRelatives(packet.Write(), calendarEvent); } -void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) +void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const { - WorldPackets::Calendar::CalendarInviteAlert packet; - packet.Date = calendarEvent.GetDate(); - packet.EventID = calendarEvent.GetEventId(); - packet.EventName = calendarEvent.GetTitle(); - packet.EventType = calendarEvent.GetType(); - packet.Flags = calendarEvent.GetFlags(); - packet.InviteID = invite.GetInviteId(); - packet.InvitedByGuid = invite.GetSenderGUID(); - packet.ModeratorStatus = invite.GetRank(); - packet.OwnerGuid = calendarEvent.GetOwnerGUID(); - packet.Status = invite.GetStatus(); - packet.TextureID = calendarEvent.GetTextureId(); - packet.EventClubID = calendarEvent.GetGuildId(); + auto packetBuilder = [&](Player const* receiver) + { + WorldPackets::Calendar::CalendarInviteAlert packet; + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += receiver->GetSession()->GetTimezoneOffset(); + packet.EventID = calendarEvent.GetEventId(); + packet.EventName = calendarEvent.GetTitle(); + packet.EventType = calendarEvent.GetType(); + packet.Flags = calendarEvent.GetFlags(); + packet.InviteID = invite.GetInviteId(); + packet.InvitedByGuid = invite.GetSenderGUID(); + packet.ModeratorStatus = invite.GetRank(); + packet.OwnerGuid = calendarEvent.GetOwnerGUID(); + packet.Status = invite.GetStatus(); + packet.TextureID = calendarEvent.GetTextureId(); + packet.EventClubID = calendarEvent.GetGuildId(); + + receiver->SendDirectMessage(packet.Write()); + }; if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) { if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId())) - guild->BroadcastPacket(packet.Write()); + guild->BroadcastWorker(packetBuilder); } else if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID())) - player->SendDirectMessage(packet.Write()); + packetBuilder(player); } -void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) +void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) const { Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (!player) return; - CalendarInviteStore const& eventInviteeList = _invites[calendarEvent.GetEventId()]; - WorldPackets::Calendar::CalendarSendEvent packet; - packet.Date = calendarEvent.GetDate(); + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += player->GetSession()->GetTimezoneOffset(); packet.Description = calendarEvent.GetDescription(); packet.EventID = calendarEvent.GetEventId(); packet.EventName = calendarEvent.GetTitle(); packet.EventType = sendType; packet.Flags = calendarEvent.GetFlags(); packet.GetEventType = calendarEvent.GetType(); - packet.LockDate = calendarEvent.GetLockDate(); // Always 0 ? + packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ? + if (calendarEvent.GetLockDate()) + packet.LockDate += player->GetSession()->GetTimezoneOffset(); packet.OwnerGuid = calendarEvent.GetOwnerGUID(); packet.TextureID = calendarEvent.GetTextureId(); packet.EventClubID = calendarEvent.GetGuildId(); - for (auto const& calendarInvite : eventInviteeList) + if (CalendarInviteStore const* eventInviteeList = Trinity::Containers::MapGetValuePtr(_invites, calendarEvent.GetEventId())) { - ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID(); - Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid); - - uint8 inviteeLevel = invitee ? invitee->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(inviteeGuid); - ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : sCharacterCache->GetCharacterGuildIdByGuid(inviteeGuid); - - WorldPackets::Calendar::CalendarEventInviteInfo inviteInfo; - inviteInfo.Guid = inviteeGuid; - inviteInfo.Level = inviteeLevel; - inviteInfo.Status = calendarInvite->GetStatus(); - inviteInfo.Moderator = calendarInvite->GetRank(); - inviteInfo.InviteType = calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId; - inviteInfo.InviteID = calendarInvite->GetInviteId(); - inviteInfo.ResponseTime = calendarInvite->GetResponseTime(); - inviteInfo.Notes = calendarInvite->GetNote(); - - packet.Invites.push_back(inviteInfo); + for (CalendarInvite const* calendarInvite : *eventInviteeList) + { + ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID(); + Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid); + + uint8 inviteeLevel = invitee ? invitee->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(inviteeGuid); + ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : sCharacterCache->GetCharacterGuildIdByGuid(inviteeGuid); + + WorldPackets::Calendar::CalendarEventInviteInfo inviteInfo; + inviteInfo.Guid = inviteeGuid; + inviteInfo.Level = inviteeLevel; + inviteInfo.Status = calendarInvite->GetStatus(); + inviteInfo.Moderator = calendarInvite->GetRank(); + inviteInfo.InviteType = calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId; + inviteInfo.InviteID = calendarInvite->GetInviteId(); + inviteInfo.ResponseTime.SetUtcTimeFromUnixTime(calendarInvite->GetResponseTime()); + inviteInfo.ResponseTime += player->GetSession()->GetTimezoneOffset(); + inviteInfo.Notes = calendarInvite->GetNote(); + + packet.Invites.push_back(inviteInfo); + } } player->SendDirectMessage(packet.Write()); } -void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) +void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) const { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { WorldPackets::Calendar::CalendarInviteRemovedAlert packet; - packet.Date = calendarEvent.GetDate(); + packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate()); + packet.Date += player->GetSession()->GetTimezoneOffset(); packet.EventID = calendarEvent.GetEventId(); packet.Flags = calendarEvent.GetFlags(); packet.Status = status; @@ -657,13 +708,13 @@ void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEv } } -void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) +void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) const { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->SendDirectMessage(WorldPackets::Calendar::CalendarClearPendingAction().Write()); } -void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/) +void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/) const { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { @@ -686,17 +737,35 @@ void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, } } -void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent) +void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent) const { + for (Player* player : GetAllEventRelatives(calendarEvent)) + player->SendDirectMessage(packet); +} + +std::vector<Player*> CalendarMgr::GetAllEventRelatives(CalendarEvent const& calendarEvent) const +{ + std::vector<Player*> relatedPlayers; + // Send packet to all guild members if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) + { if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId())) - guild->BroadcastPacket(packet); + { + auto memberCollector = [&](Player* player) { relatedPlayers.push_back(player); }; + guild->BroadcastWorker(memberCollector); + } + } // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them) - CalendarInviteStore invites = _invites[calendarEvent.GetEventId()]; - for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr) - if (Player* player = ObjectAccessor::FindConnectedPlayer((*itr)->GetInviteeGUID())) - if (!calendarEvent.IsGuildEvent() || player->GetGuildId() != calendarEvent.GetGuildId()) - player->SendDirectMessage(packet); + if (auto itr =_invites.find(calendarEvent.GetEventId()); itr != _invites.end()) + { + CalendarInviteStore invites = itr->second; + for (CalendarInvite const* invite : invites) + if (Player* player = ObjectAccessor::FindConnectedPlayer(invite->GetInviteeGUID())) + if (!calendarEvent.IsGuildEvent() || player->GetGuildId() != calendarEvent.GetGuildId()) + relatedPlayers.push_back(player); + } + + return relatedPlayers; } |