diff options
Diffstat (limited to 'src/server')
-rwxr-xr-x | src/server/game/Battlegrounds/ArenaTeam.cpp | 17 | ||||
-rwxr-xr-x | src/server/game/Battlegrounds/ArenaTeam.h | 2 | ||||
-rwxr-xr-x | src/server/game/Calendar/Calendar.cpp | 99 | ||||
-rwxr-xr-x | src/server/game/Calendar/Calendar.h | 189 | ||||
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.cpp | 895 | ||||
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.h | 317 | ||||
-rwxr-xr-x | src/server/game/Guilds/Guild.cpp | 36 | ||||
-rwxr-xr-x | src/server/game/Guilds/Guild.h | 2 | ||||
-rwxr-xr-x | src/server/game/Handlers/CalendarHandler.cpp | 884 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Handlers/MailHandler.cpp | 6 | ||||
-rwxr-xr-x | src/server/game/Mails/Mail.cpp | 10 | ||||
-rwxr-xr-x | src/server/game/Mails/Mail.h | 4 | ||||
-rwxr-xr-x | src/server/game/Miscellaneous/SharedDefines.h | 98 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.h | 14 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 6 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.h | 5 |
18 files changed, 1168 insertions, 1420 deletions
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 0223541335c..cc543544c7a 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -511,6 +511,23 @@ void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCoun sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_EVENT"); } +void ArenaTeam::MassInviteToEvent(WorldSession* session) +{ + WorldPacket data(SMSG_CALENDAR_ARENA_TEAM, (Members.size() - 1) * (4 + 8 + 1)); + data << uint32(Members.size() - 1); + + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) + { + if (itr->Guid != session->GetPlayer()->GetGUID()) + { + data.appendPackGUID(itr->Guid); + data << uint8(0); // unk + } + } + + session->SendPacket(&data); +} + uint8 ArenaTeam::GetSlotByType(uint32 type) { switch (type) diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index 7d2d680cddc..137ac93d3c0 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -162,6 +162,8 @@ class ArenaTeam void BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string const& str1, std::string const& str2, std::string const& str3); void NotifyStatsChanged(); + void MassInviteToEvent(WorldSession* session); + void Roster(WorldSession* session); void Query(WorldSession* session); void SendStats(WorldSession* session); diff --git a/src/server/game/Calendar/Calendar.cpp b/src/server/game/Calendar/Calendar.cpp deleted file mode 100755 index 139e63614cc..00000000000 --- a/src/server/game/Calendar/Calendar.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "Player.h" -#include "Calendar.h" - -std::string CalendarInvite::GetDebugString() const -{ - std::ostringstream data; - - data << "CalendarInvite::" - << " inviteId: " << _inviteId - << " EventId: " << _eventId - << " Status: " << uint32(_status) - << " Invitee: " << _invitee - << " Sender: " << _senderGUID - << " Rank: " << uint32(_rank) - << " Text: " << _text; - - return data.str(); -} - -void CalendarInvite::Init() -{ - _eventId = 0; - _invitee = 0; - _senderGUID = 0; - _statusTime = 0; - _status = CALENDAR_STATUS_INVITED; // default (0)? - _rank = CALENDAR_RANK_PLAYER; - _text = ""; -} - -std::string CalendarEvent::GetDebugString() const -{ - std::ostringstream data; - - data << "CalendarEvent::" - << " EventId: " << _eventId - << " Title: " << _title - << " Description" << _description - << " Type: " << uint32(_type) - << " Max Invites: " << _maxInvites - << " Creator: " << _creatorGUID - << " Flags: " << _flags - << " Guild: " << _guildId - << " Time: " << _eventTime - << " Time2: " << _timezoneTime - << " Repeatable: " << uint32(_repeatable) - << " DungeonId: " << _dungeonId; - - return data.str(); -} - -void CalendarEvent::Init() -{ - _creatorGUID = 0; - _guildId = 0; - _type = CALENDAR_TYPE_OTHER; - _dungeonId = -1; - _maxInvites = 0; - _eventTime = 0; - _flags = 0; - _repeatable = false; - _timezoneTime = 0; - _title = ""; - _description = ""; - -} - -std::string CalendarAction::GetDebugString() const -{ - std::ostringstream data; - - data << "CalendarAction::" - << " Action: " << GetAction() - << " Guid: " << GetPlayer()->GetGUID() - << " Invite Id: " << GetInviteId() - << " Extra data: " << GetExtraData() - << " Event: " << Event.GetDebugString() - << " Invite: " << Invite.GetDebugString(); - - return data.str(); -} diff --git a/src/server/game/Calendar/Calendar.h b/src/server/game/Calendar/Calendar.h deleted file mode 100755 index 273db4c3854..00000000000 --- a/src/server/game/Calendar/Calendar.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_CALENDAR_H -#define TRINITY_CALENDAR_H - -#include "Errors.h" -#include "SharedDefines.h" -#include <map> - -class CalendarInvite -{ - public: - CalendarInvite() : _inviteId(0) { Init(); } - explicit CalendarInvite(uint64 inviteId) : _inviteId(inviteId) { Init(); } - - ~CalendarInvite() { } - - void SetInviteId(uint64 inviteId) { _inviteId = inviteId; } - uint64 GetInviteId() const { return _inviteId; } - - void SetEventId(uint64 eventId) { _eventId = eventId; } - uint64 GetEventId() const { return _eventId; } - - void SetSenderGUID(uint64 guid) { _senderGUID = guid; } - uint64 GetSenderGUID() const { return _senderGUID; } - - void SetInvitee(uint64 guid) { _invitee = guid; } - uint64 GetInvitee() const { return _invitee; } - - void SetStatusTime(uint32 statusTime) { _statusTime = statusTime; } - uint32 GetStatusTime() const { return _statusTime; } - - void SetText(std::string const& text) { _text = text; } - std::string const& GetText() const { return _text; } - - void SetStatus(CalendarInviteStatus status) { _status = status; } - CalendarInviteStatus GetStatus() const { return _status; } - - void SetRank(CalendarModerationRank rank) { _rank = rank; } - CalendarModerationRank GetRank() const { return _rank; } - - std::string GetDebugString() const; - - private: - void Init(); - - uint64 _inviteId; - uint64 _eventId; - uint64 _invitee; - uint64 _senderGUID; - uint32 _statusTime; - CalendarInviteStatus _status; - CalendarModerationRank _rank; - std::string _text; -}; - -typedef std::set<uint64> CalendarInviteIdList; - -class CalendarEvent -{ - public: - CalendarEvent() : _eventId(0) { Init(); } - explicit CalendarEvent(uint64 eventId) : _eventId(eventId) { Init(); } - - ~CalendarEvent() { } - - void SetEventId(uint64 eventId) { _eventId = eventId; } - uint64 GetEventId() const { return _eventId; } - - void SetCreatorGUID(uint64 guid) { _creatorGUID = guid; } - uint64 GetCreatorGUID() const { return _creatorGUID; } - - void SetGuildId(uint32 guildId) { _guildId = guildId; } - uint32 GetGuildId() const { return _guildId; } - - void SetTitle(std::string const& title) { _title = title; } - std::string const& GetTitle() const { return _title; } - - void SetDescription(std::string const& description) { _description = description; } - std::string const& GetDescription() const { return _description; } - - void SetType(CalendarEventType type) { _type = type; } - CalendarEventType GetType() const { return _type; } - - void SetMaxInvites(uint32 limit) { _maxInvites = limit; } - uint32 GetMaxInvites() const { return _maxInvites; } - - void SetDungeonId(int32 dungeonId) { _dungeonId = dungeonId; } - int32 GetDungeonId() const { return _dungeonId; } - - void SetTime(uint32 eventTime) { _eventTime = eventTime; } - uint32 GetTime() const { return _eventTime; } - - void SetFlags(uint32 flags) { _flags = flags; } - uint32 GetFlags() const { return _flags; } - - void SetRepeatable(bool repeatable) { _repeatable = repeatable; } - bool GetRepeatable() const { return _repeatable; } - - void SetTimeZoneTime(uint32 timezoneTime) { _timezoneTime = timezoneTime; } - uint32 GetTimeZoneTime() const { return _timezoneTime; } - - void AddInvite(uint64 inviteId) - { - if (inviteId) - _invites.insert(inviteId); - } - - void RemoveInvite(uint64 inviteId) { _invites.erase(inviteId); } - bool HasInvite(uint64 inviteId) const { return _invites.find(inviteId) != _invites.end(); } - CalendarInviteIdList const& GetInviteIdList() const { return _invites; } - void SetInviteIdList(CalendarInviteIdList const& list) { _invites = list; } - void ClearInviteIdList() { _invites.clear(); } - - std::string GetDebugString() const; - - private: - void Init(); - - uint64 _eventId; - uint64 _creatorGUID; - uint32 _guildId; - CalendarEventType _type; - int32 _dungeonId; - uint32 _maxInvites; - uint32 _eventTime; - uint32 _flags; - bool _repeatable; - uint32 _timezoneTime; - std::string _title; - std::string _description; - CalendarInviteIdList _invites; -}; - -typedef std::set<uint64> CalendarEventIdList; -typedef std::map<uint64, CalendarInviteIdList> CalendarPlayerInviteIdMap; -typedef std::map<uint64, CalendarEventIdList> CalendarPlayerEventIdMap; -typedef std::map<uint64, CalendarInvite> CalendarInviteMap; -typedef std::map<uint64, CalendarEvent> CalendarEventMap; - -class Player; - -struct CalendarAction -{ - CalendarAction(): _action(CALENDAR_ACTION_NONE), _player(NULL), _inviteId(0), _data(0) - { - } - - void SetAction(CalendarActionData data) { _action = data; } - CalendarActionData GetAction() const { return _action; } - - void SetPlayer(Player* player) { ASSERT(player); _player = player; } - Player* GetPlayer() const { return _player; } - - void SetInviteId(uint64 id) { _inviteId = id; } - uint64 GetInviteId() const { return _inviteId; } - - void SetExtraData(uint32 data) { _data = data; } - uint32 GetExtraData() const { return _data; } - - CalendarEvent Event; - CalendarInvite Invite; - - std::string GetDebugString() const; - - private: - CalendarActionData _action; - Player* _player; - uint64 _inviteId; - uint32 _data; -}; - -#endif diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 80de42c0ce2..3f909bb85fb 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -15,579 +15,620 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* - -DROP TABLE IF EXISTS `calendar_events`; -CREATE TABLE IF NOT EXISTS `calendar_events` ( - `id` int(11) unsigned NOT NULL DEFAULT '0', - `creator` int(11) unsigned NOT NULL DEFAULT '0', - `title` varchar(255) NOT NULL DEFAULT '', - `description` varchar(255) NOT NULL DEFAULT '', - `type` tinyint(1) unsigned NOT NULL DEFAULT '4', - `dungeon` tinyint(3) NOT NULL DEFAULT '-1', - `eventtime` int(10) unsigned NOT NULL DEFAULT '0', - `flags` int(10) unsigned NOT NULL DEFAULT '0', - `repeatable` tinyint(1) unsigned NOT NULL DEFAULT '0', - `time2` int(10) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -); - -DROP TABLE IF EXISTS `calendar_invites`; -CREATE TABLE IF NOT EXISTS `calendar_invites` ( - `id` int(11) unsigned NOT NULL DEFAULT '0', - `event` int(11) unsigned NOT NULL DEFAULT '0', - `invitee` int(11) unsigned NOT NULL DEFAULT '0', - `sender` int(11) unsigned NOT NULL DEFAULT '0', - `status` tinyint(1) unsigned NOT NULL DEFAULT '0', - `statustime` int(10) unsigned NOT NULL DEFAULT '0', - `rank` tinyint(1) unsigned NOT NULL DEFAULT '0', - `text` varchar(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`) -); -*/ - #include "CalendarMgr.h" #include "QueryResult.h" #include "DatabaseEnv.h" #include "Log.h" #include "Player.h" +#include "GuildMgr.h" #include "ObjectAccessor.h" -CalendarMgr::CalendarMgr() : - _eventNum(0), _inviteNum(0) +CalendarInvite::~CalendarInvite() { + sCalendarMgr->FreeInviteId(_inviteId); } -CalendarMgr::~CalendarMgr() +CalendarEvent::~CalendarEvent() { + sCalendarMgr->FreeEventId(_eventId); } -uint32 CalendarMgr::GetPlayerNumPending(uint64 guid) +CalendarMgr::CalendarMgr() { - if (!guid) - return 0; - - CalendarPlayerInviteIdMap::const_iterator itr = _playerInvites.find(guid); - if (itr == _playerInvites.end()) - return 0; - - uint32 pendingNum = 0; - for (CalendarInviteIdList::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it) - if (CalendarInvite* invite = GetInvite(*it)) - if (invite->GetRank() != CALENDAR_RANK_OWNER - && invite->GetStatus() != CALENDAR_STATUS_CONFIRMED - && invite->GetStatus() != CALENDAR_STATUS_8 - && invite->GetStatus() != CALENDAR_STATUS_9) // FIXME Check the proper value - ++pendingNum; - - return pendingNum; } -CalendarInviteIdList const& CalendarMgr::GetPlayerInvites(uint64 guid) +CalendarMgr::~CalendarMgr() { - return _playerInvites[guid]; } -CalendarEventIdList const& CalendarMgr::GetPlayerEvents(uint64 guid) +void CalendarMgr::LoadFromDB() { - return _playerEvents[guid]; -} + uint32 count = 0; + _maxEventId = 1; + _maxInviteId = 1; -CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) -{ - CalendarInviteMap::iterator itr = _invites.find(inviteId); - if (itr != _invites.end()) - return &(itr->second); + // 0 1 2 3 4 5 6 7 8 + if (QueryResult result = CharacterDatabase.Query("SELECT id, creator, title, description, type, dungeon, eventtime, flags, time2 FROM calendar_events")) + do + { + Field* fields = result->Fetch(); - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId); - return NULL; -} + uint64 eventId = fields[0].GetUInt64(); + uint64 creatorGUID = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER); + std::string title = fields[2].GetString(); + std::string description = fields[3].GetString(); + CalendarEventType type = CalendarEventType(fields[4].GetUInt8()); + int32 dungeonId = fields[5].GetInt32(); + uint32 eventTime = fields[6].GetUInt32(); + uint32 flags = fields[7].GetUInt32(); + uint32 timezoneTime = fields[8].GetUInt32(); + uint32 guildId = 0; -CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) -{ - CalendarEventMap::iterator itr = _events.find(eventId); - if (itr != _events.end()) - return &(itr->second); + if (flags & CALENDAR_FLAG_GUILD_EVENT || flags & CALENDAR_FLAG_WITHOUT_INVITES) + guildId = Player::GetGuildIdFromDB(creatorGUID); - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId); - return NULL; -} + CalendarEvent* calendarEvent = new CalendarEvent(eventId, creatorGUID , guildId, type, dungeonId, time_t(eventTime), flags, time_t(timezoneTime), title, description); + _events.insert(calendarEvent); -uint64 CalendarMgr::GetFreeEventId() -{ - return ++_eventNum; -} -uint64 CalendarMgr::GetFreeInviteId() -{ - return ++_inviteNum; -} + _maxEventId = std::max(_maxEventId, eventId); -void CalendarMgr::LoadFromDB() -{ - /* - uint32 count = 0; - // 0 1 2 3 4 5 6 7 8 9 - if (QueryResult result = CharacterDatabase.Query("SELECT id, creator, title, description, type, dungeon, eventtime, flags, repeatable, time2 FROM calendar_events")) - do - { - Field * fields = result->Fetch(); - - uint64 eventId = fields[0].GetUInt64(); - CalendarEvent& calendarEvent = _events[eventId]; - - calendarEvent.SetEventId(eventId); - calendarEvent.SetCreatorGUID(fields[1].GetUInt64()); - calendarEvent.SetTitle(fields[2].GetString()); - calendarEvent.SetDescription(fields[3].GetString()); - calendarEvent.SetType(fields[4].GetUInt8()); - calendarEvent.SetDungeonId(fields[5].GetInt32()); - calendarEvent.SetTime(fields[6].GetUInt32()); - calendarEvent.SetFlags(fields[7].GetUInt32()); - calendarEvent.SetRepeatable(fields[8].GetBool()); - calendarEvent.SetTimeZoneTime(fields[9].GetUInt32()); ++count; } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_CALENDAR, ">> Loaded %u calendar events", count); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u calendar events", count); count = 0; // 0 1 2 3 4 5 6 7 if (QueryResult result = CharacterDatabase.Query("SELECT id, event, invitee, sender, status, statustime, rank, text FROM calendar_invites")) do { - Field * fields = result->Fetch(); + Field* fields = result->Fetch(); - uint64 inviteId = fields[0].GetUInt64(); - uint64 eventId = fields[1].GetUInt64(); + uint64 inviteId = fields[0].GetUInt64(); + uint64 eventId = fields[1].GetUInt64(); + uint64 invitee = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); + uint64 senderGUID = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER); + CalendarInviteStatus status = CalendarInviteStatus(fields[4].GetUInt8()); + uint32 statusTime = fields[5].GetUInt32(); + CalendarModerationRank rank = CalendarModerationRank(fields[6].GetUInt8()); + std::string text = fields[7].GetString(); - CalendarInvite& invite = _invites[inviteId]; + CalendarInvite* invite = new CalendarInvite(inviteId, eventId, invitee, senderGUID, time_t(statusTime), status, rank, text); + _invites[eventId].push_back(invite); - invite.SetEventId(eventId); - invite.SetInvitee(fields[2].GetUInt64()); - invite.SetSenderGUID(fields[3].GetUInt64()); - invite.SetStatus(fields[4].GetUInt8()); - invite.SetStatusTime(fields[5].GetUInt32()); - invite.SetRank(fields[6].GetUInt8()); - invite.SetText(fields[7].GetString()); + _maxInviteId = std::max(_maxInviteId, inviteId); - CalendarEvent& calendarEvent = _events[eventId]; - calendarEvent.AddInvite(inviteId); + ++count; } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_CALENDAR, ">> Loaded %u calendar Invites", count); - */ + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u calendar invites", count); + + for (uint64 i = 1; i < _maxEventId; ++i) + if (!GetEvent(i)) + _freeEventIds.push_back(i); + + for (uint64 i = 1; i < _maxInviteId; ++i) + if (!GetInvite(i)) + _freeInviteIds.push_back(i); } -CalendarEvent* CalendarMgr::CheckPermisions(uint64 eventId, Player* player, uint64 inviteId, CalendarModerationRank minRank) +void CalendarMgr::AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType) { - if (!player) - return NULL; // CALENDAR_ERROR_INTERNAL + _events.insert(calendarEvent); + UpdateEvent(calendarEvent); + SendCalendarEvent(calendarEvent->GetCreatorGUID(), *calendarEvent, sendType); +} - CalendarEvent* calendarEvent = GetEvent(eventId); - if (!calendarEvent) - { - player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_EVENT_INVALID); - return NULL; - } +void CalendarMgr::AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite) +{ + if (!calendarEvent->IsGuildAnnouncement()) + SendCalendarEventInvite(*invite); - CalendarInvite* invite = GetInvite(inviteId); - if (!invite) - { - player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_NO_INVITE); - return NULL; - } + if (!calendarEvent->IsGuildEvent() || invite->GetInviteeGUID() == calendarEvent->GetCreatorGUID()) + SendCalendarEventInviteAlert(*calendarEvent, *invite); - if (!calendarEvent->HasInvite(inviteId)) + if (!calendarEvent->IsGuildAnnouncement()) { - player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_NOT_INVITED); - return NULL; + _invites[invite->GetEventId()].push_back(invite); + UpdateInvite(invite); } +} + +void CalendarMgr::RemoveEvent(uint64 eventId, uint64 remover) +{ + CalendarEvent* calendarEvent = GetEvent(eventId); - if (invite->GetEventId() != calendarEvent->GetEventId() || invite->GetInvitee() != player->GetGUID()) + if (!calendarEvent) { - player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_INTERNAL); - return NULL; + SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID); + return; } - if (invite->GetRank() < minRank) + SendCalendarEventRemovedAlert(*calendarEvent); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt; + MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()); + + std::vector<CalendarInvite*>::iterator itr = _invites[eventId].begin(); + while (itr != _invites[eventId].end()) { - player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_PERMISSIONS); - return NULL; + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE); + stmt->setUInt64(0, (*itr)->GetInviteId()); + trans->Append(stmt); + + // guild events only? check invite status here? + // When an event is deleted, all invited (accepted/declined? - verify) guildies are notified via in-game mail. (wowwiki) + if (remover && (*itr)->GetInviteeGUID() != remover) + mail.SendMailTo(trans, MailReceiver((*itr)->GetInviteeGUID()), calendarEvent, MAIL_CHECK_MASK_COPIED); + + delete *itr; + _invites[eventId].erase(itr); } - return calendarEvent; + _invites.erase(eventId); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_EVENT); + stmt->setUInt64(0, eventId); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); + + delete calendarEvent; + _events.erase(calendarEvent); } -void CalendarMgr::AddAction(CalendarAction const& action) +void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, uint64 remover) { - switch (action.GetAction()) - { - case CALENDAR_ACTION_ADD_EVENT: - { - if (AddEvent(action.Event) && AddInvite(action.Invite)) - { - SendCalendarEventInviteAlert(action.Event, action.Invite); - SendCalendarEvent(action.Event, CALENDAR_SENDTYPE_ADD); - } - break; - } - case CALENDAR_ACTION_MODIFY_EVENT: - { - uint64 eventId = action.Event.GetEventId(); - CalendarEvent* calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); - if (!calendarEvent) - return; - - calendarEvent->SetEventId(action.Event.GetEventId()); - calendarEvent->SetType(action.Event.GetType()); - calendarEvent->SetFlags(action.Event.GetFlags()); - calendarEvent->SetTime(action.Event.GetTime()); - calendarEvent->SetTimeZoneTime(action.Event.GetTimeZoneTime()); - calendarEvent->SetRepeatable(action.Event.GetRepeatable()); - calendarEvent->SetDungeonId(action.Event.GetDungeonId()); - calendarEvent->SetTitle(action.Event.GetTitle()); - calendarEvent->SetDescription(action.Event.GetDescription()); - calendarEvent->SetMaxInvites(action.Event.GetMaxInvites()); - - CalendarInviteIdList const& invites = calendarEvent->GetInviteIdList(); - for (CalendarInviteIdList::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) - if (CalendarInvite* invite = GetInvite(*itr)) - SendCalendarEventUpdateAlert(invite->GetInvitee(), *calendarEvent, CALENDAR_SENDTYPE_ADD); + CalendarEvent* calendarEvent = GetEvent(eventId); - break; - } - case CALENDAR_ACTION_COPY_EVENT: - { - CalendarEvent* calendarEvent = CheckPermisions(action.Event.GetEventId(), action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_OWNER); - - if (!calendarEvent) - return; - - uint64 eventId = GetFreeEventId(); - CalendarEvent newEvent(eventId); - newEvent.SetType(calendarEvent->GetType()); - newEvent.SetFlags(calendarEvent->GetFlags()); - newEvent.SetTime(action.Event.GetTime()); - newEvent.SetTimeZoneTime(calendarEvent->GetTimeZoneTime()); - newEvent.SetRepeatable(calendarEvent->GetRepeatable()); - newEvent.SetDungeonId(calendarEvent->GetDungeonId()); - newEvent.SetTitle(calendarEvent->GetTitle()); - newEvent.SetDescription(calendarEvent->GetDescription()); - newEvent.SetMaxInvites(calendarEvent->GetMaxInvites()); - newEvent.SetCreatorGUID(calendarEvent->GetCreatorGUID()); - newEvent.SetGuildId(calendarEvent->GetGuildId()); - - CalendarInviteIdList const invites = calendarEvent->GetInviteIdList(); - for (CalendarInviteIdList::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) - { - if (CalendarInvite* invite = GetInvite(*itr)) - { - uint64 inviteId = GetFreeInviteId(); - CalendarInvite newInvite(inviteId); - newInvite.SetEventId(eventId); - newInvite.SetSenderGUID(action.GetPlayer()->GetGUID()); - newInvite.SetInvitee(invite->GetInvitee()); - newInvite.SetStatus(invite->GetStatus()); - newInvite.SetStatusTime(invite->GetStatusTime()); - newInvite.SetText(invite->GetText()); - newInvite.SetRank(invite->GetRank()); - if (AddInvite(newInvite)) - { - SendCalendarEventInviteAlert(newEvent, newInvite); - newEvent.AddInvite(inviteId); - } - } - } - - if (AddEvent(newEvent)) - SendCalendarEvent(newEvent, CALENDAR_SENDTYPE_COPY); + if (!calendarEvent) + return; + std::vector<CalendarInvite*>::iterator itr = _invites[eventId].begin(); + for (; itr != _invites[eventId].end(); ++itr) + if ((*itr)->GetInviteId() == inviteId) break; - } - case CALENDAR_ACTION_REMOVE_EVENT: - { - uint64 eventId = action.Event.GetEventId(); - //uint32 flags = action.Event.GetFlags(); - // FIXME - Use of Flags here! - CalendarEvent* calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_OWNER); - if (!calendarEvent) - return; + if (itr == _invites[eventId].end()) + return; - RemoveEvent(eventId); - break; - } - case CALENDAR_ACTION_ADD_EVENT_INVITE: - { - uint64 eventId = action.Invite.GetEventId(); - CalendarEvent* calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); - if (!calendarEvent) - return; - - if (AddInvite(action.Invite)) - { - calendarEvent->AddInvite(action.Invite.GetInviteId()); - SendCalendarEventInvite(action.Invite, (!(calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED) && - !action.Invite.GetStatusTime())); - SendCalendarEventInviteAlert(*calendarEvent, action.Invite); - } + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE); + stmt->setUInt64(0, (*itr)->GetInviteId()); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); - break; - } - case CALENDAR_ACTION_SIGNUP_TO_EVENT: - { - uint64 eventId = action.Event.GetEventId(); - CalendarEvent* calendarEvent = GetEvent(eventId); - CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); + if (!calendarEvent->IsGuildEvent()) + SendCalendarEventInviteRemoveAlert((*itr)->GetInviteeGUID(), *calendarEvent, CALENDAR_STATUS_REMOVED); - if (!calendarEvent || !(calendarEvent->GetFlags() & CALENDAR_FLAG_GUILD_ONLY) - || !calendarEvent->GetGuildId() || calendarEvent->GetGuildId() != action.GetExtraData()) - return; + SendCalendarEventInviteRemove(*calendarEvent, **itr, calendarEvent->GetFlags()); - CalendarInviteStatus status = action.Invite.GetStatus(); + // we need to find out how to use CALENDAR_INVITE_REMOVED_MAIL_SUBJECT to force client to display different mail + //if ((*itr)->GetInviteeGUID() != remover) + // MailDraft(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()) + // .SendMailTo(trans, MailReceiver((*itr)->GetInvitee()), calendarEvent, MAIL_CHECK_MASK_COPIED); - if (status == CALENDAR_STATUS_INVITED) - status = CALENDAR_STATUS_CONFIRMED; - else if (status == CALENDAR_STATUS_ACCEPTED) - status = CALENDAR_STATUS_8; + delete *itr; + _invites[eventId].erase(itr); +} - CalendarInvite newInvite(GetFreeInviteId()); - newInvite.SetStatus(status); - newInvite.SetStatusTime(uint32(time(NULL))); - newInvite.SetEventId(eventId); - newInvite.SetInvitee(action.GetPlayer()->GetGUID()); - newInvite.SetSenderGUID(action.GetPlayer()->GetGUID()); +void CalendarMgr::UpdateEvent(CalendarEvent* calendarEvent) +{ + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CALENDAR_EVENT); + stmt->setUInt64(0, calendarEvent->GetEventId()); + stmt->setUInt32(1, GUID_LOPART(calendarEvent->GetCreatorGUID())); + stmt->setString(2, calendarEvent->GetTitle()); + stmt->setString(3, calendarEvent->GetDescription()); + stmt->setUInt8(4, calendarEvent->GetType()); + stmt->setInt32(5, calendarEvent->GetDungeonId()); + stmt->setUInt32(6, uint32(calendarEvent->GetEventTime())); + stmt->setUInt32(7, calendarEvent->GetFlags()); + stmt->setUInt32(8, calendarEvent->GetTimeZoneTime()); // correct? + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); +} - if (AddInvite(newInvite)) - SendCalendarEventInvite(newInvite, false); +void CalendarMgr::UpdateInvite(CalendarInvite* invite) +{ + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CALENDAR_INVITE); + stmt->setUInt64(0, invite->GetInviteId()); + stmt->setUInt64(1, invite->GetEventId()); + stmt->setUInt32(2, GUID_LOPART(invite->GetInviteeGUID())); + stmt->setUInt32(3, GUID_LOPART(invite->GetSenderGUID())); + stmt->setUInt8(4, invite->GetStatus()); + stmt->setUInt32(5, uint32(invite->GetStatusTime())); + stmt->setUInt8(6, invite->GetRank()); + stmt->setString(7, invite->GetText()); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); +} - break; - } - case CALENDAR_ACTION_MODIFY_EVENT_INVITE: - { - uint64 eventId = action.Invite.GetEventId(); - uint64 inviteId = action.Invite.GetInviteId(); +void CalendarMgr::RemoveAllPlayerEventsAndInvites(uint64 guid) +{ + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetCreatorGUID() == guid) + RemoveEvent((*itr)->GetEventId(), 0); // don't send mail if removing a character - CalendarEvent* calendarEvent = NULL; - if (action.GetInviteId() != action.Invite.GetInviteId()) - calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); - else - calendarEvent = GetEvent(eventId); + std::vector<CalendarInvite*> playerInvites = GetPlayerInvites(guid); + for (std::vector<CalendarInvite*>::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); +} - CalendarInvite* invite = GetInvite(inviteId); +void CalendarMgr::RemovePlayerGuildEventsAndSignups(uint64 guid, uint32 guildId) +{ + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement())) + RemoveEvent((*itr)->GetEventId(), guid); + + std::vector<CalendarInvite*> playerInvites = GetPlayerInvites(guid); + for (std::vector<CalendarInvite*>::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId())) + if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId) + RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); +} - if (!calendarEvent || !invite || !calendarEvent->HasInvite(inviteId)) - return; +CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) +{ + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetEventId() == eventId) + return *itr; - invite->SetStatus(action.Invite.GetStatus()); - SendCalendarEventStatus(invite->GetSenderGUID(), *calendarEvent, *invite); - break; - } - case CALENDAR_ACTION_MODIFY_MODERATOR_EVENT_INVITE: - { - uint64 eventId = action.Invite.GetEventId(); - uint64 inviteId = action.Invite.GetInviteId(); + sLog->outDebug(LOG_FILTER_CALENDAR, "CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId); + return NULL; +} - CalendarEvent* calendarEvent = NULL; - if (action.GetInviteId() != action.Invite.GetInviteId()) - calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_OWNER); - else - calendarEvent = GetEvent(eventId); +CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) +{ + for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + if ((*itr2)->GetInviteId() == inviteId) + return *itr2; - CalendarInvite* invite = GetInvite(inviteId); + sLog->outDebug(LOG_FILTER_CALENDAR, "CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId); + return NULL; +} - if (!calendarEvent || !invite || !calendarEvent->HasInvite(inviteId)) - return; +void CalendarMgr::FreeEventId(uint64 id) +{ + if (id == _maxEventId) + --_maxEventId; + else + _freeEventIds.push_back(id); +} - invite->SetStatus(action.Invite.GetStatus()); - SendCalendarEventModeratorStatusAlert(*invite); - break; - } - case CALENDAR_ACTION_REMOVE_EVENT_INVITE: - { - uint64 eventId = action.Invite.GetEventId(); - uint64 inviteId = action.Invite.GetInviteId(); - CalendarEvent* calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); - if (!calendarEvent) - return; - - // already checked in CheckPermisions - CalendarInvite* invite = GetInvite(inviteId); - if (!invite) - return; - - if (calendarEvent->GetCreatorGUID() == invite->GetInvitee()) - { - action.GetPlayer()->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_DELETE_CREATOR_FAILED); - return; - } - - if (uint64 invitee = RemoveInvite(inviteId)) - { - SendCalendarEventInviteRemoveAlert(invitee, *calendarEvent, CALENDAR_STATUS_9); - SendCalendarEventInviteRemove(action.GetPlayer()->GetGUID(), action.Invite, calendarEvent->GetFlags()); - } - break; - } - default: - break; +uint64 CalendarMgr::GetFreeEventId() +{ + if (_freeEventIds.empty()) + return ++_maxEventId; + else + { + uint64 eventId = _freeEventIds.front(); + _freeEventIds.pop_front(); + return eventId; } +} +void CalendarMgr::FreeInviteId(uint64 id) +{ + if (id == _maxInviteId) + --_maxInviteId; + else + _freeInviteIds.push_back(id); } -bool CalendarMgr::AddEvent(CalendarEvent const& newEvent) +uint64 CalendarMgr::GetFreeInviteId() { - uint64 eventId = newEvent.GetEventId(); - if (_events.find(eventId) != _events.end()) + if (_freeInviteIds.empty()) + return ++_maxInviteId; + else { - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddEvent: Event [" UI64FMTD "] exists", eventId); - return false; + uint64 inviteId = _freeInviteIds.front(); + _freeInviteIds.pop_front(); + return inviteId; } +} + +CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid) +{ + CalendarEventStore events; + + for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + if ((*itr2)->GetInviteeGUID() == guid) + events.insert(GetEvent(itr->first)); - _events[eventId] = newEvent; - return true; + if (Player* player = ObjectAccessor::FindPlayer(guid)) + for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) + if ((*itr)->GetGuildId() == player->GetGuildId()) + events.insert(*itr); + + return events; } -bool CalendarMgr::RemoveEvent(uint64 eventId) +std::vector<CalendarInvite*> CalendarMgr::GetEventInvites(uint64 eventId) { - CalendarEventMap::iterator itr = _events.find(eventId); - if (itr == _events.end()) - { - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::RemoveEvent: Event [" UI64FMTD "] does not exist", eventId); - return false; - } + return _invites[eventId]; +} - bool val = true; +std::vector<CalendarInvite*> CalendarMgr::GetPlayerInvites(uint64 guid) +{ + std::vector<CalendarInvite*> invites; - CalendarInviteIdList const& invites = itr->second.GetInviteIdList(); - for (CalendarInviteIdList::const_iterator itrInvites = invites.begin(); itrInvites != invites.end(); ++itrInvites) - { - CalendarInvite* invite = GetInvite(*itrInvites); - if (!invite || !RemovePlayerEvent(invite->GetInvitee(), eventId)) - val = false; + for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + if ((*itr2)->GetInviteeGUID() == guid) + invites.push_back(*itr2); - if (uint64 invitee = RemoveInvite(*itrInvites)) - SendCalendarEventRemovedAlert(invitee, itr->second); - } + return invites; +} + +uint32 CalendarMgr::GetPlayerNumPending(uint64 guid) +{ + std::vector<CalendarInvite*> const& invites = GetPlayerInvites(guid); - _events.erase(itr); + uint32 pendingNum = 0; + for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + // correct? + if ((*itr)->GetStatus() == CALENDAR_STATUS_INVITED || (*itr)->GetStatus() == CALENDAR_STATUS_TENTATIVE || (*itr)->GetStatus() == CALENDAR_STATUS_NOT_SIGNED_UP) + ++pendingNum; - return val; + return pendingNum; } -bool CalendarMgr::AddPlayerEvent(uint64 guid, uint64 eventId) +std::string CalendarEvent::BuildCalendarMailSubject(uint64 remover) const { - _playerEvents[guid].insert(eventId); - return true; + std::ostringstream strm; + strm << remover << ':' << _title; + return strm.str(); } -bool CalendarMgr::RemovePlayerEvent(uint64 guid, uint64 eventId) +std::string CalendarEvent::BuildCalendarMailBody() const { - _playerEvents[guid].erase(eventId); - return true; + WorldPacket data; + uint32 time; + std::ostringstream strm; + + // we are supposed to send PackedTime so i used WorldPacket to pack it + data.AppendPackedTime(_eventTime); + data >> time; + strm << time; + return strm.str(); } -bool CalendarMgr::AddInvite(CalendarInvite const& newInvite) +void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) { - uint64 inviteId = newInvite.GetInviteId(); - if (!inviteId) + CalendarEvent* calendarEvent = GetEvent(invite.GetEventId()); + time_t statusTime = invite.GetStatusTime(); + bool hasStatusTime = statusTime != 946684800; // 01/01/2000 00:00:00 + + uint64 invitee = invite.GetInviteeGUID(); + Player* player = ObjectAccessor::FindPlayer(invitee); + + uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee); + + WorldPacket data(SMSG_CALENDAR_EVENT_INVITE, 8 + 8 + 8 + 1 + 1 + 1 + (statusTime ? 4 : 0) + 1); + data.appendPackGUID(invitee); + data << uint64(invite.GetEventId()); + data << uint64(invite.GetInviteId()); + data << uint8(level); + data << uint8(invite.GetStatus()); + data << uint8(hasStatusTime); + if (hasStatusTime) + data.AppendPackedTime(statusTime); + data << uint8(invite.GetSenderGUID() != invite.GetInviteeGUID()); // false only if the invite is sign-up + + if (!calendarEvent) // Pre-invite { - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddInvite: Cant add Invite 0"); - return false; + if (Player* player = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) + player->SendDirectMessage(&data); } - - if (_invites.find(inviteId) != _invites.end()) + else { - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddInvite: Invite [" UI64FMTD "] exists", inviteId); - return false; + if (calendarEvent->GetCreatorGUID() != invite.GetInviteeGUID()) // correct? + SendPacketToAllEventRelatives(data, *calendarEvent); } - - _invites[inviteId] = newInvite; - uint64 guid = newInvite.GetInvitee(); - bool inviteAdded = AddPlayerInvite(guid, inviteId); - bool eventAdded = AddPlayerEvent(guid, newInvite.GetEventId()); - return eventAdded && inviteAdded; } -uint64 CalendarMgr::RemoveInvite(uint64 inviteId) +void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t oldEventTime) { - CalendarInviteMap::iterator itr = _invites.find(inviteId); - if (itr == _invites.end()) - { - sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::RemoveInvite: Invite [" UI64FMTD "] does not exist", inviteId); - return 0; - } - - uint64 invitee = itr->second.GetInvitee(); - _invites.erase(itr); - - return RemovePlayerInvite(invitee, inviteId) ? invitee : 0; + WorldPacket data(SMSG_CALENDAR_EVENT_UPDATED_ALERT, 1 + 8 + 4 + 4 + 4 + 1 + 4 + + calendarEvent.GetTitle().size() + calendarEvent.GetDescription().size() + 1 + 4 + 4); + data << uint8(1); // unk + data << uint64(calendarEvent.GetEventId()); + data.AppendPackedTime(oldEventTime); + data << uint32(calendarEvent.GetFlags()); + data.AppendPackedTime(calendarEvent.GetEventTime()); + data << uint8(calendarEvent.GetType()); + data << int32(calendarEvent.GetDungeonId()); + data << calendarEvent.GetTitle(); + data << calendarEvent.GetDescription(); + data << uint8(CALENDAR_REPEAT_NEVER); // repeatable + data << uint32(CALENDAR_MAX_INVITES); + data << uint32(0); // unk + + SendPacketToAllEventRelatives(data, calendarEvent); } -bool CalendarMgr::AddPlayerInvite(uint64 guid, uint64 inviteId) +void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) { - _playerInvites[guid].insert(inviteId); - return true; + WorldPacket data(SMSG_CALENDAR_EVENT_STATUS, 8 + 8 + 4 + 4 + 1 + 1 + 4); + data.appendPackGUID(invite.GetInviteeGUID()); + data << uint64(calendarEvent.GetEventId()); + data.AppendPackedTime(calendarEvent.GetEventTime()); + data << uint32(calendarEvent.GetFlags()); + data << uint8(invite.GetStatus()); + data << uint8(invite.GetRank()); + data.AppendPackedTime(invite.GetStatusTime()); + + SendPacketToAllEventRelatives(data, calendarEvent); } -bool CalendarMgr::RemovePlayerInvite(uint64 guid, uint64 inviteId) +void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) { - _playerInvites[guid].erase(inviteId); - return true; + WorldPacket data(SMSG_CALENDAR_EVENT_REMOVED_ALERT, 1 + 8 + 1); + data << uint8(1); // FIXME: If true does not SignalEvent(EVENT_CALENDAR_ACTION_PENDING) + data << uint64(calendarEvent.GetEventId()); + data.AppendPackedTime(calendarEvent.GetEventTime()); + + SendPacketToAllEventRelatives(data, calendarEvent); } -void CalendarMgr::SendCalendarEvent(CalendarEvent const& calendarEvent, CalendarSendEventType type) +void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags) { - if (Player* player = ObjectAccessor::FindPlayer(calendarEvent.GetCreatorGUID())) - player->GetSession()->SendCalendarEvent(calendarEvent, type); + WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED, 8 + 4 + 4 + 1); + data.appendPackGUID(invite.GetInviteeGUID()); + data << uint64(invite.GetEventId()); + data << uint32(flags); + data << uint8(1); // FIXME + + SendPacketToAllEventRelatives(data, calendarEvent); } -void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite, bool pending) +void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) { - if (Player* player = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) - player->GetSession()->SendCalendarEventInvite(invite, pending); + WorldPacket data(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, 8 + 8 + 1 + 1); + data.appendPackGUID(invite.GetInviteeGUID()); + data << uint64(invite.GetEventId()); + data << uint8(invite.GetRank()); + data << uint8(1); // Unk boolean - Display to client? + + SendPacketToAllEventRelatives(data, calendarEvent); } void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) { - if (Player* player = ObjectAccessor::FindPlayer(invite.GetInvitee())) - player->GetSession()->SendCalendarEventInviteAlert(calendarEvent, invite); + WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_ALERT); + data << uint64(calendarEvent.GetEventId()); + data << calendarEvent.GetTitle(); + data.AppendPackedTime(calendarEvent.GetEventTime()); + data << uint32(calendarEvent.GetFlags()); + data << uint32(calendarEvent.GetType()); + data << int32(calendarEvent.GetDungeonId()); + data << uint64(invite.GetInviteId()); + data << uint8(invite.GetStatus()); + data << uint8(invite.GetRank()); + data.appendPackGUID(calendarEvent.GetCreatorGUID()); + data.appendPackGUID(invite.GetSenderGUID()); + + if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) + { + if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId())) + guild->BroadcastPacket(&data); + } + else + if (Player* player = ObjectAccessor::FindPlayer(invite.GetInviteeGUID())) + player->SendDirectMessage(&data); } -void CalendarMgr::SendCalendarEventUpdateAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType type) +void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendCalendarEventUpdateAlert(calendarEvent, type); -} + Player* player = ObjectAccessor::FindPlayer(guid); + if (!player) + return; + + std::vector<CalendarInvite*> const& eventInviteeList = _invites[calendarEvent.GetEventId()]; + + WorldPacket data(SMSG_CALENDAR_SEND_EVENT, 60 + eventInviteeList.size() * 32); + data << uint8(sendType); + data.appendPackGUID(calendarEvent.GetCreatorGUID()); + data << uint64(calendarEvent.GetEventId()); + data << calendarEvent.GetTitle(); + data << calendarEvent.GetDescription(); + data << uint8(calendarEvent.GetType()); + data << uint8(CALENDAR_REPEAT_NEVER); // repeatable + data << uint32(CALENDAR_MAX_INVITES); + data << int32(calendarEvent.GetDungeonId()); + data << uint32(calendarEvent.GetFlags()); + data.AppendPackedTime(calendarEvent.GetEventTime()); + data.AppendPackedTime(calendarEvent.GetTimeZoneTime()); + data << uint32(calendarEvent.GetGuildId()); + + data << uint32(eventInviteeList.size()); + for (std::vector<CalendarInvite*>::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) + { + CalendarInvite const* calendarInvite = (*itr); + uint64 inviteeGuid = calendarInvite->GetInviteeGUID(); + Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid); + + uint8 inviteeLevel = invitee ? invitee->getLevel() : Player::GetLevelFromDB(inviteeGuid); + uint32 inviteeGuildId = invitee ? invitee->GetGuildId() : Player::GetGuildIdFromDB(inviteeGuid); + + data.appendPackGUID(inviteeGuid); + data << uint8(inviteeLevel); + data << uint8(calendarInvite->GetStatus()); + data << uint8(calendarInvite->GetRank()); + data << uint8(calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId); + data << uint64(calendarInvite->GetInviteId()); + data.AppendPackedTime(calendarInvite->GetStatusTime()); + data << calendarInvite->GetText(); + } -void CalendarMgr::SendCalendarEventStatus(uint64 guid, CalendarEvent const& calendarEvent, CalendarInvite const& invite) -{ - if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendCalendarEventStatus(calendarEvent, invite); + player->SendDirectMessage(&data); } -void CalendarMgr::SendCalendarEventRemovedAlert(uint64 guid, CalendarEvent const& calendarEvent) +void CalendarMgr::SendCalendarEventInviteRemoveAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendCalendarEventRemovedAlert(calendarEvent); + { + WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1); + data << uint64(calendarEvent.GetEventId()); + data.AppendPackedTime(calendarEvent.GetEventTime()); + data << uint32(calendarEvent.GetFlags()); + data << uint8(status); + + player->SendDirectMessage(&data); + } } -void CalendarMgr::SendCalendarEventInviteRemoveAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) +void CalendarMgr::SendCalendarClearPendingAction(uint64 guid) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendCalendarEventInviteRemoveAlert(calendarEvent, status); + { + WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0); + player->SendDirectMessage(&data); + } } -void CalendarMgr::SendCalendarEventInviteRemove(uint64 guid, CalendarInvite const& invite, uint32 flags) +void CalendarMgr::SendCalendarCommandResult(uint64 guid, CalendarError err, char const* param /*= NULL*/) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendCalendarEventInviteRemove(invite, flags); + { + WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0); + data << uint32(0); + data << uint8(0); + switch (err) + { + case CALENDAR_ERROR_OTHER_INVITES_EXCEEDED: + case CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S: + case CALENDAR_ERROR_IGNORING_YOU_S: + data << param; + break; + default: + data << uint8(0); + break; + } + + data << uint32(err); + + player->SendDirectMessage(&data); + } } -void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarInvite const& invite) +void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent) { - if (Player* player = ObjectAccessor::FindPlayer(invite.GetInvitee())) - player->GetSession()->SendCalendarEventModeratorStatusAlert(invite); + // Send packet to all guild members + if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) + if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId())) + guild->BroadcastPacket(&packet); + + // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them) + std::vector<CalendarInvite*> invites = _invites[calendarEvent.GetEventId()]; + for (std::vector<CalendarInvite*>::iterator itr = invites.begin(); itr != invites.end(); ++itr) + if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID())) + if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId())) + player->SendDirectMessage(&packet); } diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index a8749778cb3..db6acb667ec 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -19,60 +19,311 @@ #define TRINITY_CALENDARMGR_H #include <ace/Singleton.h> -#include "Calendar.h" +#include "Common.h" +#include "WorldPacket.h" + +enum CalendarMailAnswers +{ + // else + CALENDAR_EVENT_REMOVED_MAIL_SUBJECT = 0, + // if ( *(_DWORD *)(a1 + 8292) & 0x100 ) + CALENDAR_INVITE_REMOVED_MAIL_SUBJECT = 0x100 +}; + +enum CalendarFlags +{ + CALENDAR_FLAG_ALL_ALLOWED = 0x001, + CALENDAR_FLAG_INVITES_LOCKED = 0x010, + CALENDAR_FLAG_WITHOUT_INVITES = 0x040, + CALENDAR_FLAG_GUILD_EVENT = 0x400 +}; + +enum CalendarModerationRank +{ + CALENDAR_RANK_PLAYER = 0, + CALENDAR_RANK_MODERATOR = 1, + CALENDAR_RANK_OWNER = 2 +}; + +enum CalendarSendEventType +{ + CALENDAR_SENDTYPE_GET = 0, + CALENDAR_SENDTYPE_ADD = 1, + CALENDAR_SENDTYPE_COPY = 2 +}; + +enum CalendarEventType +{ + CALENDAR_TYPE_RAID = 0, + CALENDAR_TYPE_DUNGEON = 1, + CALENDAR_TYPE_PVP = 2, + CALENDAR_TYPE_MEETING = 3, + CALENDAR_TYPE_OTHER = 4 +}; + +enum CalendarRepeatType +{ + CALENDAR_REPEAT_NEVER = 0, + CALENDAR_REPEAT_WEEKLY = 1, + CALENDAR_REPEAT_BIWEEKLY = 2, + CALENDAR_REPEAT_MONTHLY = 3 +}; + +enum CalendarInviteStatus +{ + CALENDAR_STATUS_INVITED = 0, + CALENDAR_STATUS_ACCEPTED = 1, + CALENDAR_STATUS_DECLINED = 2, + CALENDAR_STATUS_CONFIRMED = 3, + CALENDAR_STATUS_OUT = 4, + CALENDAR_STATUS_STANDBY = 5, + CALENDAR_STATUS_SIGNED_UP = 6, + CALENDAR_STATUS_NOT_SIGNED_UP = 7, + CALENDAR_STATUS_TENTATIVE = 8, + CALENDAR_STATUS_REMOVED = 9 // correct name? +}; + +enum CalendarError +{ + CALENDAR_OK = 0, + CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED = 1, + CALENDAR_ERROR_EVENTS_EXCEEDED = 2, + CALENDAR_ERROR_SELF_INVITES_EXCEEDED = 3, + CALENDAR_ERROR_OTHER_INVITES_EXCEEDED = 4, + CALENDAR_ERROR_PERMISSIONS = 5, + CALENDAR_ERROR_EVENT_INVALID = 6, + CALENDAR_ERROR_NOT_INVITED = 7, + CALENDAR_ERROR_INTERNAL = 8, + CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD = 9, + CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S = 10, + CALENDAR_ERROR_PLAYER_NOT_FOUND = 11, + CALENDAR_ERROR_NOT_ALLIED = 12, + CALENDAR_ERROR_IGNORING_YOU_S = 13, + CALENDAR_ERROR_INVITES_EXCEEDED = 14, + CALENDAR_ERROR_INVALID_DATE = 16, + CALENDAR_ERROR_INVALID_TIME = 17, + + CALENDAR_ERROR_NEEDS_TITLE = 19, + CALENDAR_ERROR_EVENT_PASSED = 20, + CALENDAR_ERROR_EVENT_LOCKED = 21, + CALENDAR_ERROR_DELETE_CREATOR_FAILED = 22, + CALENDAR_ERROR_SYSTEM_DISABLED = 24, + CALENDAR_ERROR_RESTRICTED_ACCOUNT = 25, + CALENDAR_ERROR_ARENA_EVENTS_EXCEEDED = 26, + CALENDAR_ERROR_RESTRICTED_LEVEL = 27, + CALENDAR_ERROR_USER_SQUELCHED = 28, + CALENDAR_ERROR_NO_INVITE = 29, + + CALENDAR_ERROR_EVENT_WRONG_SERVER = 36, + CALENDAR_ERROR_INVITE_WRONG_SERVER = 37, + CALENDAR_ERROR_NO_GUILD_INVITES = 38, + CALENDAR_ERROR_INVALID_SIGNUP = 39, + CALENDAR_ERROR_NO_MODERATOR = 40 +}; + +#define CALENDAR_MAX_EVENTS 30 +#define CALENDAR_MAX_GUILD_EVENTS 100 +#define CALENDAR_MAX_INVITES 100 + +struct CalendarInvite +{ + public: + CalendarInvite(CalendarInvite const& calendarInvite, uint64 inviteId, uint64 eventId) + { + _inviteId = inviteId; + _eventId = eventId; + _invitee = calendarInvite.GetInviteeGUID(); + _senderGUID = calendarInvite.GetSenderGUID(); + _statusTime = calendarInvite.GetStatusTime(); + _status = calendarInvite.GetStatus(); + _rank = calendarInvite.GetRank(); + _text = calendarInvite.GetText(); + } + + CalendarInvite() : _inviteId(1), _eventId(0), _invitee(0), _senderGUID(0), _statusTime(time(NULL)), + _status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _text("") { } + + CalendarInvite(uint64 inviteId, uint64 eventId, uint64 invitee, uint64 senderGUID, time_t statusTime, + CalendarInviteStatus status, CalendarModerationRank rank, std::string text) : + _inviteId(inviteId), _eventId(eventId), _invitee(invitee), _senderGUID(senderGUID), _statusTime(statusTime), + _status(status), _rank(rank), _text(text) { } + + ~CalendarInvite(); + + void SetInviteId(uint64 inviteId) { _inviteId = inviteId; } + uint64 GetInviteId() const { return _inviteId; } + + void SetEventId(uint64 eventId) { _eventId = eventId; } + uint64 GetEventId() const { return _eventId; } + + void SetSenderGUID(uint64 guid) { _senderGUID = guid; } + uint64 GetSenderGUID() const { return _senderGUID; } + + void SetInvitee(uint64 guid) { _invitee = guid; } + uint64 GetInviteeGUID() const { return _invitee; } + + void SetStatusTime(time_t statusTime) { _statusTime = statusTime; } + time_t GetStatusTime() const { return _statusTime; } + + void SetText(std::string text) { _text = text; } + std::string GetText() const { return _text; } + + void SetStatus(CalendarInviteStatus status) { _status = status; } + CalendarInviteStatus GetStatus() const { return _status; } + + void SetRank(CalendarModerationRank rank) { _rank = rank; } + CalendarModerationRank GetRank() const { return _rank; } + + private: + uint64 _inviteId; + uint64 _eventId; + uint64 _invitee; + uint64 _senderGUID; + time_t _statusTime; + CalendarInviteStatus _status; + CalendarModerationRank _rank; + std::string _text; +}; + +struct CalendarEvent +{ + public: + CalendarEvent(CalendarEvent const& calendarEvent, uint64 eventId) + { + _eventId = eventId; + _creatorGUID = calendarEvent.GetCreatorGUID(); + _guildId = calendarEvent.GetGuildId(); + _type = calendarEvent.GetType(); + _dungeonId = calendarEvent.GetDungeonId(); + _eventTime = calendarEvent.GetEventTime(); + _flags = calendarEvent.GetFlags(); + _timezoneTime = calendarEvent.GetTimeZoneTime(); + _title = calendarEvent.GetTitle(); + _description = calendarEvent.GetDescription(); + } + + CalendarEvent(uint64 eventId, uint64 creatorGUID, uint32 guildId, CalendarEventType type, int32 dungeonId, + time_t eventTime, uint32 flags, time_t timezoneTime, std::string title, std::string description) : + _eventId(eventId), _creatorGUID(creatorGUID), _guildId(guildId), _type(type), _dungeonId(dungeonId), + _eventTime(eventTime), _flags(flags), _timezoneTime(timezoneTime), _title(title), + _description(description) { } + + CalendarEvent() : _eventId(1), _creatorGUID(0), _guildId(0), _type(CALENDAR_TYPE_OTHER), _dungeonId(-1), _eventTime(0), + _flags(0), _timezoneTime(0), _title(""), _description("") { } + + ~CalendarEvent(); + + void SetEventId(uint64 eventId) { _eventId = eventId; } + uint64 GetEventId() const { return _eventId; } + + void SetCreatorGUID(uint64 guid) { _creatorGUID = guid; } + uint64 GetCreatorGUID() const { return _creatorGUID; } + + void SetGuildId(uint32 guildId) { _guildId = guildId; } + uint32 GetGuildId() const { return _guildId; } + + void SetTitle(std::string title) { _title = title; } + std::string GetTitle() const { return _title; } + + void SetDescription(std::string description) { _description = description; } + std::string GetDescription() const { return _description; } + + void SetType(CalendarEventType type) { _type = type; } + CalendarEventType GetType() const { return _type; } + + void SetDungeonId(int32 dungeonId) { _dungeonId = dungeonId; } + int32 GetDungeonId() const { return _dungeonId; } + + void SetEventTime(time_t eventTime) { _eventTime = eventTime; } + time_t GetEventTime() const { return _eventTime; } + + void SetFlags(uint32 flags) { _flags = flags; } + uint32 GetFlags() const { return _flags; } + + void SetTimeZoneTime(time_t timezoneTime) { _timezoneTime = timezoneTime; } + time_t GetTimeZoneTime() const { return _timezoneTime; } + + bool IsGuildEvent() const { return _flags & CALENDAR_FLAG_GUILD_EVENT; } + bool IsGuildAnnouncement() const { return _flags & CALENDAR_FLAG_WITHOUT_INVITES; } + + std::string BuildCalendarMailSubject(uint64 remover) const; + std::string BuildCalendarMailBody() const; + + private: + uint64 _eventId; + uint64 _creatorGUID; + uint32 _guildId; + CalendarEventType _type; + int32 _dungeonId; + time_t _eventTime; + uint32 _flags; + time_t _timezoneTime; + std::string _title; + std::string _description; +}; + +typedef std::set<CalendarEvent*> CalendarEventStore; +typedef std::map<uint64 /* eventId */, std::vector<CalendarInvite*> > CalendarInviteStore; class CalendarMgr { - friend class ACE_Singleton<CalendarMgr, ACE_Null_Mutex>; + friend class ACE_Singleton<CalendarMgr, ACE_Null_Mutex>; + private: CalendarMgr(); ~CalendarMgr(); + CalendarEventStore _events; + CalendarInviteStore _invites; + + std::deque<uint64> _freeEventIds; + std::deque<uint64> _freeInviteIds; + uint64 _maxEventId; + uint64 _maxInviteId; + public: void LoadFromDB(); - CalendarInvite* GetInvite(uint64 inviteId); CalendarEvent* GetEvent(uint64 eventId); + CalendarEventStore const& GetEvents() const { return _events; } + CalendarEventStore GetPlayerEvents(uint64 guid); - CalendarInviteIdList const& GetPlayerInvites(uint64 guid); - CalendarEventIdList const& GetPlayerEvents(uint64 guid); + CalendarInvite* GetInvite(uint64 inviteId); + CalendarInviteStore const& GetInvites() const { return _invites; } + std::vector<CalendarInvite*> GetEventInvites(uint64 eventId); + std::vector<CalendarInvite*> GetPlayerInvites(uint64 guid); - uint32 GetPlayerNumPending(uint64 guid); + void FreeEventId(uint64 id); uint64 GetFreeEventId(); + void FreeInviteId(uint64 id); uint64 GetFreeInviteId(); - void AddAction(CalendarAction const& action); - - void SendCalendarEvent(CalendarEvent const& calendarEvent, CalendarSendEventType type); - void SendCalendarEventInvite(CalendarInvite const& invite, bool pending); - void SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite); - void SendCalendarEventInviteRemove(uint64 guid, CalendarInvite const& invite, uint32 flags); - void SendCalendarEventInviteRemoveAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status); - void SendCalendarEventUpdateAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType type); - void SendCalendarEventStatus(uint64 guid, CalendarEvent const& calendarEvent, CalendarInvite const& invite); - void SendCalendarEventRemovedAlert(uint64 guid, CalendarEvent const& calendarEvent); - void SendCalendarEventModeratorStatusAlert(CalendarInvite const& invite); + uint32 GetPlayerNumPending(uint64 guid); - private: - CalendarEvent* CheckPermisions(uint64 eventId, Player* player, uint64 inviteId, CalendarModerationRank minRank); + void AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType); + void RemoveEvent(uint64 eventId, uint64 remover); + void UpdateEvent(CalendarEvent* calendarEvent); - bool AddEvent(CalendarEvent const& calendarEvent); - bool RemoveEvent(uint64 eventId); - bool AddPlayerEvent(uint64 guid, uint64 eventId); - bool RemovePlayerEvent(uint64 guid, uint64 eventId); + void AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite); + void RemoveInvite(uint64 inviteId, uint64 eventId, uint64 remover); + void UpdateInvite(CalendarInvite* invite); - bool AddInvite(CalendarInvite const& invite); - uint64 RemoveInvite(uint64 inviteId); - bool AddPlayerInvite(uint64 guid, uint64 inviteId); - bool RemovePlayerInvite(uint64 guid, uint64 inviteId); + void RemoveAllPlayerEventsAndInvites(uint64 guid); + void RemovePlayerGuildEventsAndSignups(uint64 guid, uint32 guildId); - CalendarEventMap _events; - CalendarInviteMap _invites; - CalendarPlayerInviteIdMap _playerInvites; - CalendarPlayerEventIdMap _playerEvents; + void SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType); + void SendCalendarEventInvite(CalendarInvite const& invite); + void SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite); + void SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags); + void SendCalendarEventInviteRemoveAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status); + void SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t oldEventTime); + void SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite); + void SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent); + void SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite); + void SendCalendarClearPendingAction(uint64 guid); + void SendCalendarCommandResult(uint64 guid, CalendarError err, char const* param = NULL); - uint64 _eventNum; - uint64 _inviteNum; + void SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent); }; #define sCalendarMgr ACE_Singleton<CalendarMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4db293f0e89..e1be2049dad 100755 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -25,6 +25,7 @@ #include "SocialMgr.h" #include "Log.h" #include "AccountMgr.h" +#include "CalendarMgr.h" #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -1579,6 +1580,8 @@ void Guild::HandleLeaveMember(WorldSession* session) SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_COMMAND_SUCCESS, m_name); } + + sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId()); } void Guild::HandleRemoveMember(WorldSession* session, std::string const& name) @@ -2138,6 +2141,39 @@ void Guild::BroadcastPacket(WorldPacket* packet) const player->GetSession()->SendPacket(packet); } +void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank) +{ + uint32 count = 0; + + WorldPacket data(SMSG_CALENDAR_FILTER_GUILD); + data << uint32(count); // count placeholder + + for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + { + // not sure if needed, maybe client checks it as well + if (count >= CALENDAR_MAX_INVITES) + { + if (Player* player = session->GetPlayer()) + sCalendarMgr->SendCalendarCommandResult(player->GetGUID(), CALENDAR_ERROR_INVITES_EXCEEDED); + return; + } + + Member* member = itr->second; + uint32 level = Player::GetLevelFromDB(member->GetGUID()); + + if (member->GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member->IsRankNotLower(minRank)) + { + data.appendPackGUID(member->GetGUID()); + data << uint8(0); // unk + ++count; + } + } + + data.put<uint32>(0, count); + + session->SendPacket(&data); +} + // Members handling bool Guild::AddMember(uint64 guid, uint8 rankId) { diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index a8bf5dcdb62..2f43245159b 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -711,6 +711,8 @@ public: void BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const; void BroadcastPacket(WorldPacket* packet) const; + void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank); + template<class Do> void BroadcastWorker(Do& _do, Player* except = NULL) { diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 0cecd3d615a..8eb52ee3c0a 100755 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -19,131 +19,116 @@ /* ----- Opcodes Not Used yet ----- -SMSG_CALENDAR_CLEAR_PENDING_ACTION SendCalendarClearPendingAction() -SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save) - ------ Opcodes without Sniffs ----- -SMSG_CALENDAR_FILTER_GUILD [ for (... uint32(count) { packguid(???), uint8(???) } ] -SMSG_CALENDAR_ARENA_TEAM [ for (... uint32(count) { packguid(???), uint8(???) } ] -CMSG_CALENDAR_EVENT_INVITE_NOTES [ packguid(Invitee), uint64(inviteId), string(Text), Boolean(Unk) ] -SMSG_CALENDAR_EVENT_INVITE_NOTES [ uint32(unk1), uint32(unk2), uint32(unk3), uint32(unk4), uint32(unk5) ] +SMSG_CALENDAR_EVENT_INVITE_NOTES [ packguid(Invitee), uint64(inviteId), string(Text), Boolean(Unk) ] +?CMSG_CALENDAR_EVENT_INVITE_NOTES [ uint32(unk1), uint32(unk2), uint32(unk3), uint32(unk4), uint32(unk5) ] SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT [ uint64(inviteId), string(Text) ] -SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT [ Structure unkown ] +SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT [ uint64(eventId), uint32(eventTime), uint32(unkFlag), uint8(deletePending) ] +SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save) -*/ +----- TODO ----- -#include "Common.h" -#include "WorldPacket.h" -#include "WorldSession.h" +Finish complains' handling - what to do with received complains and how to respond? +Find out what to do with all "not used yet" opcodes +Correct errors sending (event/invite not found, invites exceeded, event already passed, permissions etc.) +Fix locked events to be displayed properly and response time shouldn't be shown for people that haven't respond yet +Copied events should probably have a new owner + +*/ #include "InstanceSaveMgr.h" #include "Log.h" #include "Opcodes.h" #include "Player.h" +#include "SocialMgr.h" #include "CalendarMgr.h" #include "ObjectMgr.h" #include "ObjectAccessor.h" #include "DatabaseEnv.h" +#include "GuildMgr.h" +#include "ArenaTeamMgr.h" +#include "WorldSession.h" void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) { uint64 guid = _player->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GET_CALENDAR [" UI64FMTD "]", guid); - time_t cur_time = time_t(time(NULL)); + time_t currTime = time(NULL); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_CALENDAR [" UI64FMTD "]", guid); - WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Impossible to get the correct size without doing a double iteration of some elements + WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance - CalendarInviteIdList const& invites = sCalendarMgr->GetPlayerInvites(guid); + std::vector<CalendarInvite*> invites = sCalendarMgr->GetPlayerInvites(guid); data << uint32(invites.size()); - for (CalendarInviteIdList::const_iterator it = invites.begin(); it != invites.end(); ++it) + for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) { - CalendarInvite* invite = sCalendarMgr->GetInvite(*it); - CalendarEvent* calendarEvent = invite ? sCalendarMgr->GetEvent(invite->GetEventId()) : NULL; + data << uint64((*itr)->GetEventId()); + data << uint64((*itr)->GetInviteId()); + data << uint8((*itr)->GetStatus()); + data << uint8((*itr)->GetRank()); - if (calendarEvent) + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent((*itr)->GetEventId())) { - data << uint64(invite->GetEventId()); - data << uint64(invite->GetInviteId()); - data << uint8(invite->GetStatus()); - data << uint8(invite->GetRank()); - data << uint8(calendarEvent->GetGuildId() != 0); + data << uint8(calendarEvent->IsGuildEvent()); data.appendPackGUID(calendarEvent->GetCreatorGUID()); } else { - sLog->outError(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_CALENDAR: No Invite found with id [" UI64FMTD "]", *it); - data << uint64(0); - data << uint64(0); - data << uint8(0); data << uint8(0); - data << uint8(0); - data.appendPackGUID(0); + data.appendPackGUID((*itr)->GetSenderGUID()); } } - CalendarEventIdList const& events = sCalendarMgr->GetPlayerEvents(guid); - data << uint32(events.size()); - for (CalendarEventIdList::const_iterator it = events.begin(); it != events.end(); ++it) + CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid); + data << uint32(playerEvents.size()); + for (CalendarEventStore::const_iterator itr = playerEvents.begin(); itr != playerEvents.end(); ++itr) { - if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(*it)) - { - data << uint64(*it); - data << calendarEvent->GetTitle(); - data << uint32(calendarEvent->GetType()); - data.AppendPackedTime(calendarEvent->GetTime()); - data << uint32(calendarEvent->GetFlags()); - data << uint32(calendarEvent->GetDungeonId()); - data.appendPackGUID(calendarEvent->GetCreatorGUID()); - } - else - { - sLog->outError(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_CALENDAR: No Event found with id [" UI64FMTD "]", *it); - data << uint64(0); - data << uint8(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data.appendPackGUID(0); - } + CalendarEvent* calendarEvent = *itr; + + data << uint64(calendarEvent->GetEventId()); + data << calendarEvent->GetTitle(); + data << uint32(calendarEvent->GetType()); + data.AppendPackedTime(calendarEvent->GetEventTime()); + data << uint32(calendarEvent->GetFlags()); + data << int32(calendarEvent->GetDungeonId()); + data.appendPackGUID(calendarEvent->GetCreatorGUID()); } - data << uint32(cur_time); // server time - data.AppendPackedTime(cur_time); // server time - - uint32 counter = 0; - size_t p_counter = data.wpos(); - data << uint32(counter); // instance save count + data << uint32(currTime); // server time + data.AppendPackedTime(currTime); // zone time + ByteBuffer dataBuffer; + uint32 boundCounter = 0; for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr) + { + Player::BoundInstancesMap boundInstances = _player->GetBoundInstances(Difficulty(i)); + for (Player::BoundInstancesMap::const_iterator itr = boundInstances.begin(); itr != boundInstances.end(); ++itr) + { if (itr->second.perm) { InstanceSave const* save = itr->second.save; - data << uint32(save->GetMapId()); - data << uint32(save->GetDifficulty()); - data << uint32(save->GetResetTime() - cur_time); - data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id - ++counter; + dataBuffer << uint32(save->GetMapId()); + dataBuffer << uint32(save->GetDifficulty()); + dataBuffer << uint32(save->GetResetTime() - currTime); + dataBuffer << uint64(save->GetInstanceId()); // instance save id as unique instance copy id + ++boundCounter; } + } + } - data.put<uint32>(p_counter, counter); - - data << uint32(1135753200); // unk (28.12.2005 07:00) + data << uint32(boundCounter); + data.append(dataBuffer); - counter = 0; - p_counter = data.wpos(); - data << uint32(counter); // raid reset count + data << uint32(1135753200); // Constant date, unk (28.12.2005 07:00) + // Reuse variables + boundCounter = 0; std::set<uint32> sentMaps; + dataBuffer.clear(); ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap(); for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr) { uint32 mapId = PAIR32_LOPART(itr->first); - if (sentMaps.find(mapId) != sentMaps.end()) continue; @@ -153,12 +138,14 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) sentMaps.insert(mapId); - data << uint32(mapId); - data << uint32(itr->second - cur_time); - data << uint32(mapEntry->unk_time); - ++counter; + dataBuffer << int32(mapId); + dataBuffer << int32(itr->second - currTime); + dataBuffer << int32(0); // Never seen anything else in sniffs - still unknown + ++boundCounter; } - data.put<uint32>(p_counter, counter); + + data << uint32(boundCounter); + data.append(dataBuffer); // TODO: Fix this, how we do know how many and what holidays to send? uint32 holidayCount = 0; @@ -174,7 +161,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) data << uint32(holiday->CalendarFilterType); // m_calendarFilterType for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j) - data << uint32(holiday->Date[j]); // 26 * m_date + data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ? for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j) data << uint32(holiday->Duration[j]); // 10 * m_duration @@ -193,133 +180,114 @@ void WorldSession::HandleCalendarGetEvent(WorldPacket& recvData) uint64 eventId; recvData >> eventId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GET_EVENT. Event: [" + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GET_EVENT. Player [" UI64FMTD "] Event [" UI64FMTD "]", _player->GetGUID(), eventId); if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) - SendCalendarEvent(*calendarEvent, CALENDAR_SENDTYPE_GET); + sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET); + else + sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarGuildFilter(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GUILD_FILTER [" UI64FMTD "]", _player->GetGUID()); - int32 unk1, unk2, unk3; - recvData >> unk1; - recvData >> unk2; - recvData >> unk3; + uint32 minLevel; + uint32 maxLevel; + uint32 minRank; + + recvData >> minLevel >> maxLevel >> minRank; + + if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) + guild->MassInviteToEvent(this, minLevel, maxLevel, minRank); - sLog->outDebug(LOG_FILTER_NETWORKIO, "Calendar: CMSG_CALENDAR_GUILD_FILTER - unk1: %d unk2: %d unk3: %d", unk1, unk2, unk3); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GUILD_FILTER: Min level [%d], Max level [%d], Min rank [%d]", minLevel, maxLevel, minRank); } void WorldSession::HandleCalendarArenaTeam(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_ARENA_TEAM [" UI64FMTD "]", _player->GetGUID()); - int32 unk1; - recvData >> unk1; + uint32 arenaTeamId; + recvData >> arenaTeamId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "Calendar: CMSG_CALENDAR_ARENA_TEAM - unk1: %d", unk1); + if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenaTeamId)) + team->MassInviteToEvent(this); } void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); + std::string title; std::string description; uint8 type; - bool repeatable; + uint8 repeatable; uint32 maxInvites; int32 dungeonId; uint32 eventPackedTime; uint32 unkPackedTime; uint32 flags; - uint64 inviteId = 0; - uint64 invitee = 0; - uint8 status; - uint8 rank; - recvData >> title >> description >> type >> repeatable >> maxInvites; - recvData >> dungeonId; + recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData.ReadPackedTime(unkPackedTime); recvData >> flags; - if (!(flags & CALENDAR_FLAG_WITHOUT_INVITES)) + 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()); + + if (calendarEvent->IsGuildAnnouncement()) + { + // 946684800 is 01/01/2000 00:00:00 - default response time + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); + sCalendarMgr->AddInvite(calendarEvent, invite); + } + else { uint32 inviteCount; recvData >> inviteCount; - recvData.readPackGUID(invitee); - recvData >> status >> rank; - if (inviteCount != 1 || invitee != guid) + for (uint32 i = 0; i < inviteCount; ++i) { - sLog->outError(LOG_FILTER_NETWORKIO, "HandleCalendarAddEvent: [" UI64FMTD - "]: More than one invite (%d) or Invitee [" UI64FMTD - "] differs", guid, inviteCount, invitee); - return; + uint64 invitee = 0; + uint8 status = 0; + uint8 rank = 0; + recvData.readPackGUID(invitee); + recvData >> status >> rank; + + // 946684800 is 01/01/2000 00:00:00 - default response time + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), ""); + sCalendarMgr->AddInvite(calendarEvent, invite); } - - inviteId = sCalendarMgr->GetFreeInviteId(); - } - else - { - inviteId = 0; - status = CALENDAR_STATUS_NO_OWNER; - rank = CALENDAR_RANK_PLAYER; } - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_ADD_EVENT: [" UI64FMTD "] " - "Title %s, Description %s, type %u, Repeatable %u, MaxInvites %u, " - "Dungeon ID %d, Time %u, Time2 %u, Flags %u, Invitee [" UI64FMTD "] " - "Status %d, Rank %d", guid, title.c_str(), description.c_str(), - type, repeatable, maxInvites, dungeonId, eventPackedTime, - unkPackedTime, flags, invitee, status, rank); - - CalendarAction action; - - action.SetAction(CALENDAR_ACTION_ADD_EVENT); - action.SetPlayer(_player); - action.Event.SetEventId(sCalendarMgr->GetFreeEventId()); - action.Event.SetCreatorGUID(guid); - action.Event.SetType((CalendarEventType) type); - action.Event.SetFlags(flags); - action.Event.SetTime(eventPackedTime); - action.Event.SetTimeZoneTime(unkPackedTime); - action.Event.SetRepeatable(repeatable); - action.Event.SetMaxInvites(maxInvites); - action.Event.SetDungeonId(dungeonId); - action.Event.SetGuildId((flags & CALENDAR_FLAG_GUILD_ONLY) ? GetPlayer()->GetGuildId() : 0); - action.Event.SetTitle(title); - action.Event.SetDescription(description); - action.Event.AddInvite(inviteId); - action.Invite.SetEventId(action.Event.GetEventId()); - action.Invite.SetInviteId(inviteId); - action.Invite.SetInvitee(invitee); - action.Invite.SetStatus((CalendarInviteStatus) status); - action.Invite.SetRank((CalendarModerationRank) rank); - action.Invite.SetSenderGUID(guid); - - sCalendarMgr->AddAction(action); + sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD); } void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); + time_t oldEventTime; + uint64 eventId; uint64 inviteId; std::string title; std::string description; uint8 type; - bool repeatable; + uint8 repetitionType; uint32 maxInvites; int32 dungeonId; uint32 eventPackedTime; uint32 timeZoneTime; uint32 flags; - recvData >> eventId >> inviteId >> title >> description >> type; - recvData >> repeatable >> maxInvites >> dungeonId; + recvData >> eventId >> inviteId >> title >> description >> type >> repetitionType >> maxInvites >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData.ReadPackedTime(timeZoneTime); recvData >> flags; @@ -328,46 +296,37 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) "], InviteId [" UI64FMTD "] Title %s, Description %s, type %u " "Repeatable %u, MaxInvites %u, Dungeon ID %d, Time %u " "Time2 %u, Flags %u", guid, eventId, inviteId, title.c_str(), - description.c_str(), type, repeatable, maxInvites, dungeonId, + description.c_str(), type, repetitionType, maxInvites, dungeonId, eventPackedTime, timeZoneTime, flags); - CalendarAction action; - action.SetAction(CALENDAR_ACTION_MODIFY_EVENT); - action.SetPlayer(_player); - action.SetInviteId(inviteId); - action.Event.SetEventId(eventId); - action.Event.SetType((CalendarEventType) type); - action.Event.SetFlags((CalendarFlags) flags); - action.Event.SetTime(eventPackedTime); - action.Event.SetTimeZoneTime(timeZoneTime); - action.Event.SetRepeatable(repeatable); - action.Event.SetDungeonId(dungeonId); - action.Event.SetTitle(title); - action.Event.SetDescription(description); - action.Event.SetMaxInvites(maxInvites); - - sCalendarMgr->AddAction(action); + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + oldEventTime = calendarEvent->GetEventTime(); + + calendarEvent->SetType(CalendarEventType(type)); + calendarEvent->SetFlags(flags); + calendarEvent->SetEventTime(time_t(eventPackedTime)); + calendarEvent->SetTimeZoneTime(time_t(timeZoneTime)); // Not sure, seems constant from the little sniffs we have + calendarEvent->SetDungeonId(dungeonId); + calendarEvent->SetTitle(title); + calendarEvent->SetDescription(description); + + sCalendarMgr->UpdateEvent(calendarEvent); + sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarRemoveEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); uint64 eventId; - uint64 inviteId; - uint32 flags; - recvData >> eventId >> inviteId >> flags; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_REMOVE_EVENT [" UI64FMTD "], EventId [" UI64FMTD - "] inviteId [" UI64FMTD "] Flags?: %u", guid, eventId, inviteId, flags); - - CalendarAction action; - action.SetAction(CALENDAR_ACTION_REMOVE_EVENT); - action.SetPlayer(_player); - action.SetInviteId(inviteId); - action.Event.SetEventId(eventId); - action.Event.SetFlags((CalendarFlags) flags); + recvData >> eventId; + recvData.rfinish(); // Skip flags & invite ID, we don't use them - sCalendarMgr->AddAction(action); + sCalendarMgr->RemoveEvent(eventId, guid); } void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) @@ -382,94 +341,140 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_COPY_EVENT [" UI64FMTD "], EventId [" UI64FMTD "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, time); - CalendarAction action; - action.SetAction(CALENDAR_ACTION_COPY_EVENT); - action.SetPlayer(_player); - action.SetInviteId(inviteId); - action.Event.SetEventId(eventId); - action.Event.SetTime(time); + if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId)) + { + CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId()); + newEvent->SetEventTime(time_t(time)); + sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY); + + std::vector<CalendarInvite*> invites = sCalendarMgr->GetEventInvites(eventId); + + for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId())); - sCalendarMgr->AddAction(action); + // should we change owner when somebody makes a copy of event owned by another person? + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) { - uint64 guid = _player->GetGUID(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_INVITE"); + + uint64 playerGuid = _player->GetGUID(); + uint64 eventId; uint64 inviteId; std::string name; - uint8 status; - uint8 rank; - uint64 invitee = 0; - uint32 team = 0; + bool isPreInvite; + bool isGuildEvent; + + uint64 inviteeGuid = 0; + uint32 inviteeTeam = 0; + uint32 inviteeGuildId = 0; - recvData >> eventId >> inviteId >> name >> status >> rank; - if (Player* player = sObjectAccessor->FindPlayerByName(name)) + recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent; + + if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str())) { - invitee = player->GetGUID(); - team = player->GetTeam(); + // Invitee is online + inviteeGuid = player->GetGUID(); + inviteeTeam = player->GetTeam(); + inviteeGuildId = player->GetGuildId(); } else { + // Invitee offline, get data from database PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME); stmt->setString(0, name); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); - invitee = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - team = Player::TeamForRace(fields[1].GetUInt8()); + inviteeGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + inviteeTeam = Player::TeamForRace(fields[1].GetUInt8()); + inviteeGuildId = Player::GetGuildIdFromDB(inviteeGuid); } } - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_INVITE [" UI64FMTD "], EventId [" - UI64FMTD "] InviteId [" UI64FMTD "] Name %s ([" UI64FMTD "]), status %u, " - "Rank %u", guid, eventId, inviteId, name.c_str(), invitee, status, rank); - - if (!invitee) + if (!inviteeGuid) { - SendCalendarCommandResult(CALENDAR_ERROR_PLAYER_NOT_FOUND); + sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND); return; } - if (_player->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR)) + if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR)) { - SendCalendarCommandResult(CALENDAR_ERROR_NOT_ALLIED); + sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED); return; } - // TODO: Check ignore, even if offline (db query) + if (QueryResult result = CharacterDatabase.PQuery("SELECT flags FROM character_social WHERE guid = " UI64FMTD " AND friend = " UI64FMTD, inviteeGuid, playerGuid)) + { + Field* fields = result->Fetch(); + if (fields[0].GetUInt8() & SOCIAL_FLAG_IGNORED) + { + sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str()); + return; + } + } + + if (!isPreInvite) + { + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId) + { + // we can't invite guild members to guild events + sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); + return; + } - CalendarAction action; - action.SetAction(CALENDAR_ACTION_ADD_EVENT_INVITE); - action.SetPlayer(_player); - action.SetInviteId(inviteId); - action.Invite.SetEventId(eventId); - action.Invite.SetInviteId(sCalendarMgr->GetFreeInviteId()); - action.Invite.SetSenderGUID(_player->GetGUID()); - action.Invite.SetInvitee(invitee); - action.Invite.SetRank((CalendarModerationRank) rank); - action.Invite.SetStatus((CalendarInviteStatus) status); + // 946684800 is 01/01/2000 00:00:00 - default response time + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); + sCalendarMgr->AddInvite(calendarEvent, invite); + } + else + sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID); + } + else + { + if (isGuildEvent && inviteeGuildId == _player->GetGuildId()) + { + sCalendarMgr->SendCalendarCommandResult(inviteeGuid, CALENDAR_ERROR_NO_GUILD_INVITES); + return; + } - sCalendarMgr->AddAction(action); + // 946684800 is 01/01/2000 00:00:00 - default response time + CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); + sCalendarMgr->SendCalendarEventInvite(*invite); + } } void WorldSession::HandleCalendarEventSignup(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); uint64 eventId; - uint8 status; + bool tentative; + + recvData >> eventId >> tentative; + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_SIGNUP [" UI64FMTD "] EventId [" UI64FMTD "] Tentative %u", guid, eventId, tentative); - recvData >> eventId >> status; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_SIGNUP [" UI64FMTD "] EventId [" - UI64FMTD "] Status %u", guid, eventId, status); - - CalendarAction action; - action.SetAction(CALENDAR_ACTION_SIGNUP_TO_EVENT); - action.SetPlayer(_player); - action.SetExtraData(GetPlayer()->GetGuildId()); - action.Event.SetEventId(eventId); - action.Invite.SetStatus((CalendarInviteStatus) status); - sCalendarMgr->AddAction(action); + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId()) + { + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + CalendarInviteStatus status = tentative ? CALENDAR_STATUS_TENTATIVE : CALENDAR_STATUS_SIGNED_UP; + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, time(NULL), status, CALENDAR_RANK_PLAYER, ""); + sCalendarMgr->AddInvite(calendarEvent, invite); + sCalendarMgr->SendCalendarClearPendingAction(guid); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData) @@ -477,22 +482,36 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData) uint64 guid = _player->GetGUID(); uint64 eventId; uint64 inviteId; - uint8 status; + uint32 status; recvData >> eventId >> inviteId >> status; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_RSVP [" UI64FMTD"] EventId [" UI64FMTD "], InviteId [" UI64FMTD "], status %u", guid, eventId, inviteId, status); - CalendarAction action; - action.SetAction(CALENDAR_ACTION_MODIFY_EVENT_INVITE); - action.SetPlayer(_player); - action.SetInviteId(inviteId); - action.Invite.SetInviteId(inviteId); - action.Invite.SetEventId(eventId); - action.Invite.SetStatus((CalendarInviteStatus) status); + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + // i think we still should be able to remove self from locked events + if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED) + { + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED); + return; + } + + if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId)) + { + invite->SetStatus(CalendarInviteStatus(status)); + invite->SetStatusTime(time(NULL)); - sCalendarMgr->AddAction(action); + sCalendarMgr->UpdateInvite(invite); + sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite); + sCalendarMgr->SendCalendarClearPendingAction(guid); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct? + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket& recvData) @@ -500,26 +519,29 @@ void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket& recvData) uint64 guid = _player->GetGUID(); uint64 invitee; uint64 eventId; - uint64 owninviteId; + uint64 ownerInviteId; // isn't it sender's inviteId? uint64 inviteId; recvData.readPackGUID(invitee); - recvData >> inviteId >> owninviteId >> eventId; + recvData >> inviteId >> ownerInviteId >> eventId; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_REMOVE_INVITE [" - UI64FMTD "] EventId [" UI64FMTD "], OwnInviteId [" + UI64FMTD "] EventId [" UI64FMTD "], ownerInviteId [" UI64FMTD "], Invitee ([" UI64FMTD "] id: [" UI64FMTD "])", - guid, eventId, owninviteId, invitee, inviteId); + guid, eventId, ownerInviteId, invitee, inviteId); - CalendarAction action; - action.SetAction(CALENDAR_ACTION_REMOVE_EVENT_INVITE); - action.SetPlayer(_player); - action.SetInviteId(owninviteId); - action.Invite.SetInviteId(inviteId); - action.Invite.SetEventId(eventId); - action.Invite.SetInvitee(invitee); + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + if (calendarEvent->GetCreatorGUID() == invitee) + { + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED); + return; + } - sCalendarMgr->AddAction(action); + sCalendarMgr->RemoveInvite(inviteId, eventId, guid); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); } void WorldSession::HandleCalendarEventStatus(WorldPacket& recvData) @@ -528,25 +550,32 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket& recvData) uint64 invitee; uint64 eventId; uint64 inviteId; - uint64 owninviteId; + uint64 ownerInviteId; // isn't it sender's inviteId? uint8 status; recvData.readPackGUID(invitee); - recvData >> eventId >> inviteId >> owninviteId >> status; + recvData >> eventId >> inviteId >> ownerInviteId >> status; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_STATUS [" UI64FMTD"] EventId [" - UI64FMTD "] OwnInviteId [" UI64FMTD "], Invitee ([" UI64FMTD "] id: [" - UI64FMTD "], status %u", guid, eventId, owninviteId, invitee, inviteId, status); - - CalendarAction action; - action.SetAction(CALENDAR_ACTION_MODIFY_EVENT_INVITE); - action.SetPlayer(_player); - action.SetInviteId(owninviteId); - action.Invite.SetInviteId(inviteId); - action.Invite.SetEventId(eventId); - action.Invite.SetInvitee(invitee); - action.Invite.SetStatus((CalendarInviteStatus) status); - - sCalendarMgr->AddAction(action); + UI64FMTD "] ownerInviteId [" UI64FMTD "], Invitee ([" UI64FMTD "] id: [" + UI64FMTD "], status %u", guid, eventId, ownerInviteId, invitee, inviteId, status); + + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId)) + { + invite->SetStatus((CalendarInviteStatus)status); + // not sure if we should set response time when moderator changes invite status + //invite->SetStatusTime(time(NULL)); + + sCalendarMgr->UpdateInvite(invite); + sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite); + sCalendarMgr->SendCalendarClearPendingAction(invitee); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct? + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket& recvData) @@ -555,25 +584,28 @@ void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket& recvData) uint64 invitee; uint64 eventId; uint64 inviteId; - uint64 owninviteId; - uint8 status; + uint64 ownerInviteId; // isn't it sender's inviteId? + uint8 rank; recvData.readPackGUID(invitee); - recvData >> eventId >> inviteId >> owninviteId >> status; + recvData >> eventId >> inviteId >> ownerInviteId >> rank; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [" UI64FMTD "] EventId [" - UI64FMTD "] OwnInviteId [" UI64FMTD "], Invitee ([" UI64FMTD "] id: [" - UI64FMTD "], status %u", guid, eventId, owninviteId, invitee, inviteId, status); - - CalendarAction action; - action.SetAction(CALENDAR_ACTION_MODIFY_MODERATOR_EVENT_INVITE); - action.SetPlayer(_player); - action.SetInviteId(owninviteId); - action.Invite.SetInviteId(inviteId); - action.Invite.SetEventId(eventId); - action.Invite.SetInvitee(invitee); - action.Invite.SetStatus((CalendarInviteStatus) status); - - sCalendarMgr->AddAction(action); + UI64FMTD "] ownerInviteId [" UI64FMTD "], Invitee ([" UI64FMTD "] id: [" + UI64FMTD "], rank %u", guid, eventId, ownerInviteId, invitee, inviteId, rank); + + if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) + { + if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId)) + { + invite->SetRank(CalendarModerationRank(rank)); + sCalendarMgr->UpdateInvite(invite); + sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite); + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct? + } + else + sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); } void WorldSession::HandleCalendarComplain(WorldPacket& recvData) @@ -585,6 +617,8 @@ void WorldSession::HandleCalendarComplain(WorldPacket& recvData) recvData >> eventId >> complainGUID; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_COMPLAIN [" UI64FMTD "] EventId [" UI64FMTD "] guid [" UI64FMTD "]", guid, eventId, complainGUID); + + // what to do with complains? } void WorldSession::HandleCalendarGetNumPending(WorldPacket& /*recvData*/) @@ -600,279 +634,23 @@ void WorldSession::HandleCalendarGetNumPending(WorldPacket& /*recvData*/) SendPacket(&data); } -// ----------------------------------- SEND ------------------------------------ - -void WorldSession::SendCalendarEvent(CalendarEvent const& calendarEvent, CalendarSendEventType sendEventType) -{ - uint64 eventId = calendarEvent.GetEventId(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_EVENT [" UI64FMTD "] EventId [" - UI64FMTD "] SendType %u", _player->GetGUID(), eventId, sendEventType); - - WorldPacket data(SMSG_CALENDAR_SEND_EVENT); - data << uint8(sendEventType); - data.appendPackGUID(calendarEvent.GetCreatorGUID()); - data << uint64(eventId); - data << calendarEvent.GetTitle(); - data << calendarEvent.GetDescription(); - data << uint8(calendarEvent.GetType()); - data << uint8(calendarEvent.GetRepeatable()); - data << uint32(calendarEvent.GetMaxInvites()); - data << int32(calendarEvent.GetDungeonId()); - data << uint32(calendarEvent.GetFlags()); - data.AppendPackedTime(calendarEvent.GetTime()); - data.AppendPackedTime(calendarEvent.GetTimeZoneTime()); - data << uint32(calendarEvent.GetGuildId()); - - CalendarInviteIdList const& invites = calendarEvent.GetInviteIdList(); - data << uint32(invites.size()); - for (CalendarInviteIdList::const_iterator it = invites.begin(); it != invites.end(); ++it) - { - if (CalendarInvite* invite = sCalendarMgr->GetInvite(*it)) - { - uint64 guid = invite->GetInvitee(); - Player* player = ObjectAccessor::FindPlayer(guid); - uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(guid); - - data.appendPackGUID(guid); - data << uint8(level); - data << uint8(invite->GetStatus()); - data << uint8(invite->GetRank()); - data << uint8(calendarEvent.GetGuildId() != 0); - data << uint64(invite->GetInviteId()); - data << uint32(invite->GetStatusTime()); - data << invite->GetText(); - } - else - { - data.appendPackGUID(_player->GetGUID()); - data << uint8(0) << uint8(0) << uint8(0) << uint8(0) - << uint64(0) << uint32(0) << uint8(0); - - sLog->outError(LOG_FILTER_NETWORKIO, "SendCalendarEvent: No Invite found with id [" UI64FMTD "]", *it); - } - } - SendPacket(&data); -} - -void WorldSession::SendCalendarEventInvite(CalendarInvite const& invite, bool pending) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = invite.GetEventId(); - uint64 inviteId = invite.GetInviteId(); - uint64 invitee = invite.GetInvitee(); - uint8 status = invite.GetStatus(); - uint32 statusTime = invite.GetStatusTime(); - Player* player = ObjectAccessor::FindPlayer(invitee); - uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_INVITE [" UI64FMTD "] EventId [" - UI64FMTD "] InviteId [" UI64FMTD "] Invitee [" UI64FMTD "] " - " Level %u, Status %u, StatusTime %u" , guid, eventId, inviteId, - invitee, level, status, statusTime); - - WorldPacket data(SMSG_CALENDAR_EVENT_INVITE, 8 + 8 + 8 + 1 + 1 + 1 + (statusTime ? 4 : 0) + 1); - data.appendPackGUID(invitee); - data << uint64(eventId); - data << uint64(inviteId); - data << uint8(level); - data << uint8(status); - if (statusTime) - data << uint8(1) << uint32(statusTime); - else - data << uint8(0); - data << uint8(pending); - - SendPacket(&data); -} - -void WorldSession::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = calendarEvent.GetEventId(); - uint64 inviteId = invite.GetInviteId(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_INVITE_ALERT [" UI64FMTD "] EventId [" - UI64FMTD "] InviteId [" UI64FMTD "]", guid, eventId, inviteId); - - WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_ALERT); - data << uint64(eventId); - data << calendarEvent.GetTitle().c_str(); - data.AppendPackedTime(calendarEvent.GetTime()); - data << uint32(calendarEvent.GetFlags()); - data << uint32(calendarEvent.GetType()); - data << uint32(calendarEvent.GetDungeonId()); - data << uint64(inviteId); - data << uint8(invite.GetStatus()); - data << uint8(invite.GetRank()); - data.appendPackGUID(calendarEvent.GetCreatorGUID()); - data.appendPackGUID(invite.GetSenderGUID()); - SendPacket(&data); -} - -void WorldSession::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, CalendarSendEventType sendEventType) +void WorldSession::HandleSetSavedInstanceExtend(WorldPacket& recvData) { - uint64 guid = _player->GetGUID(); - uint64 eventId = calendarEvent.GetEventId(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_UPDATED_ALERT [" - UI64FMTD "] EventId [" UI64FMTD "]", guid, eventId); - - - WorldPacket data(SMSG_CALENDAR_EVENT_UPDATED_ALERT, 1 + 8 + 4 + 4 + 4 + 1 + 4 + - calendarEvent.GetTitle().size() + calendarEvent.GetDescription().size() + 1 + 4 + 4); - data << uint8(sendEventType); - data << uint64(eventId); - data.AppendPackedTime(calendarEvent.GetTime()); - data << uint32(calendarEvent.GetFlags()); - data.AppendPackedTime(calendarEvent.GetTime()); - data << uint8(calendarEvent.GetType()); - data << uint32(calendarEvent.GetDungeonId()); - data << calendarEvent.GetTitle().c_str(); - data << calendarEvent.GetDescription().c_str(); - data << uint8(calendarEvent.GetRepeatable()); - data << uint32(calendarEvent.GetMaxInvites()); - data << uint32(0); // FIXME - SendPacket(&data); -} - -void WorldSession::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = calendarEvent.GetEventId(); - uint32 eventTime = calendarEvent.GetTime(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_REMOVED_ALERT [" UI64FMTD "] EventId [" - UI64FMTD "] Time %u", guid, eventId, eventTime); - - WorldPacket data(SMSG_CALENDAR_EVENT_REMOVED_ALERT, 1 + 8 + 1); - data << uint8(1); // FIXME: If true does not SignalEvent(EVENT_CALENDAR_ACTION_PENDING) - data << uint64(eventId); - data.AppendPackedTime(eventTime); - SendPacket(&data); -} - -void WorldSession::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = calendarEvent.GetEventId(); - uint64 inviteId = invite.GetInviteId(); - uint64 invitee = invite.GetInvitee(); - uint32 eventTime = calendarEvent.GetTime(); - uint32 flags = calendarEvent.GetFlags(); - uint8 status = invite.GetStatus(); - uint8 rank = invite.GetRank(); - uint32 statusTime = invite.GetStatusTime(); - - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_STATUS [" UI64FMTD "] EventId [" - UI64FMTD "] InviteId [" UI64FMTD "] Invitee [" UI64FMTD "] Time %u " - "Flags %u, Status %u, Rank %u, StatusTime %u", - guid, eventId, inviteId, invitee, eventTime, flags, status, rank, - statusTime); - - WorldPacket data(SMSG_CALENDAR_EVENT_STATUS, 8 + 8 + 4 + 4 + 1 + 1 + 4); - data.appendPackGUID(invitee); - data << uint64(eventId); - data.AppendPackedTime(eventTime); - data << uint32(flags); - data << uint8(status); - data << uint8(rank); - data.AppendPackedTime(statusTime); - SendPacket(&data); -} - -void WorldSession::SendCalendarEventModeratorStatusAlert(CalendarInvite const& invite) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = invite.GetEventId(); - uint64 invitee = invite.GetInvitee(); - uint8 status = invite.GetStatus(); - - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT [" UI64FMTD - "] Invitee [" UI64FMTD "] EventId [" UI64FMTD "] Status %u ", guid, - invitee, eventId, status); - - - WorldPacket data(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, 8 + 8 + 1 + 1); - data.appendPackGUID(invitee); - data << uint64(eventId); - data << uint8(status); - data << uint8(1); // FIXME - SendPacket(&data); -} - -void WorldSession::SendCalendarEventInviteRemoveAlert(CalendarEvent const& calendarEvent, CalendarInviteStatus status) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = calendarEvent.GetEventId(); - uint32 eventTime = calendarEvent.GetTime(); - uint32 flags = calendarEvent.GetFlags(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT [" - UI64FMTD "] EventId [" UI64FMTD "] Time %u, Flags %u, Status %u", - guid, eventId, eventTime, flags, status); - - WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1); - data << uint64(eventId); - data.AppendPackedTime(eventTime); - data << uint32(flags); - data << uint8(status); - SendPacket(&data); -} + uint32 mapId, difficulty; + uint8 toggleExtend; + recvData >> mapId >> difficulty>> toggleExtend; + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_SAVED_INSTANCE_EXTEND - MapId: %u, Difficulty: %u, ToggleExtend: %s", mapId, difficulty, toggleExtend ? "On" : "Off"); -void WorldSession::SendCalendarEventInviteRemove(CalendarInvite const& invite, uint32 flags) -{ - uint64 guid = _player->GetGUID(); - uint64 eventId = invite.GetEventId(); - uint64 invitee = invite.GetInvitee(); - - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_INVITE_REMOVED [" - UI64FMTD "] Invitee [" UI64FMTD "] EventId [" UI64FMTD - "] Flags %u", guid, invitee, eventId, flags); - - WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED, 8 + 4 + 4 + 1); - data.appendPackGUID(invitee); - data << uint32(eventId); - data << uint32(flags); - data << uint8(1); // FIXME - SendPacket(&data); -} - -void WorldSession::SendCalendarClearPendingAction() -{ - uint64 guid = _player->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_CLEAR_PENDING_ACTION [" UI64FMTD "]", guid); + InstancePlayerBind* instanceBind = _player->GetBoundInstance(mapId, Difficulty(difficulty)); + if (!instanceBind || !instanceBind->save) + return; - WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0); - SendPacket(&data); + InstanceSave* save = instanceBind->save; + // http://www.wowwiki.com/Instance_Lock_Extension + // SendCalendarRaidLockoutUpdated(save); } -void WorldSession::SendCalendarCommandResult(CalendarError err, char const* param /*= NULL*/) -{ - uint64 guid = _player->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_COMMAND_RESULT [" UI64FMTD "] Value: %u", guid, err); - - WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0); - data << uint32(0); - data << uint8(0); - switch (err) - { - case CALENDAR_ERROR_OTHER_INVITES_EXCEEDED: - case CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S: - case CALENDAR_ERROR_IGNORING_YOU_S: - data << param; - break; - default: - data << uint8(0); - break; - } - - data << uint32(err); - - SendPacket(&data); -} +// ----------------------------------- SEND ------------------------------------ void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add) { @@ -902,13 +680,13 @@ void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save) sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [" UI64FMTD "] Map: %u, Difficulty %u", guid, save->GetMapId(), save->GetDifficulty()); - time_t cur_time = time_t(time(NULL)); + time_t currTime = time(NULL); WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8); - data.AppendPackedTime(cur_time); + data.AppendPackedTime(currTime); data << uint32(save->GetMapId()); data << uint32(save->GetDifficulty()); data << uint32(0); // Amount of seconds that has changed to the reset time - data << uint32(save->GetResetTime() - cur_time); + data << uint32(save->GetResetTime() - currTime); SendPacket(&data); -} +}
\ No newline at end of file diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 8e6cdbc9dc2..d0aad7072f7 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -44,6 +44,7 @@ #include "Battleground.h" #include "AccountMgr.h" #include "LFGMgr.h" +#include "CalendarMgr.h" class LoginQueryHolder : public SQLQueryHolder { @@ -726,6 +727,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData) sLog->outCharDump(dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); } + sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid); Player::DeleteFromDB(guid, GetAccountId()); WorldPacket data(SMSG_CHAR_DELETE, 1); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 5a7a3b52b56..cb3a6d920b8 100755 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -607,10 +607,8 @@ void WorldSession::HandleGetMailList(WorldPacket & recvData) case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: - data << uint32((*itr)->sender); // creature/gameobject entry, auction id - break; - case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI - data << uint32(0); // item entry + case MAIL_CALENDAR: + data << uint32((*itr)->sender); // creature/gameobject entry, auction id, calendar event id? break; } diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index 929a1d81d57..108856d81b6 100755 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -26,6 +26,7 @@ #include "BattlegroundMgr.h" #include "Item.h" #include "AuctionHouseMgr.h" +#include "CalendarMgr.h" MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery) { @@ -39,10 +40,10 @@ MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery m_messageType = MAIL_GAMEOBJECT; m_senderId = sender->GetEntry(); break; - case TYPEID_ITEM: + /*case TYPEID_ITEM: m_messageType = MAIL_ITEM; m_senderId = sender->GetEntry(); - break; + break;*/ case TYPEID_PLAYER: m_messageType = MAIL_NORMAL; m_senderId = sender->GetGUIDLow(); @@ -55,6 +56,11 @@ MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery } } +MailSender::MailSender(CalendarEvent* sender) + : m_messageType(MAIL_CALENDAR), m_senderId(sender->GetEventId()), m_stationery(MAIL_STATIONERY_DEFAULT) // what stationery we should use here? +{ +} + MailSender::MailSender(AuctionEntry* sender) : m_messageType(MAIL_AUCTION), m_senderId(sender->GetHouseId()), m_stationery(MAIL_STATIONERY_AUCTION) { diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h index 7c12ac1a1c6..c2771f4b57c 100755 --- a/src/server/game/Mails/Mail.h +++ b/src/server/game/Mails/Mail.h @@ -23,6 +23,7 @@ #include <map> struct AuctionEntry; +struct CalendarEvent; class Item; class Object; class Player; @@ -36,7 +37,7 @@ enum MailMessageType MAIL_AUCTION = 2, MAIL_CREATURE = 3, // client send CMSG_CREATURE_QUERY on this mailmessagetype MAIL_GAMEOBJECT = 4, // client send CMSG_GAMEOBJECT_QUERY on this mailmessagetype - MAIL_ITEM = 5 // client send CMSG_ITEM_QUERY on this mailmessagetype + MAIL_CALENDAR = 5 }; enum MailCheckMask @@ -85,6 +86,7 @@ class MailSender { } MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_DEFAULT); + MailSender(CalendarEvent* sender); MailSender(AuctionEntry* sender); MailSender(Player* sender); public: // Accessors diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 57e92c77655..810419bc2ea 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3428,104 +3428,6 @@ enum DuelCompleteType DUEL_WON = 1, DUEL_FLED = 2 }; - -enum CalendarFlags -{ - CALENDAR_FLAG_ALL_ALLOWED = 0x001, - CALENDAR_FLAG_INVITES_LOCKED = 0x010, - CALENDAR_FLAG_WITHOUT_INVITES = 0x040, - CALENDAR_FLAG_GUILD_ONLY = 0x400 -}; - -enum CalendarActionData -{ - CALENDAR_ACTION_NONE, - CALENDAR_ACTION_ADD_EVENT, - CALENDAR_ACTION_MODIFY_EVENT, - CALENDAR_ACTION_REMOVE_EVENT, - CALENDAR_ACTION_COPY_EVENT, - CALENDAR_ACTION_ADD_EVENT_INVITE, - CALENDAR_ACTION_MODIFY_EVENT_INVITE, - CALENDAR_ACTION_MODIFY_MODERATOR_EVENT_INVITE, - CALENDAR_ACTION_REMOVE_EVENT_INVITE, - CALENDAR_ACTION_SIGNUP_TO_EVENT -}; - -enum CalendarModerationRank -{ - CALENDAR_RANK_PLAYER, - CALENDAR_RANK_MODERATOR, - CALENDAR_RANK_OWNER -}; - -enum CalendarSendEventType -{ - CALENDAR_SENDTYPE_GET, - CALENDAR_SENDTYPE_ADD, - CALENDAR_SENDTYPE_COPY -}; - -enum CalendarEventType -{ - CALENDAR_TYPE_RAID, - CALENDAR_TYPE_DUNGEON, - CALENDAR_TYPE_PVP, - CALENDAR_TYPE_MEETING, - CALENDAR_TYPE_OTHER -}; - -enum CalendarInviteStatus -{ - CALENDAR_STATUS_INVITED, - CALENDAR_STATUS_ACCEPTED, - CALENDAR_STATUS_DECLINED, - CALENDAR_STATUS_TENTATIVE, - CALENDAR_STATUS_OUT, - CALENDAR_STATUS_STANDBY, - CALENDAR_STATUS_CONFIRMED, - CALENDAR_STATUS_NO_OWNER, - CALENDAR_STATUS_8, - CALENDAR_STATUS_9 -}; - -enum CalendarError -{ - CALENDAR_OK = 0, - CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED = 1, - CALENDAR_ERROR_EVENTS_EXCEEDED = 2, - CALENDAR_ERROR_SELF_INVITES_EXCEEDED = 3, - CALENDAR_ERROR_OTHER_INVITES_EXCEEDED = 4, - CALENDAR_ERROR_PERMISSIONS = 5, - CALENDAR_ERROR_EVENT_INVALID = 6, - CALENDAR_ERROR_NOT_INVITED = 7, - CALENDAR_ERROR_INTERNAL = 8, - CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD = 9, - CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S = 10, - CALENDAR_ERROR_PLAYER_NOT_FOUND = 11, - CALENDAR_ERROR_NOT_ALLIED = 12, - CALENDAR_ERROR_IGNORING_YOU_S = 13, - CALENDAR_ERROR_INVITES_EXCEEDED = 14, - CALENDAR_ERROR_INVALID_DATE = 16, - CALENDAR_ERROR_INVALID_TIME = 17, - - CALENDAR_ERROR_NEEDS_TITLE = 19, - CALENDAR_ERROR_EVENT_PASSED = 20, - CALENDAR_ERROR_EVENT_LOCKED = 21, - CALENDAR_ERROR_DELETE_CREATOR_FAILED = 22, - CALENDAR_ERROR_SYSTEM_DISABLED = 24, - CALENDAR_ERROR_RESTRICTED_ACCOUNT = 25, - CALENDAR_ERROR_ARENA_EVENTS_EXCEEDED = 26, - CALENDAR_ERROR_RESTRICTED_LEVEL = 27, - CALENDAR_ERROR_USER_SQUELCHED = 28, - CALENDAR_ERROR_NO_INVITE = 29, - - CALENDAR_ERROR_EVENT_WRONG_SERVER = 36, - CALENDAR_ERROR_INVITE_WRONG_SERVER = 37, - CALENDAR_ERROR_NO_GUILD_INVITES = 38, - CALENDAR_ERROR_INVALID_SIGNUP = 39, - CALENDAR_ERROR_NO_MODERATOR = 40 -}; - // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time enum BattlegroundQueueTypeId { diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 9078f6720a0..0821be2abb9 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -684,7 +684,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode}, /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem }, /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend }, /*0x293*/ { "SMSG_LFG_OFFER_CONTINUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x294*/ { "CMSG_TEST_DROP_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x295*/ { "SMSG_TEST_DROP_RATE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1158559f315..2060ab54cba 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -31,8 +31,6 @@ #include "WorldPacket.h" #include "Cryptography/BigNumber.h" -class CalendarEvent; -class CalendarInvite; class Creature; class GameObject; class InstanceSave; @@ -904,19 +902,9 @@ class WorldSession void HandleCalendarGetNumPending(WorldPacket& recvData); void HandleCalendarEventSignup(WorldPacket& recvData); - void SendCalendarEvent(CalendarEvent const& calendarEvent, CalendarSendEventType sendEventType); - void SendCalendarEventInvite(CalendarInvite const& invite, bool pending); - void SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& calendarInvite); - void SendCalendarEventInviteRemove(CalendarInvite const& invite, uint32 flags); - void SendCalendarEventInviteRemoveAlert(CalendarEvent const& calendarEvent, CalendarInviteStatus status); - void SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent); - void SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, CalendarSendEventType sendEventType); - void SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite); - void SendCalendarEventModeratorStatusAlert(CalendarInvite const& invite); - void SendCalendarClearPendingAction(); void SendCalendarRaidLockout(InstanceSave const* save, bool add); void SendCalendarRaidLockoutUpdated(InstanceSave const* save); - void SendCalendarCommandResult(CalendarError err, char const* param = NULL); + void HandleSetSavedInstanceExtend(WorldPacket& recvData); void HandleSpellClick(WorldPacket& recvData); void HandleMirrorImageDataRequest(WorldPacket& recvData); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index db9a5646a69..5210ee6f39d 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -535,4 +535,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + + // Calendar + PREPARE_STATEMENT(CHAR_REP_CALENDAR_EVENT, "REPLACE INTO calendar_events (id, creator, title, description, type, dungeon, eventtime, flags, time2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CALENDAR_EVENT, "DELETE FROM calendar_events WHERE id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_CALENDAR_INVITE, "REPLACE INTO calendar_invites (id, event, invitee, sender, status, statustime, rank, text) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CALENDAR_INVITE, "DELETE FROM calendar_invites WHERE id = ?", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index e421a7917ca..7e4fe6a0b0e 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -496,6 +496,11 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, + CHAR_REP_CALENDAR_EVENT, + CHAR_DEL_CALENDAR_EVENT, + CHAR_REP_CALENDAR_INVITE, + CHAR_DEL_CALENDAR_INVITE, + MAX_CHARACTERDATABASE_STATEMENTS }; |