TrinityCore
Loading...
Searching...
No Matches
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
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
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
#define sCalendarMgr
CalendarError
Definition CalendarMgr.h:95
@ CALENDAR_ERROR_OTHER_INVITES_EXCEEDED
@ CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S
@ CALENDAR_ERROR_IGNORING_YOU_S
@ CALENDAR_ERROR_EVENT_INVALID
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
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
#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.
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
#define UI64LIT(N)
Definition Define.h:139
uint32_t uint32
Definition Define.h:154
uint16 flags
#define sGuildMgr
Definition GuildMgr.h:76
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
@ 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
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
void SendCalendarEventStatus(CalendarEvent const &calendarEvent, CalendarInvite const &invite) const
void UpdateInvite(CalendarInvite *invite, CharacterDatabaseTransaction trans=nullptr)
std::deque< uint64 > _freeEventIds
static CalendarMgr * instance()
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
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()
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents=false) const
uint64 _maxEventId
std::deque< uint64 > _freeInviteIds
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:94
uint64 GetUInt64() const noexcept
Definition Field.cpp:71
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
int32 GetInt32() const noexcept
Definition Field.cpp:64
std::string GetString() const noexcept
Definition Field.cpp:113
int64 GetInt64() const noexcept
Definition Field.cpp:78
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:195
LowType GetCounter() const
Definition ObjectGuid.h:336
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
uint64 LowType
Definition ObjectGuid.h:321
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
WorldSession * GetSession() const
Definition Player.h:2272
ObjectGuid::LowType GetGuildId() const
Definition Player.h:2164
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setInt64(uint8 index, int64 value)
void setUInt64(uint8 index, uint64 value)
void setInt32(uint8 index, int32 value)
void setUInt8(uint8 index, uint8 value)
uint8 GetLevel() const
Definition Unit.h:757
std::vector< CalendarEventInviteInfo > Invites
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:52
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:37
std::string ToString(Type &&val, Params &&... params)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
std::string BuildCalendarMailSubject(ObjectGuid remover) const
bool IsGuildAnnouncement() const
CalendarEventType GetType() const
ObjectGuid GetOwnerGUID() const
bool IsGuildEvent() const
time_t GetDate() const
uint64 GetEventId() const
ObjectGuid::LowType GetGuildId() const
std::string _title
int32 GetTextureId() const
time_t GetLockDate() const
std::string GetTitle() const
std::string GetDescription() const
std::string BuildCalendarMailBody(Player const *invitee) const
uint32 GetFlags() const
CalendarModerationRank GetRank() const
CalendarInviteStatus GetStatus() const
uint64 GetInviteId() const
std::string GetNote() const
time_t GetResponseTime() const
uint64 GetEventId() const
ObjectGuid GetSenderGUID() const
ObjectGuid GetInviteeGUID() const