diff options
author | Giacomo Pozzoni <giacomopoz@gmail.com> | 2019-09-17 09:11:56 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-18 22:19:05 +0100 |
commit | 562c567b1e0c878f0632994a79bcfbfd4a962504 (patch) | |
tree | fe5d5e3045e649c9fda5cb9a98871fe0f193b757 | |
parent | 368d99787cd8fff0e7831fbd2aafb122caea9b18 (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.
(cherry picked from commit fb059722fdb18a94d47b3f44a5b2d7f183bf5a29)
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.cpp | 73 | ||||
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.h | 20 | ||||
-rw-r--r-- | src/server/game/DungeonFinding/LFGMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/CalendarHandler.cpp | 87 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 8 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 44 | ||||
-rw-r--r-- | src/server/game/World/World.h | 5 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 8 |
9 files changed, 233 insertions, 22 deletions
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 4a2d31803fb..dd36321da74 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -19,6 +19,7 @@ #include "CalendarPackets.h" #include "CharacterCache.h" #include "DatabaseEnv.h" +#include "GameTime.h" #include "Guild.h" #include "GuildMgr.h" #include "Log.h" @@ -174,13 +175,24 @@ void CalendarMgr::RemoveEvent(uint64 eventId, ObjectGuid remover) return; } + RemoveEvent(calendarEvent, remover); +} + +void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover) +{ + if (!calendarEvent) + { + SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID); + return; + } + SendCalendarEventRemovedAlert(*calendarEvent); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); CharacterDatabasePreparedStatement* stmt; MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()); - CalendarInviteStore& eventInvites = _invites[eventId]; + CalendarInviteStore& eventInvites = _invites[calendarEvent->GetEventId()]; for (size_t i = 0; i < eventInvites.size(); ++i) { CalendarInvite* invite = eventInvites[i]; @@ -196,10 +208,10 @@ void CalendarMgr::RemoveEvent(uint64 eventId, ObjectGuid remover) delete invite; } - _invites.erase(eventId); + _invites.erase(calendarEvent->GetEventId()); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_EVENT); - stmt->setUInt64(0, eventId); + stmt->setUInt64(0, calendarEvent->GetEventId()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); @@ -279,9 +291,13 @@ void CalendarMgr::UpdateInvite(CalendarInvite* invite, CharacterDatabaseTransact void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid) { - for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) - if ((*itr)->GetOwnerGUID() == guid) - RemoveEvent((*itr)->GetEventId(), ObjectGuid::Empty); // don't send mail if removing a character + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();) + { + CalendarEvent* event = *itr; + ++itr; + if (event->GetOwnerGUID() == guid) + RemoveEvent(event, ObjectGuid::Empty); // don't send mail if removing a character + } CalendarInviteStore playerInvites = GetPlayerInvites(guid); for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) @@ -358,6 +374,44 @@ uint64 CalendarMgr::GetFreeInviteId() return inviteId; } +void CalendarMgr::DeleteOldEvents() +{ + time_t oldEventsTime = GameTime::GetGameTime() - CALENDAR_OLD_EVENTS_DELETION_TIME; + + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();) + { + CalendarEvent* event = *itr; + ++itr; + if (event->GetDate() < oldEventsTime) + RemoveEvent(event, ObjectGuid::Empty); + } +} + +CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents) +{ + CalendarEventStore result; + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetOwnerGUID() == guid && (includeGuildEvents || (!(*itr)->IsGuildEvent() && !(*itr)->IsGuildAnnouncement()))) + result.insert(*itr); + + return result; +} + +CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) +{ + CalendarEventStore result; + + if (!guildId) + return result; + + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()) + if ((*itr)->GetGuildId() == guildId) + result.insert(*itr); + + return result; +} + CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) { CalendarEventStore events; @@ -369,9 +423,10 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) events.insert(event); if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) - if ((*itr)->GetGuildId() == player->GetGuildId()) - events.insert(*itr); + if (player->GetGuildId()) + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetGuildId() == player->GetGuildId()) + events.insert(*itr); return events; } diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 349ac555e84..2d564b8f32f 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -128,9 +128,15 @@ enum CalendarError CALENDAR_ERROR_NO_MODERATOR = 40 }; -#define CALENDAR_MAX_EVENTS 30 -#define CALENDAR_MAX_GUILD_EVENTS 100 -#define CALENDAR_MAX_INVITES 100 +enum CalendarLimits +{ + CALENDAR_MAX_EVENTS = 30, + CALENDAR_MAX_GUILD_EVENTS = 100, + CALENDAR_MAX_INVITES = 100, + CALENDAR_CREATE_EVENT_COOLDOWN = 5, + CALENDAR_OLD_EVENTS_DELETION_TIME = 1 * MONTH, +}; + #define CALENDAR_DEFAULT_RESPONSE_TIME 946684800 // 01/01/2000 00:00:00 struct TC_GAME_API CalendarInvite @@ -253,6 +259,9 @@ struct TC_GAME_API CalendarEvent void SetLockDate(time_t lockDate) { _lockDate = lockDate; } time_t GetLockDate() const { return _lockDate; } + static bool IsGuildEvent(uint32 flags) { return (flags & CALENDAR_FLAG_GUILD_EVENT) != 0; } + static bool IsGuildAnnouncement(uint32 flags) { return (flags & CALENDAR_FLAG_WITHOUT_INVITES) != 0; } + std::string BuildCalendarMailSubject(ObjectGuid remover) const; std::string BuildCalendarMailBody() const; @@ -293,7 +302,9 @@ class TC_GAME_API CalendarMgr CalendarEvent* GetEvent(uint64 eventId) const; CalendarEventStore const& GetEvents() const { return _events; } + CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false); CalendarEventStore GetPlayerEvents(ObjectGuid guid); + CalendarEventStore GetGuildEvents(ObjectGuid::LowType guildId); CalendarInvite* GetInvite(uint64 inviteId) const; CalendarEventInviteStore const& GetInvites() const { return _invites; } @@ -305,10 +316,13 @@ class TC_GAME_API CalendarMgr void FreeInviteId(uint64 id); uint64 GetFreeInviteId(); + void DeleteOldEvents(); + uint32 GetPlayerNumPending(ObjectGuid guid); void AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType); void RemoveEvent(uint64 eventId, ObjectGuid remover); + void RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover); void UpdateEvent(CalendarEvent* calendarEvent); void AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite); diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 5576093e465..6de7f3f449a 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -544,7 +544,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons) { // Create new rolecheck LfgRoleCheck& roleCheck = RoleChecksStore[gguid]; - roleCheck.cancelTime = time_t(GameTime::GetGameTime()) + LFG_TIME_ROLECHECK; + roleCheck.cancelTime = GameTime::GetGameTime() + LFG_TIME_ROLECHECK; roleCheck.state = LFG_ROLECHECK_INITIALITING; roleCheck.leader = guid; roleCheck.dungeons = dungeons; diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 37118477dca..56df85015b7 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -141,14 +141,51 @@ void WorldSession::HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEve // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack if (calendarAddEvent.EventInfo.Time < (GameTime::GetGameTime() - time_t(86400L))) + { + 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(calendarAddEvent.EventInfo.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.EventInfo.Flags)) + { + if (!_player->GetGuildId()) + { + 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(calendarAddEvent.EventInfo.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.EventInfo.Flags)) + { + 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* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, UI64LIT(0), CalendarEventType(calendarAddEvent.EventInfo.EventType), calendarAddEvent.EventInfo.TextureID, calendarAddEvent.EventInfo.Time, calendarAddEvent.EventInfo.Flags, calendarAddEvent.EventInfo.Title, calendarAddEvent.EventInfo.Description, time_t(0)); if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement()) - if (Player* creator = ObjectAccessor::FindPlayer(guid)) - calendarEvent->SetGuildId(creator->GetGuildId()); + calendarEvent->SetGuildId(_player->GetGuildId()); if (calendarEvent->IsGuildAnnouncement()) { @@ -223,10 +260,56 @@ void WorldSession::HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyE // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack if (calendarCopyEvent.Date < (GameTime::GetGameTime() - time_t(86400L))) + { + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED); return; + } if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(calendarCopyEvent.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->GetOwnerGUID() != 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->SetDate(calendarCopyEvent.Date); sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 84d9ef9ff86..6fac054eea5 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -139,14 +139,14 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun _timeSyncClockDeltaQueue(6), _timeSyncClockDelta(0), _pendingTimeSyncRequests(), + _timeSyncNextCounter(0), + _timeSyncTimer(0), + _calendarEventCreationCooldown(0), _battlePetMgr(std::make_unique<BattlePets::BattlePetMgr>(this)), _collectionMgr(std::make_unique<CollectionMgr>(this)) { memset(_tutorials, 0, sizeof(_tutorials)); - _timeSyncNextCounter = 0; - _timeSyncTimer = 0; - if (sock) { m_Address = sock->GetRemoteIpAddress().to_string(); @@ -1389,7 +1389,6 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_SET_PARTY_LEADER: // 1 2 1 async db query case CMSG_CONVERT_RAID: // 1 5 1 async db query case CMSG_SET_ASSISTANT_LEADER: // 1 2 1 async db query - case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query case CMSG_MOVE_CHANGE_VEHICLE_SEATS: // not profiled case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled @@ -1411,6 +1410,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT: // 22 3 2 async db queries case CMSG_SUBMIT_USER_FEEDBACK: // not profiled 1 async db query case CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT: // not profiled 1 async db query + case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query case CMSG_CALENDAR_UPDATE_EVENT: // not profiled case CMSG_CALENDAR_REMOVE_EVENT: // not profiled case CMSG_CALENDAR_COPY_EVENT: // not profiled diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 23262c1657f..3ee0c596980 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1146,6 +1146,10 @@ class TC_GAME_API WorldSession void SendTimeSync(); uint32 AdjustClientMovementTime(uint32 time) const; + // Packets cooldown + time_t GetCalendarEventCreationCooldown() const { return _calendarEventCreationCooldown; } + void SetCalendarEventCreationCooldown(time_t cooldown) { _calendarEventCreationCooldown = cooldown; } + // Battle Pets BattlePets::BattlePetMgr* GetBattlePetMgr() const { return _battlePetMgr.get(); } @@ -1308,7 +1312,6 @@ class TC_GAME_API WorldSession void HandleRequestRaidInfoOpcode(WorldPackets::Party::RequestRaidInfo& packet); void HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet); - //void HandleGroupCancelOpcode(WorldPacket& recvPacket); void HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet); void HandlePartyUninviteOpcode(WorldPackets::Party::PartyUninvite& packet); void HandleSetPartyLeaderOpcode(WorldPackets::Party::SetPartyLeader& packet); @@ -1933,6 +1936,9 @@ class TC_GAME_API WorldSession uint32 _timeSyncNextCounter; uint32 _timeSyncTimer; + // Packets cooldown + time_t _calendarEventCreationCooldown; + std::unique_ptr<BattlePets::BattlePetMgr> _battlePetMgr; std::unique_ptr<CollectionMgr> _collectionMgr; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9562b82cde9..d99123ec6f2 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -132,6 +132,7 @@ World::World() m_NextWeeklyQuestReset = 0; m_NextMonthlyQuestReset = 0; m_NextRandomBGReset = 0; + m_NextCalendarOldEventsDeletionTime = 0; m_NextGuildReset = 0; m_NextCurrencyReset = 0; @@ -1245,6 +1246,13 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_RANDOM_BG_RESET_HOUR] = 6; } + m_int_configs[CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR] = sConfigMgr->GetIntDefault("Calendar.DeleteOldEventsHour", 6); + if (m_int_configs[CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR] > 23) + { + TC_LOG_ERROR("misc", "Calendar.DeleteOldEventsHour (%i) can't be load. Set to 6.", m_int_configs[CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR]); + m_int_configs[CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR] = 6; + } + m_int_configs[CONFIG_GUILD_RESET_HOUR] = sConfigMgr->GetIntDefault("Guild.ResetHour", 6); if (m_int_configs[CONFIG_GUILD_RESET_HOUR] > 23) { @@ -2400,6 +2408,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Calculate random battleground reset time..."); InitRandomBGResetTime(); + TC_LOG_INFO("server.loading", "Calculate deletion of old calendar events time..."); + InitCalendarOldEventsDeletionTime(); + TC_LOG_INFO("server.loading", "Calculate guild limitation(s) reset time..."); InitGuildResetTime(); @@ -2523,6 +2534,9 @@ void World::Update(uint32 diff) if (currentGameTime > m_NextRandomBGReset) ResetRandomBG(); + if (currentGameTime > m_NextCalendarOldEventsDeletionTime) + CalendarDeleteOldEvents(); + if (currentGameTime > m_NextGuildReset) ResetGuildCap(); @@ -3485,7 +3499,7 @@ void World::InitRandomBGResetTime() { time_t bgtime = sWorld->getWorldState(WS_BG_DAILY_RESET_TIME); if (!bgtime) - m_NextRandomBGReset = GameTime::GetGameTime(); // game time not yet init + m_NextRandomBGReset = GameTime::GetGameTime(); // game time not yet init // generate time by config time_t curTime = GameTime::GetGameTime(); @@ -3509,11 +3523,28 @@ void World::InitRandomBGResetTime() sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint32(m_NextRandomBGReset)); } +void World::InitCalendarOldEventsDeletionTime() +{ + time_t now = GameTime::GetGameTime(); + time_t nextDeletionTime = GetLocalHourTimestamp(now, getIntConfig(CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR)); + time_t currentDeletionTime = getWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME); + + // If the reset time saved in the worldstate is before now it means the server was offline when the reset was supposed to occur. + // In this case we set the reset time in the past and next world update will do the reset and schedule next one in the future. + if (currentDeletionTime < now) + m_NextCalendarOldEventsDeletionTime = nextDeletionTime - DAY; + else + m_NextCalendarOldEventsDeletionTime = nextDeletionTime; + + if (!currentDeletionTime) + sWorld->setWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME, uint64(m_NextCalendarOldEventsDeletionTime)); +} + void World::InitGuildResetTime() { time_t gtime = getWorldState(WS_GUILD_DAILY_RESET_TIME); if (!gtime) - m_NextGuildReset = GameTime::GetGameTime(); // game time not yet init + m_NextGuildReset = GameTime::GetGameTime(); // game time not yet init // generate time by config time_t curTime = GameTime::GetGameTime(); @@ -3607,6 +3638,15 @@ void World::ResetRandomBG() sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint32(m_NextRandomBGReset)); } +void World::CalendarDeleteOldEvents() +{ + TC_LOG_INFO("misc", "Calendar deletion of old events."); + + m_NextCalendarOldEventsDeletionTime = time_t(m_NextCalendarOldEventsDeletionTime + DAY); + sWorld->setWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME, uint64(m_NextCalendarOldEventsDeletionTime)); + sCalendarMgr->DeleteOldEvents(); +} + void World::ResetGuildCap() { m_NextGuildReset = time_t(m_NextGuildReset + DAY); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 0e09a7eaf97..40d6ce3c938 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -349,6 +349,7 @@ enum WorldIntConfigs CONFIG_GUILD_BANK_EVENT_LOG_COUNT, CONFIG_MIN_LEVEL_STAT_SAVE, CONFIG_RANDOM_BG_RESET_HOUR, + CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR, CONFIG_GUILD_RESET_HOUR, CONFIG_CHARDELETE_KEEP_DAYS, CONFIG_CHARDELETE_METHOD, @@ -561,6 +562,7 @@ enum WorldStates WS_GUILD_DAILY_RESET_TIME = 20006, // Next guild cap reset time WS_MONTHLY_QUEST_RESET_TIME = 20007, // Next monthly quest reset time WS_DAILY_QUEST_RESET_TIME = 20008, // Next daily quest reset time + WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME = 20009, // Next daily calendar deletions of old events time // Cata specific custom worldstates WS_GUILD_WEEKLY_RESET_TIME = 20050, // Next guild week reset time }; @@ -820,8 +822,10 @@ class TC_GAME_API World void ResetMonthlyQuests(); void InitRandomBGResetTime(); + void InitCalendarOldEventsDeletionTime(); void InitGuildResetTime(); void ResetRandomBG(); + void CalendarDeleteOldEvents(); void ResetGuildCap(); void ResetCurrencyWeekCap(); private: @@ -885,6 +889,7 @@ class TC_GAME_API World time_t m_NextWeeklyQuestReset; time_t m_NextMonthlyQuestReset; time_t m_NextRandomBGReset; + time_t m_NextCalendarOldEventsDeletionTime; time_t m_NextGuildReset; time_t m_NextCurrencyReset; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 3a64aedf766..593018d4c6b 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1085,6 +1085,14 @@ Quests.DailyResetTime = 3 Quests.WeeklyResetWDay = 3 # +# Calendar.DeleteOldEventsHour +# Description: Hour of the day when the daily deletion of old calendar events occurs. +# Range: 0-23 +# Default: 6 - (06:00 AM) + +Calendar.DeleteOldEventsHour = 6 + +# # Guild.EventLogRecordsCount # Description: Number of log entries for guild events that are stored per guild. Old entries # will be overwritten if the number of log entries exceed the configured value. |