aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/CalendarHandler.cpp
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2019-09-17 09:11:56 +0200
committerGitHub <noreply@github.com>2019-09-17 09:11:56 +0200
commitfb059722fdb18a94d47b3f44a5b2d7f183bf5a29 (patch)
treebd492eb60a771dd7fd3f712b1e0a63d4110df45b /src/server/game/Handlers/CalendarHandler.cpp
parent6fc7ab3448850199835f9ee9dca6991b511eba09 (diff)
Core/Calendar: Add some additional validation when creating events (#23797)
* Core/Calendar: Add some additional validation when creating events Allow only 30 player events and 100 guild events to be created. Don't allow to create guild events if player is not in guild. Send some more error messages to the client (not blizzlike errors but better than nothing). * Core/Calendar: Add some additional validation/checks Add guild id check in GetPlayerEvents(). Change error message in HandleCalendarCopyEvent() to be the same as in HandleCalendarAddEvent() when creating an event in the past. * Core/Calendar: Add some additional validation/checks Reduce the number of CMSG_CALENDAR_ADD_EVENT packets a seconds allowed from 10 to 3. * Core/Calendar: Add some additional validation/checks Implement 5 seconds cooldown between the creation of calendar events * Core/Calendar: Add some additional validation/checks Don't allow to copy events of a different player/guild * Core/Calendar: Implement automatic deletion of old events Implement automatic deletion of events older than 1 month (30 days). Fix debug assertion triggered when deleting a character with calendar events. Avoid double std::set lookup when deleting events when deleting a character. NB: The whole CalendarMgr/CalendarHandler code should be checked line by line for bugs/crashes/exploits.
Diffstat (limited to 'src/server/game/Handlers/CalendarHandler.cpp')
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp99
1 files changed, 90 insertions, 9 deletions
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 3ee233a4c76..46839c4b147 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -245,15 +245,54 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
if (time_t(eventPackedTime) < (GameTime::GetGameTime() - time_t(86400L)))
{
recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
}
+ // If the event is a guild event, check if the player is in a guild
+ if (CalendarEvent::IsGuildEvent(flags) || CalendarEvent::IsGuildAnnouncement(flags))
+ {
+ if (!_player->GetGuildId())
+ {
+ recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
+ return;
+ }
+ }
+
+ // Check if the player reached the max number of events allowed to create
+ if (CalendarEvent::IsGuildEvent(flags) || CalendarEvent::IsGuildAnnouncement(flags))
+ {
+ if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
+ {
+ recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
+ return;
+ }
+ }
+ else
+ {
+ if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
+ {
+ recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
+ return;
+ }
+ }
+
+ if (GetCalendarEventCreationCooldown() > GameTime::GetGameTime())
+ {
+ recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
+ return;
+ }
+ SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
+
CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
- if (Player* creator = ObjectAccessor::FindPlayer(guid))
- calendarEvent->SetGuildId(creator->GetGuildId());
+ calendarEvent->SetGuildId(_player->GetGuildId());
if (calendarEvent->IsGuildAnnouncement())
{
@@ -266,12 +305,11 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
else
{
// client limits the amount of players to be invited to 100
- const uint32 MaxPlayerInvites = 100;
uint32 inviteCount;
- ObjectGuid invitee[MaxPlayerInvites];
- uint8 status[MaxPlayerInvites];
- uint8 rank[MaxPlayerInvites];
+ ObjectGuid invitee[CALENDAR_MAX_INVITES];
+ uint8 status[CALENDAR_MAX_INVITES];
+ uint8 rank[CALENDAR_MAX_INVITES];
memset(status, 0, sizeof(status));
memset(rank, 0, sizeof(rank));
@@ -280,7 +318,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
{
recvData >> inviteCount;
- for (uint32 i = 0; i < inviteCount && i < MaxPlayerInvites; ++i)
+ for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
{
recvData >> invitee[i].ReadAsPacked();
recvData >> status[i] >> rank[i];
@@ -297,7 +335,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
if (inviteCount > 1)
trans = CharacterDatabase.BeginTransaction();
- for (uint32 i = 0; i < inviteCount && i < MaxPlayerInvites; ++i)
+ for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
{
// 946684800 is 01/01/2000 00:00:00 - default response time
CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
@@ -398,12 +436,55 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (time_t(eventTime) < (GameTime::GetGameTime() - time_t(86400L)))
{
- recvData.rfinish();
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
}
if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
{
+ // Ensure that the player has access to the event
+ if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
+ {
+ if (oldEvent->GetGuildId() != _player->GetGuildId())
+ {
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
+ return;
+ }
+ }
+ else
+ {
+ if (oldEvent->GetCreatorGUID() != guid)
+ {
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
+ return;
+ }
+ }
+
+ // Check if the player reached the max number of events allowed to create
+ if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
+ {
+ if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
+ {
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
+ return;
+ }
+ }
+ else
+ {
+ if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
+ {
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
+ return;
+ }
+ }
+
+ if (GetCalendarEventCreationCooldown() > GameTime::GetGameTime())
+ {
+ sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
+ return;
+ }
+ SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
+
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
newEvent->SetEventTime(time_t(eventTime));
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);