/* * Copyright (C) 2008-2012 TrinityCore * * 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 . */ /* 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 "ObjectAccessor.h" CalendarMgr::CalendarMgr() : _eventNum(0), _inviteNum(0) { } CalendarMgr::~CalendarMgr() { } uint32 CalendarMgr::GetPlayerNumPending(uint64 guid) { 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) { return _playerInvites[guid]; } CalendarEventIdList const& CalendarMgr::GetPlayerEvents(uint64 guid) { return _playerEvents[guid]; } CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) { CalendarInviteMap::iterator itr = _invites.find(inviteId); if (itr != _invites.end()) return &(itr->second); sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId); return NULL; } CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) { CalendarEventMap::iterator itr = _events.find(eventId); if (itr != _events.end()) return &(itr->second); sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId); return NULL; } uint64 CalendarMgr::GetFreeEventId() { return ++_eventNum; } uint64 CalendarMgr::GetFreeInviteId() { return ++_inviteNum; } 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); 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(); uint64 inviteId = fields[0].GetUInt64(); uint64 eventId = fields[1].GetUInt64(); CalendarInvite& invite = _invites[inviteId]; 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()); CalendarEvent& calendarEvent = _events[eventId]; calendarEvent.AddInvite(inviteId); } while (result->NextRow()); sLog->outInfo(LOG_FILTER_CALENDAR, ">> Loaded %u calendar Invites", count); */ } CalendarEvent* CalendarMgr::CheckPermisions(uint64 eventId, Player* player, uint64 inviteId, CalendarModerationRank minRank) { if (!player) return NULL; // CALENDAR_ERROR_INTERNAL CalendarEvent* calendarEvent = GetEvent(eventId); if (!calendarEvent) { player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_EVENT_INVALID); return NULL; } CalendarInvite* invite = GetInvite(inviteId); if (!invite) { player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_NO_INVITE); return NULL; } if (!calendarEvent->HasInvite(inviteId)) { player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_NOT_INVITED); return NULL; } if (invite->GetEventId() != calendarEvent->GetEventId() || invite->GetInvitee() != player->GetGUID()) { player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_INTERNAL); return NULL; } if (invite->GetRank() < minRank) { player->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_PERMISSIONS); return NULL; } return calendarEvent; } void CalendarMgr::AddAction(CalendarAction const& action) { 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); 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); 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; 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); } 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 || !(calendarEvent->GetFlags() & CALENDAR_FLAG_GUILD_ONLY) || !calendarEvent->GetGuildId() || calendarEvent->GetGuildId() != action.GetExtraData()) return; CalendarInviteStatus status = action.Invite.GetStatus(); if (status == CALENDAR_STATUS_INVITED) status = CALENDAR_STATUS_CONFIRMED; else if (status == CALENDAR_STATUS_ACCEPTED) status = CALENDAR_STATUS_8; CalendarInvite newInvite(GetFreeInviteId()); newInvite.SetStatus(status); newInvite.SetStatusTime(uint32(time(NULL))); newInvite.SetEventId(eventId); newInvite.SetInvitee(action.GetPlayer()->GetGUID()); newInvite.SetSenderGUID(action.GetPlayer()->GetGUID()); if (AddInvite(newInvite)) SendCalendarEventInvite(newInvite, false); break; } case CALENDAR_ACTION_MODIFY_EVENT_INVITE: { uint64 eventId = action.Invite.GetEventId(); uint64 inviteId = action.Invite.GetInviteId(); CalendarEvent* calendarEvent = NULL; if (action.GetInviteId() != action.Invite.GetInviteId()) calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR); else calendarEvent = GetEvent(eventId); CalendarInvite* invite = GetInvite(inviteId); if (!calendarEvent || !invite || !calendarEvent->HasInvite(inviteId)) return; 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(); CalendarEvent* calendarEvent = NULL; if (action.GetInviteId() != action.Invite.GetInviteId()) calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_OWNER); else calendarEvent = GetEvent(eventId); CalendarInvite* invite = GetInvite(inviteId); if (!calendarEvent || !invite || !calendarEvent->HasInvite(inviteId)) return; 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; } } bool CalendarMgr::AddEvent(CalendarEvent const& newEvent) { uint64 eventId = newEvent.GetEventId(); if (_events.find(eventId) != _events.end()) { sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddEvent: Event [" UI64FMTD "] exists", eventId); return false; } _events[eventId] = newEvent; return true; } bool CalendarMgr::RemoveEvent(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; } bool val = true; 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; if (uint64 invitee = RemoveInvite(*itrInvites)) SendCalendarEventRemovedAlert(invitee, itr->second); } _events.erase(itr); return val; } bool CalendarMgr::AddPlayerEvent(uint64 guid, uint64 eventId) { _playerEvents[guid].insert(eventId); return true; } bool CalendarMgr::RemovePlayerEvent(uint64 guid, uint64 eventId) { _playerEvents[guid].erase(eventId); return true; } bool CalendarMgr::AddInvite(CalendarInvite const& newInvite) { uint64 inviteId = newInvite.GetInviteId(); if (!inviteId) { sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddInvite: Cant add Invite 0"); return false; } if (_invites.find(inviteId) != _invites.end()) { sLog->outError(LOG_FILTER_CALENDAR, "CalendarMgr::AddInvite: Invite [" UI64FMTD "] exists", inviteId); return false; } _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) { 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; } bool CalendarMgr::AddPlayerInvite(uint64 guid, uint64 inviteId) { _playerInvites[guid].insert(inviteId); return true; } bool CalendarMgr::RemovePlayerInvite(uint64 guid, uint64 inviteId) { _playerInvites[guid].erase(inviteId); return true; } void CalendarMgr::SendCalendarEvent(CalendarEvent const& calendarEvent, CalendarSendEventType type) { if (Player* player = ObjectAccessor::FindPlayer(calendarEvent.GetCreatorGUID())) player->GetSession()->SendCalendarEvent(calendarEvent, type); } void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite, bool pending) { if (Player* player = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) player->GetSession()->SendCalendarEventInvite(invite, pending); } void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) { if (Player* player = ObjectAccessor::FindPlayer(invite.GetInvitee())) player->GetSession()->SendCalendarEventInviteAlert(calendarEvent, invite); } void CalendarMgr::SendCalendarEventUpdateAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType type) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendCalendarEventUpdateAlert(calendarEvent, type); } void CalendarMgr::SendCalendarEventStatus(uint64 guid, CalendarEvent const& calendarEvent, CalendarInvite const& invite) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendCalendarEventStatus(calendarEvent, invite); } void CalendarMgr::SendCalendarEventRemovedAlert(uint64 guid, CalendarEvent const& calendarEvent) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendCalendarEventRemovedAlert(calendarEvent); } void CalendarMgr::SendCalendarEventInviteRemoveAlert(uint64 guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendCalendarEventInviteRemoveAlert(calendarEvent, status); } void CalendarMgr::SendCalendarEventInviteRemove(uint64 guid, CalendarInvite const& invite, uint32 flags) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendCalendarEventInviteRemove(invite, flags); } void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarInvite const& invite) { if (Player* player = ObjectAccessor::FindPlayer(invite.GetInvitee())) player->GetSession()->SendCalendarEventModeratorStatusAlert(invite); }