TrinityCore
Loading...
Searching...
No Matches
CalendarHandler.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/*
19----- Opcodes Not Used yet -----
20
21SMSG_CALENDAR_EVENT_INVITE_NOTES [ packguid(Invitee), uint64(inviteId), string(Text), Boolean(Unk) ]
22?CMSG_CALENDAR_EVENT_INVITE_NOTES [ uint32(unk1), uint32(unk2), uint32(unk3), uint32(unk4), uint32(unk5) ]
23SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT [ uint64(inviteId), string(Text) ]
24SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT [ uint64(eventId), uint32(eventTime), uint32(unkFlag), uint8(deletePending) ]
25SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save)
26
27@todo
28
29Finish complains' handling - what to do with received complains and how to respond?
30Find out what to do with all "not used yet" opcodes
31Correct errors sending (event/invite not found, invites exceeded, event already passed, permissions etc.)
32Fix locked events to be displayed properly and response time shouldn't be shown for people that haven't respond yet
33Copied events should probably have a new owner
34
35*/
36
37#include "WorldSession.h"
38#include "ArenaTeamMgr.h"
39#include "CalendarMgr.h"
40#include "CalendarPackets.h"
41#include "CharacterCache.h"
42#include "DatabaseEnv.h"
43#include "DBCStores.h"
44#include "GameEventMgr.h"
45#include "GameTime.h"
46#include "Guild.h"
47#include "GuildMgr.h"
48#include "InstanceSaveMgr.h"
49#include "Log.h"
50#include "ObjectAccessor.h"
51#include "ObjectMgr.h"
52#include "Opcodes.h"
53#include "Player.h"
54#include "SocialMgr.h"
55#include "World.h"
56
58{
59 ObjectGuid guid = _player->GetGUID();
60 TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [{}]", guid.ToString());
61
62 time_t currTime = GameTime::GetGameTime();
63
66 packet.ServerNow = currTime;
67 packet.RaidOrigin = 1135753200; // Constant date, unk (28.12.2005 07:00)
68
69 CalendarInviteStore playerInvites = sCalendarMgr->GetPlayerInvites(guid);
70 for (CalendarInvite const* invite : playerInvites)
71 {
72 WorldPackets::Calendar::CalendarSendCalendarInviteInfo& inviteInfo = packet.Invites.emplace_back();
73 inviteInfo.EventID = invite->GetEventId();
74 inviteInfo.InviteID = invite->GetInviteId();
75 inviteInfo.InviterGuid = invite->GetSenderGUID();
76 inviteInfo.Status = invite->GetStatus();
77 inviteInfo.Moderator = invite->GetRank();
78 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(invite->GetEventId()))
79 inviteInfo.InviteType = calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == _player->GetGuildId();
80 }
81
82 CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid);
83 for (CalendarEvent const* event : playerEvents)
84 {
85 WorldPackets::Calendar::CalendarSendCalendarEventInfo& eventInfo = packet.Events.emplace_back();
86 eventInfo.EventID = event->GetEventId();
87 eventInfo.Date.SetUtcTimeFromUnixTime(event->GetDate());
88 eventInfo.Date += GetTimezoneOffset();
89 eventInfo.EventName = event->GetTitle();
90 eventInfo.EventType = event->GetType();
91 eventInfo.Flags = event->GetFlags();
92 eventInfo.OwnerGuid = event->GetOwnerGUID();
93 eventInfo.TextureID = event->GetTextureId();
94 }
95
96 for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
97 {
99 for (Player::BoundInstancesMap::const_iterator itr = boundInstances.begin(); itr != boundInstances.end(); ++itr)
100 {
101 if (itr->second.perm)
102 {
103 InstanceSave const* save = itr->second.save;
105 lockoutInfo.MapID = save->GetMapId();
106 lockoutInfo.DifficultyID = save->GetDifficulty();
107 lockoutInfo.ExpireTime = int32(std::max(save->GetResetTime() - currTime, time_t(SI64LIT(0))));
108 lockoutInfo.InstanceID = save->GetInstanceId();
109 }
110 }
111 }
112
113 std::set<uint32> sentMaps;
114
115 ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap();
116 for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
117 {
118 uint32 mapId = PAIR32_LOPART(itr->first);
119 if (sentMaps.find(mapId) != sentMaps.end())
120 continue;
121
122 MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
123 if (!mapEntry || !mapEntry->IsRaid())
124 continue;
125
126 sentMaps.insert(mapId);
127
129 reset.MapID = mapId;
130 reset.Duration = itr->second - currTime;
131 reset.Offset = 0; // Never seen anything else in sniffs - still unknown
132 }
133
134 for (uint32 entry : sGameEventMgr->modifiedHolidays)
135 {
136 HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
137
138 WorldPackets::Calendar::CalendarSendCalendarHolidayInfo& holidayInfo = packet.Holidays.emplace_back();
139 holidayInfo.HolidayID = holiday->ID;
140 holidayInfo.Region = holiday->Region;
141 holidayInfo.Looping = holiday->Looping;
142 holidayInfo.Priority = holiday->Priority;
143 holidayInfo.FilterType = holiday->CalendarFilterType;
144
145 for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
146 holidayInfo.Date[j].SetPackedTime(holiday->Date[j]);
147
148 for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
149 holidayInfo.Duration[j] = holiday->Duration[j];
150
151 for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
152 holidayInfo.CalendarFlags[j] = holiday->CalendarFlags[j];
153
154 holidayInfo.TextureFilename = holiday->TextureFilename;
155 }
156
157 SendPacket(packet.Write());
158}
159
161{
162 TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), calendarGetEvent.EventID);
163
164 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarGetEvent.EventID))
165 sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
166 else
167 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
168}
169
171{
172 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
173 guild->MassInviteToEvent(this, calendarGuildFilter.MinLevel, calendarGuildFilter.MaxLevel, calendarGuildFilter.MaxRankOrder);
174
175 TC_LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]",
176 calendarGuildFilter.MinLevel, calendarGuildFilter.MaxLevel, calendarGuildFilter.MaxRankOrder);
177}
178
180{
181 TC_LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
182
183 if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(calendarArenaTeam.ArenaTeamId))
184 team->MassInviteToEvent(this);
185}
186
188{
189 ObjectGuid guid = _player->GetGUID();
190
191 calendarAddEvent.Time -= GetTimezoneOffset();
192 calendarAddEvent.LockDate -= GetTimezoneOffset();
193
194 // prevent events in the past
195 if (calendarAddEvent.Time < *GameTime::GetUtcWowTime())
196 {
197 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
198 return;
199 }
200
201 // If the event is a guild event, check if the player is in a guild
202 if (CalendarEvent::IsGuildEvent(calendarAddEvent.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.Flags))
203 {
204 if (!_player->GetGuildId())
205 {
206 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
207 return;
208 }
209 }
210
211 // Check if the player reached the max number of events allowed to create
212 if (CalendarEvent::IsGuildEvent(calendarAddEvent.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.Flags))
213 {
214 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
215 {
216 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
217 return;
218 }
219 }
220 else
221 {
222 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
223 {
224 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
225 return;
226 }
227 }
228
230 {
231 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
232 return;
233 }
235
236 CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(calendarAddEvent.EventType), calendarAddEvent.TextureID,
237 calendarAddEvent.Time.GetUnixTimeFromUtcTime(), calendarAddEvent.Flags, calendarAddEvent.Title, calendarAddEvent.Description, calendarAddEvent.LockDate.GetUnixTimeFromUtcTime());
238
239 if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
240 calendarEvent->SetGuildId(_player->GetGuildId());
241
242 if (calendarEvent->IsGuildAnnouncement())
243 {
245 // WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
246 // of storage of the pointer as it will lead to memory corruption
247 sCalendarMgr->AddInvite(calendarEvent, &invite);
248 }
249 else
250 {
252 if (calendarAddEvent.Invites.size() > 1)
253 trans = CharacterDatabase.BeginTransaction();
254
255 for (uint32 i = 0; i < calendarAddEvent.Invites.size(); ++i)
256 {
257 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), calendarAddEvent.Invites[i].Guid,
258 guid, CALENDAR_DEFAULT_RESPONSE_TIME, CalendarInviteStatus(calendarAddEvent.Invites[i].Status),
259 CalendarModerationRank(calendarAddEvent.Invites[i].Moderator), "");
260 sCalendarMgr->AddInvite(calendarEvent, invite, trans);
261 }
262
263 if (calendarAddEvent.Invites.size() > 1)
264 CharacterDatabase.CommitTransaction(trans);
265 }
266
267 sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
268}
269
271{
272 calendarUpdateEvent.Time -= GetTimezoneOffset();
273 calendarUpdateEvent.LockDate -= GetTimezoneOffset();
274
275 // prevent events in the past
276 if (calendarUpdateEvent.Time < *GameTime::GetUtcWowTime())
277 return;
278
279 TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [{}] EventId [{}], "
280 "InviteId [{}] Title {}, Description {}, EventType {} "
281 "Dungeon ID {}, Time {} LockDate {}, Flags {}", _player->GetGUID().ToString(), calendarUpdateEvent.EventID, calendarUpdateEvent.ModeratorID,
282 calendarUpdateEvent.Title, calendarUpdateEvent.Description, calendarUpdateEvent.EventType, calendarUpdateEvent.TextureID,
283 calendarUpdateEvent.Time.GetUnixTimeFromUtcTime(), calendarUpdateEvent.LockDate.GetUnixTimeFromUtcTime(), calendarUpdateEvent.Flags);
284
285 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarUpdateEvent.EventID))
286 {
287 time_t oldEventTime = calendarEvent->GetDate();
288
289 calendarEvent->SetType(CalendarEventType(calendarUpdateEvent.EventType));
290 calendarEvent->SetFlags(calendarUpdateEvent.Flags);
291 calendarEvent->SetDate(calendarUpdateEvent.Time.GetUnixTimeFromUtcTime());
292 calendarEvent->SetLockDate(calendarUpdateEvent.LockDate.GetUnixTimeFromUtcTime()); // Not sure, seems constant from the little sniffs we have
293 calendarEvent->SetTextureId(calendarUpdateEvent.TextureID);
294 calendarEvent->SetTitle(calendarUpdateEvent.Title);
295 calendarEvent->SetDescription(calendarUpdateEvent.Description);
296
297 sCalendarMgr->UpdateEvent(calendarEvent);
298 sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime);
299 }
300 else
301 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
302}
303
305{
306 ObjectGuid guid = _player->GetGUID();
307 sCalendarMgr->RemoveEvent(calendarRemoveEvent.EventID, guid);
308}
309
311{
312 ObjectGuid guid = _player->GetGUID();
313
314 calendarCopyEvent.Date -= GetTimezoneOffset();
315
316 // prevent events in the past
317 if (calendarCopyEvent.Date < *GameTime::GetUtcWowTime())
318 {
319 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
320 return;
321 }
322
323 TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}",
324 guid.ToString(), calendarCopyEvent.EventID, calendarCopyEvent.ModeratorID, calendarCopyEvent.Date.GetUnixTimeFromUtcTime());
325
326 if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(calendarCopyEvent.EventID))
327 {
328 // Ensure that the player has access to the event
329 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
330 {
331 if (oldEvent->GetGuildId() != _player->GetGuildId())
332 {
333 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
334 return;
335 }
336 }
337 else
338 {
339 if (oldEvent->GetOwnerGUID() != guid)
340 {
341 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
342 return;
343 }
344 }
345
346 // Check if the player reached the max number of events allowed to create
347 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
348 {
349 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
350 {
351 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
352 return;
353 }
354 }
355 else
356 {
357 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
358 {
359 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
360 return;
361 }
362 }
363
365 {
366 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
367 return;
368 }
370
371 CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
372 newEvent->SetDate(calendarCopyEvent.Date.GetUnixTimeFromUtcTime());
373 sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
374
375 CalendarInviteStore invites = sCalendarMgr->GetEventInvites(calendarCopyEvent.EventID);
377 if (invites.size() > 1)
378 trans = CharacterDatabase.BeginTransaction();
379
380 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
381 sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId()), trans);
382
383 if (invites.size() > 1)
384 CharacterDatabase.CommitTransaction(trans);
385 // should we change owner when somebody makes a copy of event owned by another person?
386 }
387 else
388 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
389}
390
392{
393 ObjectGuid playerGuid = _player->GetGUID();
394
395 Optional<uint64> eventId;
396 if (!calendarEventInvite.Creating)
397 eventId = calendarEventInvite.EventID;
398
399 bool isSignUp = calendarEventInvite.IsSignUp;
400
401 std::string inviteeName = calendarEventInvite.Name;
402
403 if (!normalizePlayerName(calendarEventInvite.Name))
404 return;
405
406 auto createInvite = [this, playerGuid, inviteeName, eventId, isSignUp](ObjectGuid const& inviteeGuid, uint32 inviteeTeam, ObjectGuid::LowType inviteeGuildId, bool inviteeIsIngoring)
407 {
408 if (!_player || _player->GetGUID() != playerGuid)
409 return;
410
411 if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
412 {
413 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
414 return;
415 }
416
417 if (inviteeIsIngoring)
418 {
419 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, inviteeName.c_str());
420 return;
421 }
422
423 if (eventId)
424 {
425 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(*eventId))
426 {
427 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
428 {
429 // we can't invite guild members to guild events
430 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
431 return;
432 }
433
434 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), *eventId, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
435 sCalendarMgr->AddInvite(calendarEvent, invite);
436 }
437 else
438 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
439 }
440 else
441 {
442 if (isSignUp && inviteeGuildId == _player->GetGuildId())
443 {
444 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
445 return;
446 }
447
448 CalendarInvite invite(sCalendarMgr->GetFreeInviteId(), 0L, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
449 sCalendarMgr->SendCalendarEventInvite(invite);
450 }
451 };
452
453 if (Player* player = ObjectAccessor::FindConnectedPlayerByName(calendarEventInvite.Name))
454 {
455 // Invitee is online
456 createInvite(player->GetGUID(), player->GetTeam(), player->GetGuildId(), player->GetSocial()->HasIgnore(playerGuid));
457 }
458 else
459 {
460 // Invitee offline, get data from storage
461 CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByName(inviteeName);
462 if (!characterInfo)
463 {
464 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
465 return;
466 }
467
468 GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(Trinity::StringFormat("SELECT 1 FROM character_social WHERE guid = {} AND friend = {} AND (flags & {}) <> 0",
469 characterInfo->Guid.GetCounter(), playerGuid.GetCounter(), SOCIAL_FLAG_IGNORED).c_str()))
470 .WithCallback([inviteeGuid = characterInfo->Guid, inviteeTeam = Player::TeamForRace(characterInfo->Race), inviteeGuildId = characterInfo->GuildId, continuation = std::move(createInvite)](QueryResult result)
471 {
472 bool isIgnoring = result != nullptr;
473 continuation(inviteeGuid, inviteeTeam, inviteeGuildId, isIgnoring);
474 });
475 }
476}
477
479{
480 ObjectGuid guid = _player->GetGUID();
481
482 TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), calendarEventSignUp.EventID, calendarEventSignUp.Tentative);
483
484 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarEventSignUp.EventID))
485 {
486 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
487 {
488 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
489 return;
490 }
491
493 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEventSignUp.EventID, guid, guid, GameTime::GetGameTime(), status, CALENDAR_RANK_PLAYER, "");
494 sCalendarMgr->AddInvite(calendarEvent, invite);
495 sCalendarMgr->SendCalendarClearPendingAction(guid);
496 }
497 else
498 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
499}
500
502{
503 ObjectGuid guid = _player->GetGUID();
504
505 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarRSVP.EventID))
506 {
507 // I think we still should be able to remove self from locked events
508 if (calendarRSVP.Status != CALENDAR_STATUS_REMOVED && calendarEvent->IsLocked())
509 {
510 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
511 return;
512 }
513
514 if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarRSVP.InviteID))
515 {
516 invite->SetStatus(CalendarInviteStatus(calendarRSVP.Status));
517 invite->SetResponseTime(GameTime::GetGameTime());
518
519 sCalendarMgr->UpdateInvite(invite);
520 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
521 sCalendarMgr->SendCalendarClearPendingAction(guid);
522 }
523 else
524 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
525 }
526 else
527 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
528}
529
531{
532 ObjectGuid guid = _player->GetGUID();
533
534 TC_LOG_DEBUG("network", "CMSG_CALENDAR_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
535 guid.ToString(), calendarRemoveInvite.EventID, calendarRemoveInvite.ModeratorID, calendarRemoveInvite.Guid.ToString(), calendarRemoveInvite.InviteID);
536
537 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarRemoveInvite.EventID))
538 {
539 if (calendarEvent->GetOwnerGUID() == calendarRemoveInvite.Guid)
540 {
541 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
542 return;
543 }
544
545 sCalendarMgr->RemoveInvite(calendarRemoveInvite.InviteID, calendarRemoveInvite.EventID, guid);
546 }
547 else
548 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
549}
550
552{
553 ObjectGuid guid = _player->GetGUID();
554
555 TC_LOG_DEBUG("network", "CMSG_CALENDAR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], status {}",
556 guid.ToString(), calendarStatus.EventID, calendarStatus.ModeratorID, calendarStatus.Guid.ToString(), calendarStatus.InviteID, calendarStatus.Status);
557
558 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarStatus.EventID))
559 {
560 if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarStatus.InviteID))
561 {
562 invite->SetStatus((CalendarInviteStatus)calendarStatus.Status);
563
564 sCalendarMgr->UpdateInvite(invite);
565 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
566 sCalendarMgr->SendCalendarClearPendingAction(calendarStatus.Guid);
567 }
568 else
569 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
570 }
571 else
572 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
573}
574
576{
577 ObjectGuid guid = _player->GetGUID();
578
579 TC_LOG_DEBUG("network", "CMSG_CALENDAR_MODERATOR_STATUS [{}] EventID [{}] ModeratorID [{}], Invitee ([{}] InviteID: [{}], Status {}",
580 guid.ToString(), calendarModeratorStatus.EventID, calendarModeratorStatus.ModeratorID, calendarModeratorStatus.Guid.ToString(), calendarModeratorStatus.InviteID,
581 calendarModeratorStatus.Status);
582
583 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarModeratorStatus.EventID))
584 {
585 if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarModeratorStatus.InviteID))
586 {
587 invite->SetRank(CalendarModerationRank(calendarModeratorStatus.Status));
588 sCalendarMgr->UpdateInvite(invite);
589 sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
590 }
591 else
592 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
593 }
594 else
595 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
596}
597
599{
600 ObjectGuid guid = _player->GetGUID();
601 TC_LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}] InviteId [{}]", guid.ToString(), calendarComplain.EventID,
602 calendarComplain.InvitedByGUID.ToString(), calendarComplain.InviteID);
603
604 // what to do with complains?
605}
606
608{
609 ObjectGuid guid = _player->GetGUID();
610 uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
611
612 TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
613
615}
616
618{
619 TC_LOG_DEBUG("network", "CMSG_SET_SAVED_INSTANCE_EXTEND - MapId: {}, Difficulty: {}, ToggleExtend: {}", setSavedInstanceExtend.MapID, setSavedInstanceExtend.DifficultyID, setSavedInstanceExtend.Extend ? "On" : "Off");
620
621 if (Player* player = GetPlayer())
622 {
623 InstancePlayerBind* instanceBind = player->GetBoundInstance(setSavedInstanceExtend.MapID, Difficulty(setSavedInstanceExtend.DifficultyID), setSavedInstanceExtend.Extend); // include expired instances if we are toggling extend on
624 if (!instanceBind || !instanceBind->save || !instanceBind->perm)
625 return;
626
627 BindExtensionState newState;
628 if (!setSavedInstanceExtend.Extend || instanceBind->extendState == EXTEND_STATE_EXPIRED)
629 newState = EXTEND_STATE_NORMAL;
630 else
631 newState = EXTEND_STATE_EXTENDED;
632
633 player->BindToInstance(instanceBind->save, true, newState, false);
634 }
635
636 /*
637 InstancePlayerBind* instanceBind = _player->GetBoundInstance(mapId, Difficulty(difficulty));
638 if (!instanceBind || !instanceBind->save)
639 return;
640
641 InstanceSave* save = instanceBind->save;
642 // http://www.wowwiki.com/Instance_Lock_Extension
643 // SendCalendarRaidLockoutUpdated(save);
644 */
645}
646
647// ----------------------------------- SEND ------------------------------------
648
650{
652 calendarRaidLockoutAdded.InstanceID = save->GetInstanceId();
653 calendarRaidLockoutAdded.ServerTime = *GameTime::GetWowTime();
654 calendarRaidLockoutAdded.MapID = int32(save->GetMapId());
655 calendarRaidLockoutAdded.DifficultyID = save->GetDifficulty();
656 calendarRaidLockoutAdded.TimeRemaining = int32(save->GetResetTime() - GameTime::GetGameTime());
657 SendPacket(calendarRaidLockoutAdded.Write());
658}
659
661{
663 calendarRaidLockoutRemoved.InstanceID = save->GetInstanceId();
664 calendarRaidLockoutRemoved.MapID = int32(save->GetMapId());
665 calendarRaidLockoutRemoved.DifficultyID = save->GetDifficulty();
666 calendarRaidLockoutRemoved.TimeRemaining = int32(save->GetResetTime() - GameTime::GetGameTime());
667 SendPacket(calendarRaidLockoutRemoved.Write());
668}
669
671{
672 if (!save)
673 return;
674
675 ObjectGuid guid = _player->GetGUID();
676 TC_LOG_DEBUG("network", "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [{}] Map: {}, Difficulty {}",
677 guid.ToString(), save->GetMapId(), static_cast<uint32>(save->GetDifficulty()));
678
680 calendarRaidLockoutUpdated.ServerTime = *GameTime::GetWowTime();
681 calendarRaidLockoutUpdated.MapID = save->GetMapId();
682 calendarRaidLockoutUpdated.DifficultyID = save->GetDifficulty();
683 calendarRaidLockoutUpdated.OldTimeRemaining = 0;
684 calendarRaidLockoutUpdated.NewTimeRemaining = std::max(save->GetResetTime() - GameTime::GetGameTime(), time_t(SI64LIT(0)));
685 SendPacket(calendarRaidLockoutUpdated.Write());
686}
#define sArenaTeamMgr
std::set< CalendarEvent * > CalendarEventStore
#define sCalendarMgr
@ CALENDAR_ERROR_INTERNAL
@ CALENDAR_ERROR_NO_INVITE
@ CALENDAR_ERROR_EVENT_PASSED
@ CALENDAR_ERROR_EVENT_LOCKED
@ CALENDAR_ERROR_NOT_ALLIED
@ CALENDAR_ERROR_EVENTS_EXCEEDED
Definition CalendarMgr.h:97
@ CALENDAR_ERROR_NO_GUILD_INVITES
@ CALENDAR_ERROR_DELETE_CREATOR_FAILED
@ CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED
Definition CalendarMgr.h:96
@ CALENDAR_ERROR_IGNORING_YOU_S
@ CALENDAR_ERROR_PLAYER_NOT_FOUND
@ CALENDAR_ERROR_EVENT_INVALID
@ CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD
#define CALENDAR_DEFAULT_RESPONSE_TIME
CalendarModerationRank
Definition CalendarMgr.h:49
@ CALENDAR_RANK_PLAYER
Definition CalendarMgr.h:50
std::vector< CalendarInvite * > CalendarInviteStore
@ CALENDAR_SENDTYPE_GET
Definition CalendarMgr.h:57
@ CALENDAR_SENDTYPE_COPY
Definition CalendarMgr.h:59
@ CALENDAR_SENDTYPE_ADD
Definition CalendarMgr.h:58
CalendarEventType
Definition CalendarMgr.h:63
CalendarInviteStatus
Definition CalendarMgr.h:80
@ CALENDAR_STATUS_TENTATIVE
Definition CalendarMgr.h:89
@ CALENDAR_STATUS_NOT_SIGNED_UP
Definition CalendarMgr.h:88
@ CALENDAR_STATUS_INVITED
Definition CalendarMgr.h:81
@ CALENDAR_STATUS_SIGNED_UP
Definition CalendarMgr.h:87
@ CALENDAR_STATUS_REMOVED
Definition CalendarMgr.h:90
@ CALENDAR_MAX_EVENTS
@ CALENDAR_MAX_GUILD_EVENTS
@ CALENDAR_CREATE_EVENT_COOLDOWN
#define sCharacterCache
Difficulty
Definition DBCEnums.h:279
#define MAX_DIFFICULTY
Definition DBCEnums.h:296
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
#define MAX_HOLIDAY_FLAGS
#define MAX_HOLIDAY_DURATIONS
#define MAX_HOLIDAY_DATES
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
#define SI64LIT(N)
Definition Define.h:121
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define sGameEventMgr
#define sGuildMgr
Definition GuildMgr.h:59
#define sInstanceSaveMgr
std::unordered_map< uint32, time_t > ResetTimeByMapDifficultyMap
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
uint16 PAIR32_LOPART(uint32 x)
bool normalizePlayerName(std::string &name)
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
BindExtensionState
Definition Player.h:774
@ EXTEND_STATE_NORMAL
Definition Player.h:776
@ EXTEND_STATE_EXTENDED
Definition Player.h:777
@ EXTEND_STATE_EXPIRED
Definition Player.h:775
@ SOCIAL_FLAG_IGNORED
Definition SocialMgr.h:41
Definition Guild.h:284
uint32 GetInstanceId() const
uint32 GetMapId() const
Difficulty GetDifficulty() const
time_t GetResetTime() const
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
std::string ToString() const
uint32 LowType
Definition ObjectGuid.h:142
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetTeam() const
Definition Player.h:1832
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition Player.h:2139
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:6269
BoundInstancesMap & GetBoundInstances(Difficulty difficulty)
Definition Player.h:2148
ObjectGuid::LowType GetGuildId() const
Definition Player.h:1620
size_type size() const
Array< CalendarAddEventInviteInfo, CALENDAR_MAX_INVITES > Invites
std::vector< CalendarSendCalendarInviteInfo > Invites
std::vector< CalendarSendCalendarHolidayInfo > Holidays
std::vector< CalendarSendCalendarRaidResetInfo > RaidResets
std::vector< CalendarSendCalendarRaidLockoutInfo > RaidLockouts
std::vector< CalendarSendCalendarEventInfo > Events
void HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyEvent &calendarCopyEvent)
void HandleCalendarEventRsvp(WorldPackets::Calendar::CalendarRSVP &calendarRSVP)
void HandleCalendarGuildFilter(WorldPackets::Calendar::CalendarGuildFilter &calendarGuildFilter)
time_t GetCalendarEventCreationCooldown() const
void HandleCalendarGetEvent(WorldPackets::Calendar::CalendarGetEvent &calendarGetEvent)
void HandleCalendarEventStatus(WorldPackets::Calendar::CalendarStatus &calendarStatus)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandleCalendarEventRemoveInvite(WorldPackets::Calendar::CalendarRemoveInvite &calendarRemoveInvite)
void HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGetCalendar &calendarGetCalendar)
void SendCalendarRaidLockoutUpdated(InstanceSave const *save)
void HandleCalendarComplain(WorldPackets::Calendar::CalendarComplain &calendarComplain)
void HandleSetSavedInstanceExtend(WorldPackets::Calendar::SetSavedInstanceExtend &setSavedInstanceExtend)
Minutes GetTimezoneOffset() const
Player * GetPlayer() const
void HandleCalendarArenaTeam(WorldPackets::Calendar::CalendarArenaTeam &calendarArenaTeam)
QueryCallbackProcessor & GetQueryProcessor()
void HandleCalendarEventSignup(WorldPackets::Calendar::CalendarEventSignUp &calendarEventSignUp)
void SendCalendarRaidLockoutAdded(InstanceSave const *save)
void HandleCalendarUpdateEvent(WorldPackets::Calendar::CalendarUpdateEvent &calendarUpdateEvent)
void HandleCalendarEventModeratorStatus(WorldPackets::Calendar::CalendarModeratorStatusQuery &calendarModeratorStatus)
void SendCalendarRaidLockoutRemoved(InstanceSave const *save)
void SetCalendarEventCreationCooldown(time_t cooldown)
Player * _player
void HandleCalendarEventInvite(WorldPackets::Calendar::CalendarInvite &calendarEventInvite)
void HandleCalendarRemoveEvent(WorldPackets::Calendar::CalendarRemoveEvent &calendarRemoveEvent)
void HandleCalendarGetNumPending(WorldPackets::Calendar::CalendarGetNumPending &calendarGetNumPending)
void HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEvent &calendarAddEvent)
std::time_t GetUnixTimeFromUtcTime() const
Definition WowTime.cpp:65
void SetUtcTimeFromUnixTime(std::time_t unixTime)
Definition WowTime.cpp:86
#define sWorld
Definition World.h:900
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR
Definition World.h:96
WowTime const * GetWowTime()
Definition GameTime.cpp:72
WowTime const * GetUtcWowTime()
Definition GameTime.cpp:67
time_t GetGameTime()
Definition GameTime.cpp:42
TC_GAME_API Player * FindConnectedPlayerByName(std::string_view name)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
bool IsGuildAnnouncement() const
bool IsGuildEvent() const
uint64 GetEventId() const
void SetGuildId(ObjectGuid::LowType guildId)
void SetDate(time_t date)
ObjectGuid::LowType GuildId
int32 CalendarFilterType
uint32 Duration[MAX_HOLIDAY_DURATIONS]
char const * TextureFilename
uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]
uint32 Date[MAX_HOLIDAY_DATES]
InstanceSave * save
Definition Player.h:782
BindExtensionState extendState
Definition Player.h:791
bool IsRaid() const
std::array< int32, MAX_HOLIDAY_DURATIONS > Duration
std::array< WowTime, MAX_HOLIDAY_DATES > Date
std::array< int32, MAX_HOLIDAY_FLAGS > CalendarFlags