TrinityCore
CalendarMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "CalendarMgr.h"
19#include "CalendarPackets.h"
20#include "CharacterCache.h"
21#include "DatabaseEnv.h"
22#include "GameTime.h"
23#include "Guild.h"
24#include "GuildMgr.h"
25#include "Log.h"
26#include "Mail.h"
27#include "MapUtils.h"
28#include "ObjectAccessor.h"
29#include "Player.h"
30#include "StringConvert.h"
31#include "WorldSession.h"
32#include "WowTime.h"
33
34CalendarInvite::CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _responseTime(0),
35_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note() { }
36
38{
39 // Free _inviteId only if it's a real invite and not just a pre-invite or guild announcement
40 if (_inviteId != 0 && _eventId != 0)
41 sCalendarMgr->FreeInviteId(_inviteId);
42}
43
45{
46 sCalendarMgr->FreeEventId(_eventId);
47}
48
49CalendarMgr::CalendarMgr() : _maxEventId(0), _maxInviteId(0) { }
50
52{
53 for (CalendarEventStore::iterator itr = _events.begin(); itr != _events.end(); ++itr)
54 delete *itr;
55
56 for (CalendarEventInviteStore::iterator itr = _invites.begin(); itr != _invites.end(); ++itr)
57 for (CalendarInviteStore::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
58 delete *itr2;
59}
60
62{
63 static CalendarMgr instance;
64 return &instance;
65}
66
68{
69 uint32 oldMSTime = getMSTime();
70
71 uint32 count = 0;
72 _maxEventId = 0;
73 _maxInviteId = 0;
74
75 // 0 1 2 3 4 5 6 7 8
76 if (QueryResult result = CharacterDatabase.Query("SELECT EventID, Owner, Title, Description, EventType, TextureID, Date, Flags, LockDate FROM calendar_events"))
77 do
78 {
79 Field* fields = result->Fetch();
80
81 uint64 eventID = fields[0].GetUInt64();
82 ObjectGuid ownerGUID = ObjectGuid::Create<HighGuid::Player>(fields[1].GetUInt64());
83 std::string title = fields[2].GetString();
84 std::string description = fields[3].GetString();
85 CalendarEventType type = CalendarEventType(fields[4].GetUInt8());
86 int32 textureID = fields[5].GetInt32();
87 time_t date = fields[6].GetInt64();
88 uint32 flags = fields[7].GetUInt32();
89 time_t lockDate = fields[8].GetInt64();
90 ObjectGuid::LowType guildID = UI64LIT(0);
91
93 guildID = sCharacterCache->GetCharacterGuildIdByGuid(ownerGUID);
94
95 CalendarEvent* calendarEvent = new CalendarEvent(eventID, ownerGUID, guildID, type, textureID, date, flags, title, description, lockDate);
96 _events.insert(calendarEvent);
97
98 _maxEventId = std::max(_maxEventId, eventID);
99
100 ++count;
101 }
102 while (result->NextRow());
103
104 TC_LOG_INFO("server.loading", ">> Loaded {} calendar events in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
105 count = 0;
106 oldMSTime = getMSTime();
107
108 // 0 1 2 3 4 5 6 7
109 if (QueryResult result = CharacterDatabase.Query("SELECT InviteID, EventID, Invitee, Sender, Status, ResponseTime, ModerationRank, Note FROM calendar_invites"))
110 do
111 {
112 Field* fields = result->Fetch();
113
114 uint64 inviteId = fields[0].GetUInt64();
115 uint64 eventId = fields[1].GetUInt64();
116 ObjectGuid invitee = ObjectGuid::Create<HighGuid::Player>(fields[2].GetUInt64());
117 ObjectGuid senderGUID = ObjectGuid::Create<HighGuid::Player>(fields[3].GetUInt64());
118 CalendarInviteStatus status = CalendarInviteStatus(fields[4].GetUInt8());
119 time_t responseTime = fields[5].GetInt64();
120 CalendarModerationRank rank = CalendarModerationRank(fields[6].GetUInt8());
121 std::string note = fields[7].GetString();
122
123 CalendarInvite* invite = new CalendarInvite(inviteId, eventId, invitee, senderGUID, responseTime, status, rank, note);
124 _invites[eventId].push_back(invite);
125
126 _maxInviteId = std::max(_maxInviteId, inviteId);
127
128 ++count;
129 }
130 while (result->NextRow());
131
132 TC_LOG_INFO("server.loading", ">> Loaded {} calendar invites in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
133
134 for (uint64 i = 1; i < _maxEventId; ++i)
135 if (!GetEvent(i))
136 _freeEventIds.push_back(i);
137
138 for (uint64 i = 1; i < _maxInviteId; ++i)
139 if (!GetInvite(i))
140 _freeInviteIds.push_back(i);
141}
142
144{
145 _events.insert(calendarEvent);
146 UpdateEvent(calendarEvent);
147 SendCalendarEvent(calendarEvent->GetOwnerGUID(), *calendarEvent, sendType);
148}
149
151{
152 if (!calendarEvent->IsGuildAnnouncement() && calendarEvent->GetOwnerGUID() != invite->GetInviteeGUID())
154
155 if (!calendarEvent->IsGuildEvent() || invite->GetInviteeGUID() == calendarEvent->GetOwnerGUID())
156 SendCalendarEventInviteAlert(*calendarEvent, *invite);
157
158 if (!calendarEvent->IsGuildAnnouncement())
159 {
160 _invites[invite->GetEventId()].push_back(invite);
161 UpdateInvite(invite, trans);
162 }
163}
164
166{
167 CalendarEvent* calendarEvent = GetEvent(eventId);
168
169 if (!calendarEvent)
170 {
172 return;
173 }
174
175 RemoveEvent(calendarEvent, remover);
176}
177
179{
180 if (!calendarEvent)
181 {
183 return;
184 }
185
186 SendCalendarEventRemovedAlert(*calendarEvent);
187
188 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
190
191 CalendarInviteStore& eventInvites = _invites[calendarEvent->GetEventId()];
192 for (size_t i = 0; i < eventInvites.size(); ++i)
193 {
194 CalendarInvite* invite = eventInvites[i];
195 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE);
196 stmt->setUInt64(0, invite->GetInviteId());
197 trans->Append(stmt);
198
199 // guild events only? check invite status here?
200 // When an event is deleted, all invited (accepted/declined? - verify) guildies are notified via in-game mail. (wowwiki)
201 if (!remover.IsEmpty() && invite->GetInviteeGUID() != remover)
202 {
204 mail.SendMailTo(trans, MailReceiver(invite->GetInviteeGUID().GetCounter()), calendarEvent, MAIL_CHECK_MASK_COPIED);
205 }
206
207 delete invite;
208 }
209
210 _invites.erase(calendarEvent->GetEventId());
211
212 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_EVENT);
213 stmt->setUInt64(0, calendarEvent->GetEventId());
214 trans->Append(stmt);
215 CharacterDatabase.CommitTransaction(trans);
216
217 _events.erase(calendarEvent);
218 delete calendarEvent;
219}
220
221void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, ObjectGuid /*remover*/)
222{
223 CalendarEvent* calendarEvent = GetEvent(eventId);
224
225 if (!calendarEvent)
226 return;
227
228 CalendarInviteStore::iterator itr = _invites[eventId].begin();
229 for (; itr != _invites[eventId].end(); ++itr)
230 if ((*itr)->GetInviteId() == inviteId)
231 break;
232
233 if (itr == _invites[eventId].end())
234 return;
235
236 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
238 stmt->setUInt64(0, (*itr)->GetInviteId());
239 trans->Append(stmt);
240 CharacterDatabase.CommitTransaction(trans);
241
242 if (!calendarEvent->IsGuildEvent())
243 SendCalendarEventInviteRemoveAlert((*itr)->GetInviteeGUID(), *calendarEvent, CALENDAR_STATUS_REMOVED);
244
245 SendCalendarEventInviteRemove(*calendarEvent, **itr, calendarEvent->GetFlags());
246
247 // we need to find out how to use CALENDAR_INVITE_REMOVED_MAIL_SUBJECT to force client to display different mail
248 //if ((*itr)->GetInviteeGUID() != remover)
249 // MailDraft(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody())
250 // .SendMailTo(trans, MailReceiver((*itr)->GetInvitee()), calendarEvent, MAIL_CHECK_MASK_COPIED);
251
252 delete *itr;
253 _invites[eventId].erase(itr);
254}
255
257{
259 stmt->setUInt64(0, calendarEvent->GetEventId());
260 stmt->setUInt64(1, calendarEvent->GetOwnerGUID().GetCounter());
261 stmt->setString(2, calendarEvent->GetTitle());
262 stmt->setString(3, calendarEvent->GetDescription());
263 stmt->setUInt8(4, calendarEvent->GetType());
264 stmt->setInt32(5, calendarEvent->GetTextureId());
265 stmt->setInt64(6, calendarEvent->GetDate());
266 stmt->setUInt32(7, calendarEvent->GetFlags());
267 stmt->setInt64(8, calendarEvent->GetLockDate());
268 CharacterDatabase.Execute(stmt);
269}
270
272{
274 stmt->setUInt64(0, invite->GetInviteId());
275 stmt->setUInt64(1, invite->GetEventId());
276 stmt->setUInt64(2, invite->GetInviteeGUID().GetCounter());
277 stmt->setUInt64(3, invite->GetSenderGUID().GetCounter());
278 stmt->setUInt8(4, invite->GetStatus());
279 stmt->setInt64(5, invite->GetResponseTime());
280 stmt->setUInt8(6, invite->GetRank());
281 stmt->setString(7, invite->GetNote());
282 CharacterDatabase.ExecuteOrAppend(trans, stmt);
283}
284
286{
287 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
288 {
289 CalendarEvent* event = *itr;
290 ++itr;
291 if (event->GetOwnerGUID() == guid)
292 RemoveEvent(event, ObjectGuid::Empty); // don't send mail if removing a character
293 }
294
295 CalendarInviteStore playerInvites = GetPlayerInvites(guid);
296 for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr)
297 RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid);
298}
299
301{
302 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
303 if ((*itr)->GetOwnerGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()))
304 RemoveEvent((*itr)->GetEventId(), guid);
305
306 CalendarInviteStore playerInvites = GetPlayerInvites(guid);
307 for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr)
308 if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId()))
309 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId)
310 RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid);
311}
312
314{
315 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
316 if ((*itr)->GetEventId() == eventId)
317 return *itr;
318
319 TC_LOG_DEBUG("calendar", "CalendarMgr::GetEvent: [{}] not found!", eventId);
320 return nullptr;
321}
322
324{
325 for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr)
326 for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
327 if ((*itr2)->GetInviteId() == inviteId)
328 return *itr2;
329
330 TC_LOG_DEBUG("calendar", "CalendarMgr::GetInvite: [{}] not found!", inviteId);
331 return nullptr;
332}
333
335{
336 if (id == _maxEventId)
337 --_maxEventId;
338 else
339 _freeEventIds.push_back(id);
340}
341
343{
344 if (_freeEventIds.empty())
345 return ++_maxEventId;
346
347 uint64 eventId = _freeEventIds.front();
348 _freeEventIds.pop_front();
349 return eventId;
350}
351
353{
354 if (id == _maxInviteId)
355 --_maxInviteId;
356 else
357 _freeInviteIds.push_back(id);
358}
359
361{
362 if (_freeInviteIds.empty())
363 return ++_maxInviteId;
364
365 uint64 inviteId = _freeInviteIds.front();
366 _freeInviteIds.pop_front();
367 return inviteId;
368}
369
371{
373
374 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
375 {
376 CalendarEvent* event = *itr;
377 ++itr;
378 if (event->GetDate() < oldEventsTime)
380 }
381}
382
384{
385 CalendarEventStore result;
386 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
387 if ((*itr)->GetOwnerGUID() == guid && (includeGuildEvents || (!(*itr)->IsGuildEvent() && !(*itr)->IsGuildAnnouncement())))
388 result.insert(*itr);
389
390 return result;
391}
392
394{
395 CalendarEventStore result;
396
397 if (!guildId)
398 return result;
399
400 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
401 if ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement())
402 if ((*itr)->GetGuildId() == guildId)
403 result.insert(*itr);
404
405 return result;
406}
407
409{
410 CalendarEventStore events;
411
412 for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr)
413 for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
414 if ((*itr2)->GetInviteeGUID() == guid)
415 if (CalendarEvent* event = GetEvent(itr->first)) // NULL check added as attempt to fix #11512
416 events.insert(event);
417
419 if (player->GetGuildId())
420 for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
421 if ((*itr)->GetGuildId() == player->GetGuildId())
422 events.insert(*itr);
423
424 return events;
425}
426
428{
429 CalendarInviteStore invites;
430 if (CalendarInviteStore const* invitesStore = Trinity::Containers::MapGetValuePtr(_invites, eventId))
431 invites = *invitesStore;
432
433 return invites;
434}
435
437{
438 CalendarInviteStore invites;
439
440 for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr)
441 for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
442 if ((*itr2)->GetInviteeGUID() == guid)
443 invites.push_back(*itr2);
444
445 return invites;
446}
447
449{
450 CalendarInviteStore const& invites = GetPlayerInvites(guid);
451
452 uint32 pendingNum = 0;
453 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
454 {
455 switch ((*itr)->GetStatus())
456 {
460 ++pendingNum;
461 break;
462 default:
463 break;
464 }
465 }
466
467 return pendingNum;
468}
469
471{
472 return Trinity::StringFormat("{}:{}", remover.ToString(), _title);
473}
474
475std::string CalendarEvent::BuildCalendarMailBody(Player const* invitee) const
476{
477 WowTime time;
479 if (invitee)
480 time += invitee->GetSession()->GetTimezoneOffset();
481
482 return Trinity::ToString(time.GetPackedTime());
483}
484
486{
487 CalendarEvent* calendarEvent = GetEvent(invite.GetEventId());
488
489 ObjectGuid invitee = invite.GetInviteeGUID();
491
492 uint8 level = player ? player->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(invitee);
493
494 auto packetBuilder = [&](Player const* receiver)
495 {
497 packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0;
498 packet.InviteGuid = invitee;
499 packet.InviteID = calendarEvent ? invite.GetInviteId() : 0;
500 packet.Level = level;
502 packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset();
503 packet.Status = invite.GetStatus();
504 packet.Type = calendarEvent ? calendarEvent->IsGuildEvent() : 0; // Correct ?
505 packet.ClearPending = calendarEvent ? !calendarEvent->IsGuildEvent() : true; // Correct ?
506
507 receiver->SendDirectMessage(packet.Write());
508 };
509
510 if (!calendarEvent) // Pre-invite
511 {
512 if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID()))
513 packetBuilder(playerSender);
514 }
515 else
516 {
517 if (calendarEvent->GetOwnerGUID() != invite.GetInviteeGUID()) // correct?
518 for (Player* receiver : GetAllEventRelatives(*calendarEvent))
519 packetBuilder(receiver);
520 }
521}
522
523void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) const
524{
525 auto packetBuilder = [&](Player const* receiver)
526 {
528 packet.ClearPending = calendarEvent.GetOwnerGUID() == receiver->GetGUID();
529 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
530 packet.Date += receiver->GetSession()->GetTimezoneOffset();
531 packet.Description = calendarEvent.GetDescription();
532 packet.EventClubID = calendarEvent.GetGuildId();
533 packet.EventID = calendarEvent.GetEventId();
534 packet.EventName = calendarEvent.GetTitle();
535 packet.EventType = calendarEvent.GetType();
536 packet.Flags = calendarEvent.GetFlags();
537 packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ?
538 if (calendarEvent.GetLockDate())
539 packet.LockDate += receiver->GetSession()->GetTimezoneOffset();
540 packet.OriginalDate.SetUtcTimeFromUnixTime(originalDate);
541 packet.OriginalDate += receiver->GetSession()->GetTimezoneOffset();
542 packet.TextureID = calendarEvent.GetTextureId();
543
544 receiver->SendDirectMessage(packet.Write());
545 };
546
547 for (Player* receiver : GetAllEventRelatives(calendarEvent))
548 packetBuilder(receiver);
549}
550
551void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
552{
553 auto packetBuilder = [&](Player const* receiver)
554 {
556 packet.ClearPending = invite.GetInviteeGUID() == receiver->GetGUID();
557 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
558 packet.Date += receiver->GetSession()->GetTimezoneOffset();
559 packet.EventID = calendarEvent.GetEventId();
560 packet.Flags = calendarEvent.GetFlags();
561 packet.InviteGuid = invite.GetInviteeGUID();
563 packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset();
564 packet.Status = invite.GetStatus();
565
566 receiver->SendDirectMessage(packet.Write());
567 };
568
569 for (Player* receiver : GetAllEventRelatives(calendarEvent))
570 packetBuilder(receiver);
571}
572
574{
575 auto packetBuilder = [&](Player const* receiver)
576 {
578 packet.ClearPending = calendarEvent.GetOwnerGUID() == receiver->GetGUID();
579 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
580 packet.Date += receiver->GetSession()->GetTimezoneOffset();
581 packet.EventID = calendarEvent.GetEventId();
582
583 receiver->SendDirectMessage(packet.Write());
584 };
585
586 for (Player* receiver : GetAllEventRelatives(calendarEvent))
587 packetBuilder(receiver);
588}
589
591{
593 packet.ClearPending = true; // FIXME
594 packet.EventID = calendarEvent.GetEventId();
595 packet.Flags = flags;
596 packet.InviteGuid = invite.GetInviteeGUID();
597
598 SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
599}
600
602{
604 packet.ClearPending = true; // FIXME
605 packet.EventID = calendarEvent.GetEventId();
606 packet.InviteGuid = invite.GetInviteeGUID();
607 packet.Status = invite.GetStatus();
608
609 SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
610}
611
612void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
613{
614 auto packetBuilder = [&](Player const* receiver)
615 {
617 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
618 packet.Date += receiver->GetSession()->GetTimezoneOffset();
619 packet.EventID = calendarEvent.GetEventId();
620 packet.EventName = calendarEvent.GetTitle();
621 packet.EventType = calendarEvent.GetType();
622 packet.Flags = calendarEvent.GetFlags();
623 packet.InviteID = invite.GetInviteId();
624 packet.InvitedByGuid = invite.GetSenderGUID();
625 packet.ModeratorStatus = invite.GetRank();
626 packet.OwnerGuid = calendarEvent.GetOwnerGUID();
627 packet.Status = invite.GetStatus();
628 packet.TextureID = calendarEvent.GetTextureId();
629 packet.EventClubID = calendarEvent.GetGuildId();
630
631 receiver->SendDirectMessage(packet.Write());
632 };
633
634 if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
635 {
636 if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()))
637 guild->BroadcastWorker(packetBuilder);
638 }
639 else if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
640 packetBuilder(player);
641}
642
643void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) const
644{
646 if (!player)
647 return;
648
650 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
651 packet.Date += player->GetSession()->GetTimezoneOffset();
652 packet.Description = calendarEvent.GetDescription();
653 packet.EventID = calendarEvent.GetEventId();
654 packet.EventName = calendarEvent.GetTitle();
655 packet.EventType = sendType;
656 packet.Flags = calendarEvent.GetFlags();
657 packet.GetEventType = calendarEvent.GetType();
658 packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ?
659 if (calendarEvent.GetLockDate())
660 packet.LockDate += player->GetSession()->GetTimezoneOffset();
661 packet.OwnerGuid = calendarEvent.GetOwnerGUID();
662 packet.TextureID = calendarEvent.GetTextureId();
663 packet.EventClubID = calendarEvent.GetGuildId();
664
665 if (CalendarInviteStore const* eventInviteeList = Trinity::Containers::MapGetValuePtr(_invites, calendarEvent.GetEventId()))
666 {
667 for (CalendarInvite const* calendarInvite : *eventInviteeList)
668 {
669 ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID();
670 Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid);
671
672 uint8 inviteeLevel = invitee ? invitee->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(inviteeGuid);
673 ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : sCharacterCache->GetCharacterGuildIdByGuid(inviteeGuid);
674
676 inviteInfo.Guid = inviteeGuid;
677 inviteInfo.Level = inviteeLevel;
678 inviteInfo.Status = calendarInvite->GetStatus();
679 inviteInfo.Moderator = calendarInvite->GetRank();
680 inviteInfo.InviteType = calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId;
681 inviteInfo.InviteID = calendarInvite->GetInviteId();
682 inviteInfo.ResponseTime.SetUtcTimeFromUnixTime(calendarInvite->GetResponseTime());
683 inviteInfo.ResponseTime += player->GetSession()->GetTimezoneOffset();
684 inviteInfo.Notes = calendarInvite->GetNote();
685
686 packet.Invites.push_back(inviteInfo);
687 }
688 }
689
690 player->SendDirectMessage(packet.Write());
691}
692
694{
696 {
698 packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
699 packet.Date += player->GetSession()->GetTimezoneOffset();
700 packet.EventID = calendarEvent.GetEventId();
701 packet.Flags = calendarEvent.GetFlags();
702 packet.Status = status;
703
704 player->SendDirectMessage(packet.Write());
705 }
706}
707
709{
711 player->SendDirectMessage(WorldPackets::Calendar::CalendarClearPendingAction().Write());
712}
713
714void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/) const
715{
717 {
719 packet.Command = 1; // FIXME
720 packet.Result = err;
721
722 switch (err)
723 {
727 packet.Name = param;
728 break;
729 default:
730 break;
731 }
732
733 player->SendDirectMessage(packet.Write());
734 }
735}
736
737void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent) const
738{
739 for (Player* player : GetAllEventRelatives(calendarEvent))
740 player->SendDirectMessage(packet);
741}
742
743std::vector<Player*> CalendarMgr::GetAllEventRelatives(CalendarEvent const& calendarEvent) const
744{
745 std::vector<Player*> relatedPlayers;
746
747 // Send packet to all guild members
748 if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
749 {
750 if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()))
751 {
752 auto memberCollector = [&](Player* player) { relatedPlayers.push_back(player); };
753 guild->BroadcastWorker(memberCollector);
754 }
755 }
756
757 // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them)
758 if (auto itr =_invites.find(calendarEvent.GetEventId()); itr != _invites.end())
759 {
760 CalendarInviteStore invites = itr->second;
761 for (CalendarInvite const* invite : invites)
762 if (Player* player = ObjectAccessor::FindConnectedPlayer(invite->GetInviteeGUID()))
763 if (!calendarEvent.IsGuildEvent() || player->GetGuildId() != calendarEvent.GetGuildId())
764 relatedPlayers.push_back(player);
765 }
766
767 return relatedPlayers;
768}
std::set< CalendarEvent * > CalendarEventStore
Definition: CalendarMgr.h:294
#define sCalendarMgr
Definition: CalendarMgr.h:370
CalendarError
Definition: CalendarMgr.h:95
@ CALENDAR_ERROR_OTHER_INVITES_EXCEEDED
Definition: CalendarMgr.h:100
@ CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S
Definition: CalendarMgr.h:106
@ CALENDAR_ERROR_IGNORING_YOU_S
Definition: CalendarMgr.h:109
@ CALENDAR_ERROR_EVENT_INVALID
Definition: CalendarMgr.h:102
CalendarModerationRank
Definition: CalendarMgr.h:49
@ CALENDAR_RANK_PLAYER
Definition: CalendarMgr.h:50
@ CALENDAR_FLAG_WITHOUT_INVITES
Definition: CalendarMgr.h:44
@ CALENDAR_FLAG_GUILD_EVENT
Definition: CalendarMgr.h:45
std::vector< CalendarInvite * > CalendarInviteStore
Definition: CalendarMgr.h:293
CalendarSendEventType
Definition: CalendarMgr.h:56
CalendarEventType
Definition: CalendarMgr.h:63
CalendarInviteStatus
Definition: CalendarMgr.h:81
@ CALENDAR_STATUS_TENTATIVE
Definition: CalendarMgr.h:90
@ CALENDAR_STATUS_NOT_SIGNED_UP
Definition: CalendarMgr.h:89
@ CALENDAR_STATUS_INVITED
Definition: CalendarMgr.h:82
@ CALENDAR_STATUS_REMOVED
Definition: CalendarMgr.h:91
@ CALENDAR_OLD_EVENTS_DELETION_TIME
Definition: CalendarMgr.h:138
#define sCharacterCache
@ CHAR_REP_CALENDAR_EVENT
@ CHAR_DEL_CALENDAR_INVITE
@ CHAR_DEL_CALENDAR_EVENT
@ CHAR_REP_CALENDAR_INVITE
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
#define UI64LIT(N)
Definition: Define.h:127
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
#define sGuildMgr
Definition: GuildMgr.h:70
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
Definition: Mail.h:55
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:57
uint32 getMSTime()
Definition: Timer.h:33
void SendCalendarEvent(ObjectGuid guid, CalendarEvent const &calendarEvent, CalendarSendEventType sendType) const
void UpdateEvent(CalendarEvent *calendarEvent)
void SendCalendarEventInviteRemove(CalendarEvent const &calendarEvent, CalendarInvite const &invite, uint32 flags) const
uint64 _maxInviteId
Definition: CalendarMgr.h:309
void SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const &calendarEvent, CalendarInviteStatus status) const
uint64 GetFreeEventId()
void SendCalendarEventUpdateAlert(CalendarEvent const &calendarEvent, time_t originalDate) const
void FreeInviteId(uint64 id)
CalendarEventInviteStore _invites
Definition: CalendarMgr.h:304
void SendCalendarEventStatus(CalendarEvent const &calendarEvent, CalendarInvite const &invite) const
void UpdateInvite(CalendarInvite *invite, CharacterDatabaseTransaction trans=nullptr)
std::deque< uint64 > _freeEventIds
Definition: CalendarMgr.h:306
static CalendarMgr * instance()
Definition: CalendarMgr.cpp:61
uint32 GetPlayerNumPending(ObjectGuid guid)
std::vector< Player * > GetAllEventRelatives(CalendarEvent const &calendarEvent) const
void SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const *param=nullptr) const
void RemovePlayerGuildEventsAndSignups(ObjectGuid guid, ObjectGuid::LowType guildId)
void FreeEventId(uint64 id)
uint64 GetFreeInviteId()
CalendarEventStore _events
Definition: CalendarMgr.h:303
CalendarInviteStore GetEventInvites(uint64 eventId) const
void AddInvite(CalendarEvent *calendarEvent, CalendarInvite *invite, CharacterDatabaseTransaction trans=nullptr)
void SendCalendarClearPendingAction(ObjectGuid guid) const
void RemoveInvite(uint64 inviteId, uint64 eventId, ObjectGuid remover)
void RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
CalendarEventStore GetPlayerEvents(ObjectGuid guid) const
CalendarInvite * GetInvite(uint64 inviteId) const
void SendPacketToAllEventRelatives(WorldPacket const *packet, CalendarEvent const &calendarEvent) const
void LoadFromDB()
Definition: CalendarMgr.cpp:67
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents=false) const
uint64 _maxEventId
Definition: CalendarMgr.h:308
std::deque< uint64 > _freeInviteIds
Definition: CalendarMgr.h:307
void SendCalendarEventInviteAlert(CalendarEvent const &calendarEvent, CalendarInvite const &invite) const
CalendarEvent * GetEvent(uint64 eventId) const
void AddEvent(CalendarEvent *calendarEvent, CalendarSendEventType sendType)
CalendarInviteStore GetPlayerInvites(ObjectGuid guid) const
void RemoveEvent(uint64 eventId, ObjectGuid remover)
void SendCalendarEventInvite(CalendarInvite const &invite) const
void DeleteOldEvents()
void SendCalendarEventRemovedAlert(CalendarEvent const &calendarEvent) const
void SendCalendarEventModeratorStatusAlert(CalendarEvent const &calendarEvent, CalendarInvite const &invite) const
CalendarEventStore GetGuildEvents(ObjectGuid::LowType guildId) const
Class used to access individual fields of database query result.
Definition: Field.h:90
std::string GetString() const
Definition: Field.cpp:118
int64 GetInt64() const
Definition: Field.cpp:86
uint64 GetUInt64() const
Definition: Field.cpp:78
uint32 GetUInt32() const
Definition: Field.cpp:62
int32 GetInt32() const
Definition: Field.cpp:70
Definition: Guild.h:329
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition: Mail.cpp:192
LowType GetCounter() const
Definition: ObjectGuid.h:293
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
bool IsEmpty() const
Definition: ObjectGuid.h:319
std::string ToString() const
Definition: ObjectGuid.cpp:554
uint64 LowType
Definition: ObjectGuid.h:278
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
WorldSession * GetSession() const
Definition: Player.h:2101
ObjectGuid::LowType GetGuildId() const
Definition: Player.h:1993
void setInt32(const uint8 index, const int32 value)
void setUInt8(const uint8 index, const uint8 value)
void setInt64(const uint8 index, const int64 value)
void setUInt32(const uint8 index, const uint32 value)
void setString(const uint8 index, const std::string &value)
void setUInt64(const uint8 index, const uint64 value)
uint8 GetLevel() const
Definition: Unit.h:746
std::vector< CalendarEventInviteInfo > Invites
WorldPacket const * Write() override
Minutes GetTimezoneOffset() const
uint32 GetPackedTime() const
Definition: WowTime.cpp:23
void SetUtcTimeFromUnixTime(std::time_t unixTime)
Definition: WowTime.cpp:86
time_t GetGameTime()
Definition: GameTime.cpp:44
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition: MapUtils.h:29
std::string ToString(Type &&val, Params &&... params)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
Definition: StringFormat.h:38
uint64 _eventId
Definition: CalendarMgr.h:282
std::string BuildCalendarMailSubject(ObjectGuid remover) const
bool IsGuildAnnouncement() const
Definition: CalendarMgr.h:269
CalendarEventType GetType() const
Definition: CalendarMgr.h:257
ObjectGuid GetOwnerGUID() const
Definition: CalendarMgr.h:245
bool IsGuildEvent() const
Definition: CalendarMgr.h:268
time_t GetDate() const
Definition: CalendarMgr.h:263
uint64 GetEventId() const
Definition: CalendarMgr.h:242
ObjectGuid::LowType GetGuildId() const
Definition: CalendarMgr.h:248
std::string _title
Definition: CalendarMgr.h:289
int32 GetTextureId() const
Definition: CalendarMgr.h:260
time_t GetLockDate() const
Definition: CalendarMgr.h:273
std::string GetTitle() const
Definition: CalendarMgr.h:251
std::string GetDescription() const
Definition: CalendarMgr.h:254
std::string BuildCalendarMailBody(Player const *invitee) const
uint32 GetFlags() const
Definition: CalendarMgr.h:266
CalendarModerationRank GetRank() const
Definition: CalendarMgr.h:195
CalendarInviteStatus GetStatus() const
Definition: CalendarMgr.h:192
uint64 GetInviteId() const
Definition: CalendarMgr.h:174
uint64 _inviteId
Definition: CalendarMgr.h:198
std::string GetNote() const
Definition: CalendarMgr.h:189
time_t GetResponseTime() const
Definition: CalendarMgr.h:186
uint64 GetEventId() const
Definition: CalendarMgr.h:177
ObjectGuid GetSenderGUID() const
Definition: CalendarMgr.h:180
ObjectGuid GetInviteeGUID() const
Definition: CalendarMgr.h:183