diff options
| author | Spp <spp@jorge.gr> | 2012-11-19 10:09:58 +0100 |
|---|---|---|
| committer | Spp <spp@jorge.gr> | 2012-11-19 10:09:58 +0100 |
| commit | 7f061fc57fac4b48417d25579e833e9b66364237 (patch) | |
| tree | cdbe2ff223967034dd9f236da4ca38cc73c30a7b /src/server/game | |
| parent | 09ab26ac946bc7b5458d92fbadfb66e442744098 (diff) | |
| parent | d42212b595ad01be0a839405d853f7db2b9f88de (diff) | |
Merge branch 'master' into 4.3.4
Conflicts:
src/server/game/AI/EventAI/CreatureEventAI.cpp
src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
src/server/game/AI/EventAI/CreatureEventAIMgr.h
src/server/game/Battlegrounds/Battleground.h
src/server/game/Chat/Chat.h
src/server/game/Entities/Player/Player.cpp
src/server/game/Globals/ObjectMgr.cpp
src/server/game/Globals/ObjectMgr.h
src/server/game/Guilds/Guild.cpp
src/server/game/Handlers/CharacterHandler.cpp
src/server/game/Handlers/MailHandler.cpp
src/server/game/Miscellaneous/SharedDefines.h
src/server/game/Server/Protocol/Opcodes.cpp
src/server/game/Spells/SpellInfo.cpp
src/server/game/World/World.cpp
src/server/scripts/Commands/cs_modify.cpp
src/server/scripts/Commands/cs_reload.cpp
src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
src/server/shared/Database/Implementation/CharacterDatabase.cpp
Diffstat (limited to 'src/server/game')
83 files changed, 1621 insertions, 1720 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 5ab5f99310a..d9d19c2f009 100755 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -21,6 +21,7 @@ #include "SpellInfo.h" #include "Vehicle.h" #include "ObjectAccessor.h" +#include "Player.h" int AggressorAI::Permissible(const Creature* creature) { diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index f30c4516830..2fdb3cd39c6 100755 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -90,8 +90,6 @@ void PetAI::UpdateAI(const uint32 diff) else m_updateAlliesTimer -= diff; - // me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc. - // Must also check if victim is alive if (me->getVictim() && me->getVictim()->isAlive()) { // is only necessary to stop casting, the pet must not exit combat @@ -108,7 +106,9 @@ void PetAI::UpdateAI(const uint32 diff) return; } - DoMeleeAttackIfReady(); + // Check before attacking to prevent pets from leaving stay position + if (CanAttack(me->getVictim())) + DoMeleeAttackIfReady(); } else if (owner && me->GetCharmInfo()) //no victim { @@ -335,7 +335,8 @@ void PetAI::AttackStart(Unit* target) if (Unit* owner = me->GetOwner()) owner->SetInCombatWith(target); - DoAttack(target, true); + // Only chase if not commanded to stay or if stay but commanded to attack + DoAttack(target, (!me->GetCharmInfo()->HasCommandState(COMMAND_STAY) || me->GetCharmInfo()->IsCommandAttack())); } void PetAI::OwnerDamagedBy(Unit* attacker) @@ -382,31 +383,42 @@ void PetAI::OwnerAttacked(Unit* target) Unit* PetAI::SelectNextTarget() { // Provides next target selection after current target death + // Targets are not evaluated here for being valid attack targets // Passive pets don't do next target selection if (me->HasReactState(REACT_PASSIVE)) return NULL; - Unit* target = me->getAttackerForHelper(); + // Check pet attackers first so we don't drag a bunch of targets to the owner + if (Unit* myAttacker = me->getAttackerForHelper()) + if (!myAttacker->HasBreakableByDamageCrowdControlAura()) + return myAttacker; - // Check pet's attackers first to prevent dragging mobs back to owner - if (target && !target->HasBreakableByDamageCrowdControlAura()) - return target; - - if (me->GetCharmerOrOwner()) - { - // Check owner's attackers if pet didn't have any - target = me->GetCharmerOrOwner()->getAttackerForHelper(); - if (target && !target->HasBreakableByDamageCrowdControlAura()) - return target; - - // 3.0.2 - Pets now start attacking their owners target in defensive mode as soon as the hunter does - target = me->GetCharmerOrOwner()->getVictim(); - if (target && !target->HasBreakableByDamageCrowdControlAura()) - return target; - } + // Not sure why we wouldn't have an owner but just in case... + if (!me->GetCharmerOrOwner()) + return NULL; - // Default + // Check owner attackers + if (Unit* ownerAttacker = me->GetCharmerOrOwner()->getAttackerForHelper()) + if (!ownerAttacker->HasBreakableByDamageCrowdControlAura()) + return ownerAttacker; + + // Check owner victim + // 3.0.2 - Pets now start attacking their owners victim in defensive mode as soon as the hunter does + if (Unit* ownerVictim = me->GetCharmerOrOwner()->getVictim()) + if (!ownerVictim->HasBreakableByDamageCrowdControlAura()) + return ownerVictim; + + // Neither pet or owner had a target and aggressive pets can pick any target + // Note: Creature::SelectNearestTarget() If no distance is supplied it uses MAX_VISIBILITY_DISTANCE + // We also want to lock this to LOS so pet doesn't go running through walls and stuff + if (me->HasReactState(REACT_AGGRESSIVE)) + if (Unit* nearTarget = me->ToCreature()->SelectNearestTarget()) + if (nearTarget->IsHostileTo(me) && !nearTarget->HasBreakableByDamageCrowdControlAura()) + if (nearTarget->IsWithinLOS(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())) + return nearTarget; + + // Default - no valid targets return NULL; } @@ -518,6 +530,10 @@ bool PetAI::CanAttack(Unit* target) // Evaluates wether a pet can attack a specific // target based on CommandState, ReactState and other flags + // Can't attack dead targets... + if (!target->isAlive()) + return false; + // Returning - check first since pets returning ignore attacks if (me->GetCharmInfo()->IsReturning()) return false; @@ -526,19 +542,17 @@ bool PetAI::CanAttack(Unit* target) if (me->HasReactState(REACT_PASSIVE)) return me->GetCharmInfo()->IsCommandAttack(); - // Pets commanded to attack should not stop their approach if attacked by another creature - if (me->getVictim() && (me->getVictim() != target)) - return !me->GetCharmInfo()->IsCommandAttack(); - - // From this point on, pet will always be either aggressive or defensive + // Follow + if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) + return true; // Stay - can attack if target is within range or commanded to if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY)) - return (me->IsWithinMeleeRange(target, MELEE_RANGE) || me->GetCharmInfo()->IsCommandAttack()); + return (me->IsWithinMeleeRange(target) || me->GetCharmInfo()->IsCommandAttack()); - // Follow - if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) - return true; + // Pets commanded to attack should not stop their approach if attacked by another creature + if (me->getVictim() && (me->getVictim() != target)) + return !me->GetCharmInfo()->IsCommandAttack(); // default, though we shouldn't ever get here return false; diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index 9c666e7de32..3f5952a210d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -12,6 +12,7 @@ EndScriptData */ #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" #include "Group.h" +#include "Player.h" enum ePoints { diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index ebb734156b4..96209084240 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -12,6 +12,7 @@ EndScriptData */ #include "ScriptedCreature.h" #include "ScriptedFollowerAI.h" #include "Group.h" +#include "Player.h" const float MAX_PLAYER_DISTANCE = 100.0f; diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h index 34300ff406c..ae1b5fcc12d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h +++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h @@ -8,7 +8,6 @@ #ifndef SC_GOSSIP_H #define SC_GOSSIP_H -#include "Player.h" #include "GossipDef.h" #include "QuestDef.h" diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index a1fb2147cc2..b8c0f952df9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -472,6 +472,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { + // Special handling for vehicles + if (IsUnit(*itr)) + if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) + for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) + if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger)) + player->AreaExploredOrEventHappens(e.action.quest.quest); + if (IsPlayer(*itr)) { (*itr)->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest); @@ -752,6 +759,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player %u, group credit for quest %u", unit->GetGUIDLow(), e.action.quest.quest); } + // Special handling for vehicles + if (Vehicle* vehicle = unit->GetVehicleKit()) + for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) + if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger)) + player->GroupEventHappens(e.action.quest.quest, GetBaseObject()); break; } case SMART_ACTION_CALL_CASTEDCREATUREORGO: @@ -878,6 +890,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { + // Special handling for vehicles + if (IsUnit(*itr)) + if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) + for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) + if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger)) + player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); + if (!IsPlayer(*itr)) continue; diff --git a/src/server/game/Battlefield/BattlefieldHandler.cpp b/src/server/game/Battlefield/BattlefieldHandler.cpp index 66285fe1b04..79b5f3a7998 100644 --- a/src/server/game/Battlefield/BattlefieldHandler.cpp +++ b/src/server/game/Battlefield/BattlefieldHandler.cpp @@ -26,6 +26,7 @@ #include "Battlefield.h" #include "BattlefieldMgr.h" #include "Opcodes.h" +#include "Player.h" //This send to player windows for invite player to join the war //Param1:(guid) the guid of Bf diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 4468660006e..98833589d00 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -24,6 +24,7 @@ #include "BattlefieldWG.h" #include "SpellAuras.h" #include "Vehicle.h" +#include "Player.h" enum WGVehicles { diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 68072a68249..0a81a7af992 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -21,11 +21,9 @@ #include "ObjectAccessor.h" #include "WorldPacket.h" -#include "World.h" -#include "Group.h" -#include "GroupMgr.h" #include "Battlefield.h" +class Group; class BattlefieldWG; class WintergraspCapturePoint; diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index a8526985468..e7644805a76 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -22,6 +22,7 @@ #include "World.h" #include "Group.h" #include "ArenaTeamMgr.h" +#include "Player.h" ArenaTeam::ArenaTeam() : TeamId(0), Type(0), TeamName(), CaptainGuid(0), BackgroundColor(0), EmblemStyle(0), EmblemColor(0), @@ -510,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 1c07e377d96..5d8345aec53 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -163,6 +163,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/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 9365172a4ca..8b2a056f4bb 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -22,6 +22,7 @@ #include "DatabaseEnv.h" #include "Language.h" #include "ObjectAccessor.h" +#include "Player.h" ArenaTeamMgr::ArenaTeamMgr() { diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 92a6d39a3ca..eb7ce9a64a4 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -407,6 +407,17 @@ inline void Battleground::_ProcessRessurect(uint32 diff) } } +uint32 Battleground::GetPrematureWinner() +{ + uint32 winner = 0; + if (GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam()) + winner = ALLIANCE; + else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam()) + winner = HORDE; + + return winner; +} + inline void Battleground::_ProcessProgress(uint32 diff) { // ********************************************************* @@ -421,13 +432,7 @@ inline void Battleground::_ProcessProgress(uint32 diff) else if (m_PrematureCountDownTimer < diff) { // time's up! - uint32 winner = 0; - if (GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam()) - winner = ALLIANCE; - else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam()) - winner = HORDE; - - EndBattleground(winner); + EndBattleground(GetPrematureWinner()); m_PrematureCountDown = false; } else if (!sBattlegroundMgr->isTesting()) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index ea22e2a4dd0..3feeea53ad8 100755 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -168,25 +168,6 @@ struct BattlegroundObjectInfo uint32 spellid; }; -// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time -enum BattlegroundQueueTypeId -{ - BATTLEGROUND_QUEUE_NONE = 0, - BATTLEGROUND_QUEUE_AV = 1, - BATTLEGROUND_QUEUE_WS = 2, - BATTLEGROUND_QUEUE_AB = 3, - BATTLEGROUND_QUEUE_EY = 4, - BATTLEGROUND_QUEUE_SA = 5, - BATTLEGROUND_QUEUE_IC = 6, - BATTLEGROUND_QUEUE_TP = 7, - BATTLEGROUND_QUEUE_BFG = 8, - BATTLEGROUND_QUEUE_RB = 9, - BATTLEGROUND_QUEUE_2v2 = 10, - BATTLEGROUND_QUEUE_3v3 = 11, - BATTLEGROUND_QUEUE_5v5 = 12, - MAX_BATTLEGROUND_QUEUE_TYPES -}; - enum ScoreType { SCORE_KILLING_BLOWS = 1, @@ -255,37 +236,6 @@ enum BattlegroundStartingEventsIds }; #define BG_STARTING_EVENT_COUNT 4 -enum GroupJoinBattlegroundResult -{ - ERR_BATTLEGROUND_NONE = 0, - ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS = 2, // You cannot join the battleground yet because you or one of your party members is flagged as a Deserter. - ERR_ARENA_TEAM_PARTY_SIZE = 3, // Incorrect party size for this arena. - ERR_BATTLEGROUND_TOO_MANY_QUEUES = 4, // You can only be queued for 2 battles at once - ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED = 5, // You cannot queue for a rated match while queued for other battles - ERR_BATTLEDGROUND_QUEUED_FOR_RATED = 6, // You cannot queue for another battle while queued for a rated arena match - ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = 7, // Your team has left the arena queue - ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND = 8, // You can't do that in a battleground. - ERR_BATTLEGROUND_JOIN_XP_GAIN = 9, // wtf, doesn't exist in client... - ERR_BATTLEGROUND_JOIN_RANGE_INDEX = 10, // Cannot join the queue unless all members of your party are in the same battleground level range. - ERR_BATTLEGROUND_JOIN_TIMED_OUT = 11, // %s was unavailable to join the queue. (uint64 guid exist in client cache) - //ERR_BATTLEGROUND_JOIN_TIMED_OUT = 12, // same as 11 - //ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = 13, // same as 7 - ERR_LFG_CANT_USE_BATTLEGROUND = 14, // You cannot queue for a battleground or arena while using the dungeon system. - ERR_IN_RANDOM_BG = 15, // Can't do that while in a Random Battleground queue. - ERR_IN_NON_RANDOM_BG = 16, // Can't queue for Random Battleground while in another Battleground queue. - ERR_BG_DEVELOPER_ONLY = 17, - ERR_BATTLEGROUND_INVITATION_DECLINED = 18, - ERR_MEETING_STONE_NOT_FOUND = 19, - ERR_WARGAME_REQUEST_FAILURE = 20, - ERR_BATTLEFIELD_TEAM_PARTY_SIZE = 22, - ERR_NOT_ON_TOURNAMENT_REALM = 23, - ERR_BATTLEGROUND_PLAYERS_FROM_DIFFERENT_REALMS = 24, - ERR_REMOVE_FROM_PVP_QUEUE_GRANT_LEVEL = 33, - ERR_REMOVE_FROM_PVP_QUEUE_FACTION_CHANGE = 34, - ERR_BATTLEGROUND_JOIN_FAILED = 35, - ERR_BATTLEGROUND_DUPE_QUEUE = 43 -}; - struct BattlegroundScore { BattlegroundScore() : KillingBlows(0), Deaths(0), HonorableKills(0), BonusHonor(0), @@ -580,6 +530,8 @@ class Battleground virtual uint64 GetFlagPickerGUID(int32 /*team*/ = -1) const { return 0; } virtual void SetDroppedFlagGUID(uint64 /*guid*/, int32 /*team*/ = -1) {} uint32 GetTeamScore(uint32 TeamID) const; + + virtual uint32 GetPrematureWinner(); protected: // this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends Battleground diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 90e44c32eae..fec17b2873e 100755 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -24,6 +24,7 @@ #include "ArenaTeamMgr.h" #include "Log.h" #include "Group.h" +#include "Player.h" /*********************************************************/ /*** BATTLEGROUND QUEUE SYSTEM ***/ @@ -216,7 +217,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr // Show queue status to player only (when joining queue) if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) { - ChatHandler(leader).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, + ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } // System message diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 5a887c647b1..8f7231ba66e 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -548,6 +548,25 @@ void BattlegroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* /*targ PlaySoundToAll(sound); } +uint32 BattlegroundAB::GetPrematureWinner() +{ + // How many bases each team owns + uint8 ally = 0, horde = 0; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + if (m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) + ++ally; + else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) + ++horde; + + if (ally > horde) + return ALLIANCE; + else if (horde > ally) + return HORDE; + + // If the values are equal, fall back to the original result (based on number of players on each team) + return Battleground::GetPrematureWinner(); +} + bool BattlegroundAB::SetupBattleground() { for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 63c89717c8f..b80e216a216 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -272,6 +272,8 @@ class BattlegroundAB : public Battleground /* achievement req. */ bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited bool IsTeamScores500Disadvantage(uint32 team) const { return m_TeamScores500Disadvantage[GetTeamIndexByTeamId(team)]; } + + uint32 GetPrematureWinner(); private: void PostUpdateImpl(uint32 diff); /* Gameobject spawning/despawning */ diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index a348ec69b8a..95aa0308c7d 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -1695,3 +1695,16 @@ bool BattlegroundAV::IsAllTowersControlledAndCaptainAlive(uint32 team) const return false; } + +uint32 BattlegroundAV::GetPrematureWinner() +{ + uint32 allianceScore = m_Team_Scores[GetTeamIndexByTeamId(ALLIANCE)]; + uint32 hordeScore = m_Team_Scores[GetTeamIndexByTeamId(HORDE)]; + + if (allianceScore > hordeScore) + return ALLIANCE; + else if (hordeScore > allianceScore) + return HORDE; + + return Battleground::GetPrematureWinner(); +}
\ No newline at end of file diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index dab67fe3258..bedd946a78c 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -1556,7 +1556,7 @@ class BattlegroundAV : public Battleground /*general stuff*/ void UpdateScore(uint16 team, int16 points); - void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true); + void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true); /*handlestuff*/ //these are functions which get called from extern void EventPlayerClickedOnFlag(Player* source, GameObject* target_obj); @@ -1572,6 +1572,8 @@ class BattlegroundAV : public Battleground /* achievement req. */ bool IsBothMinesControlledByTeam(uint32 team) const; bool IsAllTowersControlledAndCaptainAlive(uint32 team) const; + + uint32 GetPrematureWinner(); private: void PostUpdateImpl(uint32 diff); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index e900bc9b1d3..458e86729e7 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -937,3 +937,13 @@ bool BattlegroundEY::IsAllNodesConrolledByTeam(uint32 team) const return count == EY_POINTS_MAX; } + +uint32 BattlegroundEY::GetPrematureWinner() +{ + if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE)) + return ALLIANCE; + else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE)) + return HORDE; + + return Battleground::GetPrematureWinner(); +}
\ No newline at end of file diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 61ee5b16c1c..2cfd4ca7e0f 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -369,6 +369,8 @@ class BattlegroundEY : public Battleground /* achievement req. */ bool IsAllNodesConrolledByTeam(uint32 team) const; + + uint32 GetPrematureWinner(); private: void PostUpdateImpl(uint32 diff); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 1386af13186..9e58a93fd2d 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -20,6 +20,8 @@ #define __BATTLEGROUNDIC_H #include "Battleground.h" +#include "Language.h" +#include "Object.h" const uint32 BG_IC_Factions[2] = { diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 9f59344843c..663e5aed1e4 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -858,3 +858,12 @@ void BattlegroundWS::FillInitialWorldStates(WorldPacket& data) data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1); } +uint32 BattlegroundWS::GetPrematureWinner() +{ + if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE)) + return ALLIANCE; + else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE)) + return HORDE; + + return Battleground::GetPrematureWinner(); +} diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h index ec9f4ab1506..5b72de43b32 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h @@ -211,6 +211,8 @@ class BattlegroundWS : public Battleground void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; } void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } + + uint32 GetPrematureWinner(); private: uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde uint64 m_DroppedFlagGUID[2]; 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..1955eaa63aa 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/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 66f964fb4cf..3ccab6e5c6c 100755 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -23,6 +23,7 @@ #include "World.h" #include "DatabaseEnv.h" #include "AccountMgr.h" +#include "Player.h" Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) : m_announce(true), m_ownership(true), m_name(name), m_password(""), m_flags(0), m_channelId(channel_id), @@ -385,7 +386,7 @@ void Channel::Password(uint64 p, const char *pass) if (player) sec = player->GetSession()->GetSecurity(); - ChatHandler chat(player); + ChatHandler chat(player->GetSession()); if (!IsOn(p)) { diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index bd82a7cfc90..5f6be0e36de 100755 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -26,9 +26,10 @@ #include "Common.h" #include "Opcodes.h" -#include "Player.h" #include "WorldPacket.h" +class Player; + enum ChatNotify { CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel."; diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp index 78b71744e0e..66111e5a6db 100755 --- a/src/server/game/Chat/Channels/ChannelMgr.cpp +++ b/src/server/game/Chat/Channels/ChannelMgr.cpp @@ -17,7 +17,7 @@ */ #include "ChannelMgr.h" - +#include "Player.h" #include "World.h" ChannelMgr::~ChannelMgr() diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 4571f261587..8e2bc1fcc7a 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -1182,6 +1182,11 @@ int ChatHandler::GetSessionDbLocaleIndex() const return m_session->GetSessionDbLocaleIndex(); } +std::string ChatHandler::GetNameLink(Player* chr) const +{ + return playerLink(chr->GetName()); +} + const char *CliHandler::GetTrinityString(int32 entry) const { return sObjectMgr->GetTrinityStringForDBCLocale(entry); diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 0597ab216ec..167e6ca79d5 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -20,16 +20,18 @@ #define TRINITYCORE_CHAT_H #include "SharedDefines.h" -#include "Player.h" +#include "WorldSession.h" #include <vector> class ChatHandler; -class WorldSession; -class WorldObject; class Creature; +class Group; class Player; class Unit; +class WorldSession; +class WorldObject; + struct GameTele; class ChatCommand @@ -48,7 +50,6 @@ class ChatHandler public: WorldSession* GetSession() { return m_session; } explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) {} - explicit ChatHandler(Player* player) : m_session(player->GetSession()), sentErrorMessage(false) {} virtual ~ChatHandler() {} static void FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker, const char* addonPrefix = NULL); @@ -115,7 +116,7 @@ class ChatHandler bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL); std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; } - std::string GetNameLink(Player const* chr) const { return playerLink(chr->GetName()); } + std::string GetNameLink(Player* chr) const; GameObject* GetNearbyGameObject(); GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid, uint32 entry); diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index 7d5078a751e..8c2a3a22a70 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -19,6 +19,8 @@ #include "SpellMgr.h" #include "ObjectMgr.h" #include "SpellInfo.h" +#include "DBCStores.h" +#include "AchievementMgr.h" // Supported shift-links (client generated and server side) // |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index a640fae92d4..6c499645e39 100755 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -21,6 +21,7 @@ #include "OutdoorPvP.h" #include "SpellMgr.h" #include "VMapManager2.h" +#include "Player.h" namespace DisableMgr { diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 43b29c600d6..a6b51a4d395 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -21,6 +21,8 @@ #include "CreatureAI.h" #include "ObjectMgr.h" #include "TemporarySummon.h" +#include "Pet.h" +#include "Player.h" TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN), diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index db563c712cd..73b38c1da83 100755 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -23,6 +23,7 @@ #include "Bag.h" #include "Log.h" #include "UpdateData.h" +#include "Player.h" Bag::Bag(): Item() { diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 0c77402bf49..f01953a5441 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -26,6 +26,7 @@ #include "SpellInfo.h" #include "ScriptMgr.h" #include "ConditionMgr.h" +#include "Player.h" void AddItemsSetItem(Player* player, Item* item) { diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 5b427c48a4b..12bd99a3637 100755 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -25,6 +25,7 @@ #include <list> #include <vector> #include "Util.h" +#include "DBCStores.h" struct EnchStoreItem { diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e3ea4f77344..6da9bde6d16 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1996,7 +1996,7 @@ bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const if (obj->IsAlwaysDetectableFor(seer)) return true; - if (!seer->CanDetectInvisibilityOf(obj)) + if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj)) return false; if (!ignoreStealth && !seer->CanDetectStealthOf(obj)) diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 6e00fcbfe83..e7ecadae2f1 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -78,26 +78,6 @@ enum PetTalk PET_TALK_ATTACK = 1 }; -enum PetNameInvalidReason -{ - // custom, not send - PET_NAME_SUCCESS = 0, - - PET_NAME_INVALID = 1, - PET_NAME_NO_NAME = 2, - PET_NAME_TOO_SHORT = 3, - PET_NAME_TOO_LONG = 4, - PET_NAME_MIXED_LANGUAGES = 6, - PET_NAME_PROFANE = 7, - PET_NAME_RESERVED = 8, - PET_NAME_THREE_CONSECUTIVE = 11, - PET_NAME_INVALID_SPACE = 12, - PET_NAME_CONSECUTIVE_SPACES = 13, - PET_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 14, - PET_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 15, - PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16 -}; - typedef UNORDERED_MAP<uint32, PetSpell> PetSpellMap; typedef std::vector<uint32> AutoSpellList; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5e2fdae9c2c..d92e848e5d4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7220,7 +7220,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto int32 count = sWorld->getIntConfig(CONFIG_PVP_TOKEN_COUNT); if (AddItem(itemId, count)) - ChatHandler(this).PSendSysMessage("You have been awarded a token for slaying another player."); + ChatHandler(GetSession()).PSendSysMessage("You have been awarded a token for slaying another player."); } } @@ -20144,17 +20144,17 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) GetSession()->SendPacket(&data); } else // announce to player that player he is whispering to is dnd and cannot receive his message - ChatHandler(this).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->dndMsg.c_str()); + ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->dndMsg.c_str()); if (!isAcceptWhispers() && !isGameMaster() && !rPlayer->isGameMaster()) { SetAcceptWhispers(true); - ChatHandler(this).SendSysMessage(LANG_COMMAND_WHISPERON); + ChatHandler(GetSession()).SendSysMessage(LANG_COMMAND_WHISPERON); } // announce to player that player he is whispering to is afk if (rPlayer->isAFK()) - ChatHandler(this).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName().c_str(), rPlayer->afkMsg.c_str()); + ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName().c_str(), rPlayer->afkMsg.c_str()); // if player whisper someone, auto turn of dnd to be able to receive an answer if (isDND() && !rPlayer->isGameMaster()) @@ -25726,7 +25726,7 @@ bool Player::AddItem(uint32 itemId, uint32 count) if (count == 0 || dest.empty()) { // -- TODO: Send to mailbox if no space - ChatHandler(this).PSendSysMessage("You don't have any space in your bags."); + ChatHandler(GetSession()).PSendSysMessage("You don't have any space in your bags."); return false; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 18cc95444c0..b5c397057f4 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -21,29 +21,24 @@ #include <bitset> #include "AchievementMgr.h" -#include "Battleground.h" -#include "Bag.h" #include "Common.h" #include "DatabaseEnv.h" #include "DBCEnums.h" #include "GroupReference.h" -#include "ItemPrototype.h" #include "Item.h" #include "MapReference.h" -#include "NPCHandler.h" #include "Pet.h" #include "QuestDef.h" #include "ReputationMgr.h" #include "Unit.h" -#include "Util.h" // for Tokens typedef #include "WorldSession.h" #include "PhaseMgr.h" // for template #include "SpellMgr.h" -#include<string> -#include<vector> +#include <string> +#include <vector> struct Mail; struct ItemExtendedCostEntry; @@ -377,9 +372,7 @@ typedef std::list<PlayerCreateInfoAction> PlayerCreateInfoActions; struct PlayerInfo { // existence checked by displayId != 0 - PlayerInfo() : displayId_m(0), displayId_f(0), levelInfo(NULL) - { - } + PlayerInfo() : displayId_m(0), displayId_f(0), levelInfo(NULL) { } uint32 mapId; uint32 areaId; @@ -841,13 +834,6 @@ enum RestType REST_TYPE_IN_CITY = 2 }; -enum DuelCompleteType -{ - DUEL_INTERRUPTED = 0, - DUEL_WON = 1, - DUEL_FLED = 2 -}; - enum TeleportToOptions { TELE_TO_GM_MODE = 0x01, @@ -953,17 +939,6 @@ struct InstancePlayerBind InstancePlayerBind() : save(NULL), perm(false) {} }; -enum DungeonStatusFlag -{ - DUNGEON_STATUSFLAG_NORMAL = 0x01, - DUNGEON_STATUSFLAG_HEROIC = 0x02, - - RAID_STATUSFLAG_10MAN_NORMAL = 0x01, - RAID_STATUSFLAG_25MAN_NORMAL = 0x02, - RAID_STATUSFLAG_10MAN_HEROIC = 0x04, - RAID_STATUSFLAG_25MAN_HEROIC = 0x08 -}; - struct AccessRequirement { uint8 levelMin; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 117b93e8d90..1e849022d01 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -26,6 +26,7 @@ #include "DBCStores.h" #include "World.h" #include "GameObjectAI.h" +#include "Player.h" void MapManager::LoadTransports() { diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 7b9a99405e5..5e46d2c9ba7 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -29,6 +29,7 @@ #include "SpellMgr.h" #include "SpellInfo.h" #include "MoveSplineInit.h" +#include "TemporarySummon.h" Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry) { diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index b19abc778a9..6999eb301f5 100755 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -47,6 +47,12 @@ ObjectAccessor::~ObjectAccessor() { } +Player* ObjectAccessor::GetObjectInWorld(uint64 guid, Player* /*typeSpecifier*/) +{ + Player* player = HashMapHolder<Player>::Find(guid); + return player && player->IsInWorld() ? player : NULL; +} + WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid) { switch (GUID_HIPART(guid)) diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 41a7abc9a24..d2b532c9f94 100755 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -28,7 +28,6 @@ #include "GridDefines.h" #include "Object.h" -#include "Player.h" #include <set> @@ -116,11 +115,7 @@ class ObjectAccessor } // Player may be not in world while in ObjectAccessor - static Player* GetObjectInWorld(uint64 guid, Player* /*typeSpecifier*/) - { - Player* player = HashMapHolder<Player>::Find(guid); - return player && player->IsInWorld() ? player : NULL; - } + static Player* GetObjectInWorld(uint64 guid, Player* /*typeSpecifier*/); static Unit* GetObjectInWorld(uint64 guid, Unit* /*typeSpecifier*/) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 96e0c246f1c..37117c9edf4 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -231,11 +231,27 @@ bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clicke return true; } -ObjectMgr::ObjectMgr(): _auctionId(1), _equipmentSetGuid(1), - _itemTextId(1), _mailId(1), _hiPetNumber(1), _voidItemId(1), _hiCharGuid(1), - _hiCreatureGuid(1), _hiPetGuid(1), _hiVehicleGuid(1), _hiItemGuid(1), - _hiGoGuid(1), _hiDoGuid(1), _hiCorpseGuid(1), _hiMoTransGuid(1) -{} +ObjectMgr::ObjectMgr(): + _auctionId(1), + _equipmentSetGuid(1), + _itemTextId(1), + _mailId(1), + _hiPetNumber(1), + _voidItemId(1), + _hiCharGuid(1), + _hiCreatureGuid(1), + _hiPetGuid(1), + _hiVehicleGuid(1), + _hiItemGuid(1), + _hiGoGuid(1), + _hiDoGuid(1), + _hiCorpseGuid(1), + _hiMoTransGuid(1) +{ + for (uint8 i = 0; i < MAX_CLASSES; ++i) + for (uint8 j = 0; j < MAX_RACES; ++j) + _playerInfo[j][i] = NULL; +} ObjectMgr::~ObjectMgr() { @@ -247,7 +263,10 @@ ObjectMgr::~ObjectMgr() for (int race = 0; race < MAX_RACES; ++race) for (int class_ = 0; class_ < MAX_CLASSES; ++class_) - delete[] _playerInfo[race][class_].levelInfo; + { + delete[] _playerInfo[race][class_]->levelInfo; + delete _playerInfo[race][class_]; + } for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr) itr->second.Clear(); @@ -257,6 +276,9 @@ ObjectMgr::~ObjectMgr() for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr) for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr) delete *encounterItr; + + for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr) + delete itr->second; } void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data) @@ -2807,8 +2829,11 @@ PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint8 level) void ObjectMgr::PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count) { + if (!_playerInfo[race_][class_]) + return; + if (count > 0) - _playerInfo[race_][class_].item.push_back(PlayerCreateInfoItem(itemId, count)); + _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count)); else { if (count < -1) @@ -2915,17 +2940,16 @@ void ObjectMgr::LoadPlayerInfo() continue; } - PlayerInfo* pInfo = &_playerInfo[current_race][current_class]; - - pInfo->mapId = mapId; - pInfo->areaId = areaId; - pInfo->positionX = positionX; - pInfo->positionY = positionY; - pInfo->positionZ = positionZ; - pInfo->orientation = orientation; - - pInfo->displayId_m = rEntry->model_m; - pInfo->displayId_f = rEntry->model_f; + PlayerInfo* info = new PlayerInfo(); + info->mapId = mapId; + info->areaId = areaId; + info->positionX = positionX; + info->positionY = positionY; + info->positionZ = positionZ; + info->orientation = orientation; + info->displayId_m = rEntry->model_m; + info->displayId_f = rEntry->model_f; + _playerInfo[current_race][current_class] = info; ++count; } @@ -3048,10 +3072,16 @@ void ObjectMgr::LoadPlayerInfo() uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES; for (uint32 r = min_race; r < max_race; ++r) for (uint32 c = min_class; c < max_class; ++c) - _playerInfo[r][c].spell.push_back(fields[2].GetUInt32()); + if (PlayerInfo * info = _playerInfo[r][c]) + info->spell.push_back(fields[2].GetUInt32()); } + else if (PlayerInfo * info = _playerInfo[current_race][current_class]) + info->spell.push_back(fields[2].GetUInt32()); else - _playerInfo[current_race][current_class].spell.push_back(fields[2].GetUInt32()); + { + sLog->outError(LOG_FILTER_SQL, "Wrong race: %u, class: %u combination in `playercreateinfo_spell` table, ignoring.", current_race, current_class); + continue; + } ++count; } @@ -3096,8 +3126,8 @@ void ObjectMgr::LoadPlayerInfo() continue; } - PlayerInfo* pInfo = &_playerInfo[current_race][current_class]; - pInfo->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt16(), fields[3].GetUInt32(), fields[4].GetUInt16())); + if (PlayerInfo* info = _playerInfo[current_race][current_class]) + info->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt16(), fields[3].GetUInt32(), fields[4].GetUInt16())); ++count; } @@ -3155,16 +3185,14 @@ void ObjectMgr::LoadPlayerInfo() continue; } - PlayerInfo* pInfo = &_playerInfo[current_race][current_class]; - - if (!pInfo->levelInfo) - pInfo->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)]; - - PlayerLevelInfo* pLevelInfo = &pInfo->levelInfo[current_level-1]; - - for (int i = 0; i < MAX_STATS; i++) + if (PlayerInfo* info = _playerInfo[current_race][current_class]) { - pLevelInfo->stats[i] = fields[i+3].GetUInt8(); + if (!info->levelInfo) + info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)]; + + PlayerLevelInfo& levelInfo = info->levelInfo[current_level-1]; + for (int i = 0; i < MAX_STATS; i++) + levelInfo.stats[i] = fields[i+3].GetUInt8(); } ++count; @@ -3184,10 +3212,8 @@ void ObjectMgr::LoadPlayerInfo() if (!sChrClassesStore.LookupEntry(class_)) continue; - PlayerInfo* pInfo = &_playerInfo[race][class_]; - - // skip non loaded combinations - if (!pInfo->displayId_m || !pInfo->displayId_f) + PlayerInfo* info = _playerInfo[race][class_]; + if (!info) continue; // skip expansion races if not playing with expansion @@ -3199,7 +3225,7 @@ void ObjectMgr::LoadPlayerInfo() continue; // fatal error if no level 1 data - if (!pInfo->levelInfo || pInfo->levelInfo[0].stats[0] == 0) + if (!info->levelInfo || info->levelInfo[0].stats[0] == 0) { sLog->outError(LOG_FILTER_SQL, "Race %i Class %i Level 1 does not have stats data!", race, class_); exit(1); @@ -3208,10 +3234,10 @@ void ObjectMgr::LoadPlayerInfo() // fill level gaps for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) { - if (pInfo->levelInfo[level].stats[0] == 0) + if (info->levelInfo[level].stats[0] == 0) { sLog->outError(LOG_FILTER_SQL, "Race %i Class %i Level %i does not have stats data. Using stats data of level %i.", race, class_, level+1, level); - pInfo->levelInfo[level] = pInfo->levelInfo[level-1]; + info->levelInfo[level] = info->levelInfo[level-1]; } } } @@ -3305,8 +3331,8 @@ void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, Play if (level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES) return; - PlayerInfo const* pInfo = &_playerInfo[race][class_]; - if (pInfo->displayId_m == 0 || pInfo->displayId_f == 0) + PlayerInfo const* pInfo = _playerInfo[race][class_]; + if (!pInfo) return; if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) @@ -3318,7 +3344,7 @@ void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, Play void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, PlayerLevelInfo* info) const { // base data (last known level) - *info = _playerInfo[race][_class].levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)-1]; + *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)-1]; // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)-1; lvl < level; ++lvl) @@ -5848,7 +5874,13 @@ void ObjectMgr::LoadAccessRequirements() { uint32 oldMSTime = getMSTime(); - _accessRequirementStore.clear(); // need for reload case + if (!_accessRequirementStore.empty()) + { + for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr) + delete itr->second; + + _accessRequirementStore.clear(); // need for reload case + } // 0 1 2 3 4 5 6 7 8 9 QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement"); @@ -5870,61 +5902,61 @@ void ObjectMgr::LoadAccessRequirements() uint8 difficulty = fields[1].GetUInt8(); uint32 requirement_ID = MAKE_PAIR32(mapid, difficulty); - AccessRequirement ar; + AccessRequirement* ar = new AccessRequirement(); - ar.levelMin = fields[2].GetUInt8(); - ar.levelMax = fields[3].GetUInt8(); - ar.item = fields[4].GetUInt32(); - ar.item2 = fields[5].GetUInt32(); - ar.quest_A = fields[6].GetUInt32(); - ar.quest_H = fields[7].GetUInt32(); - ar.achievement = fields[8].GetUInt32(); - ar.questFailedText = fields[9].GetString(); + ar->levelMin = fields[2].GetUInt8(); + ar->levelMax = fields[3].GetUInt8(); + ar->item = fields[4].GetUInt32(); + ar->item2 = fields[5].GetUInt32(); + ar->quest_A = fields[6].GetUInt32(); + ar->quest_H = fields[7].GetUInt32(); + ar->achievement = fields[8].GetUInt32(); + ar->questFailedText = fields[9].GetString(); - if (ar.item) + if (ar->item) { - ItemTemplate const* pProto = GetItemTemplate(ar.item); + ItemTemplate const* pProto = GetItemTemplate(ar->item); if (!pProto) { - sLog->outError(LOG_FILTER_GENERAL, "Key item %u does not exist for map %u difficulty %u, removing key requirement.", ar.item, mapid, difficulty); - ar.item = 0; + sLog->outError(LOG_FILTER_GENERAL, "Key item %u does not exist for map %u difficulty %u, removing key requirement.", ar->item, mapid, difficulty); + ar->item = 0; } } - if (ar.item2) + if (ar->item2) { - ItemTemplate const* pProto = GetItemTemplate(ar.item2); + ItemTemplate const* pProto = GetItemTemplate(ar->item2); if (!pProto) { - sLog->outError(LOG_FILTER_GENERAL, "Second item %u does not exist for map %u difficulty %u, removing key requirement.", ar.item2, mapid, difficulty); - ar.item2 = 0; + sLog->outError(LOG_FILTER_GENERAL, "Second item %u does not exist for map %u difficulty %u, removing key requirement.", ar->item2, mapid, difficulty); + ar->item2 = 0; } } - if (ar.quest_A) + if (ar->quest_A) { - if (!GetQuestTemplate(ar.quest_A)) + if (!GetQuestTemplate(ar->quest_A)) { - sLog->outError(LOG_FILTER_SQL, "Required Alliance Quest %u not exist for map %u difficulty %u, remove quest done requirement.", ar.quest_A, mapid, difficulty); - ar.quest_A = 0; + sLog->outError(LOG_FILTER_SQL, "Required Alliance Quest %u not exist for map %u difficulty %u, remove quest done requirement.", ar->quest_A, mapid, difficulty); + ar->quest_A = 0; } } - if (ar.quest_H) + if (ar->quest_H) { - if (!GetQuestTemplate(ar.quest_H)) + if (!GetQuestTemplate(ar->quest_H)) { - sLog->outError(LOG_FILTER_SQL, "Required Horde Quest %u not exist for map %u difficulty %u, remove quest done requirement.", ar.quest_H, mapid, difficulty); - ar.quest_H = 0; + sLog->outError(LOG_FILTER_SQL, "Required Horde Quest %u not exist for map %u difficulty %u, remove quest done requirement.", ar->quest_H, mapid, difficulty); + ar->quest_H = 0; } } - if (ar.achievement) + if (ar->achievement) { - if (!sAchievementMgr->GetAchievement(ar.achievement)) + if (!sAchievementMgr->GetAchievement(ar->achievement)) { - sLog->outError(LOG_FILTER_SQL, "Required Achievement %u not exist for map %u difficulty %u, remove quest done requirement.", ar.achievement, mapid, difficulty); - ar.achievement = 0; + sLog->outError(LOG_FILTER_SQL, "Required Achievement %u not exist for map %u difficulty %u, remove quest done requirement.", ar->achievement, mapid, difficulty); + ar->achievement = 0; } } @@ -8074,9 +8106,9 @@ void ObjectMgr::LoadGossipMenuItems() _gossipMenuItemsStore.clear(); QueryResult result = WorldDatabase.Query( - // 0 1 2 3 4 + // 0 1 2 3 4 5 "SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, " - // 5 6 7 8 9 + // 6 7 8 9 10 "action_menu_id, action_poi_id, box_coded, box_money, box_text " "FROM gossip_menu_option ORDER BY menu_id, id"); @@ -8179,7 +8211,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (!cInfo) { if (player) - ChatHandler(player).SendSysMessage(LANG_COMMAND_VENDORSELECTION); + ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry); return false; @@ -8190,7 +8222,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (!skip_vendors || skip_vendors->count(vendor_entry) == 0) { if (player) - ChatHandler(player).SendSysMessage(LANG_COMMAND_VENDORSELECTION); + ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry); @@ -8204,7 +8236,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount (type == ITEM_VENDOR_TYPE_CURRENCY && !sCurrencyTypesStore.LookupEntry(id))) { if (player) - ChatHandler(player).PSendSysMessage(LANG_ITEM_NOT_FOUND, id, type); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_NOT_FOUND, id, type); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u, type %u), ignore", vendor_entry, id, type); return false; @@ -8213,7 +8245,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) { if (player) - ChatHandler(player).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", id, ExtendedCost, vendor_entry); return false; @@ -8224,7 +8256,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (maxcount > 0 && incrtime == 0) { if (player) - ChatHandler(player).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount); + ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, id, vendor_entry); return false; @@ -8232,7 +8264,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount else if (maxcount == 0 && incrtime > 0) { if (player) - ChatHandler(player).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0"); + ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0"); else sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", id, vendor_entry); return false; @@ -8246,7 +8278,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (vItems->FindItemCostPair(id, ExtendedCost, type)) { if (player) - ChatHandler(player).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, id, ExtendedCost, type); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, id, ExtendedCost, type); else sLog->outError(LOG_FILTER_SQL, "Table `npc_vendor` has duplicate items %u (with extended cost %u, type %u) for vendor (Entry: %u), ignoring", id, ExtendedCost, type, vendor_entry); return false; @@ -8255,7 +8287,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount if (vItems->GetItemCount() >= MAX_VENDOR_ITEMS) // FIXME: GetItemCount range 0...255 MAX_VENDOR_ITEMS = 300 { if (player) - ChatHandler(player).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS); + ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS); else sLog->outError(LOG_FILTER_SQL, "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry); return false; @@ -8801,3 +8833,15 @@ VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) con return &itr->second; return NULL; } + +PlayerInfo const* ObjectMgr::GetPlayerInfo(uint32 race, uint32 class_) const +{ + if (race >= MAX_RACES) + return NULL; + if (class_ >= MAX_CLASSES) + return NULL; + PlayerInfo const* info = _playerInfo[race][class_]; + if (!info) + return NULL; + return info; +} diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index e7575bec5d8..ab4306bbc87 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -23,7 +23,6 @@ #include "Object.h" #include "Bag.h" #include "Creature.h" -#include "Player.h" #include "DynamicObject.h" #include "GameObject.h" #include "Corpse.h" @@ -46,6 +45,9 @@ class Item; class PhaseMgr; +struct AccessRequirement; +struct PlayerInfo; +struct PlayerLevelInfo; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform #if defined(__GNUC__) @@ -608,7 +610,7 @@ class ObjectMgr typedef UNORDERED_MAP<uint32, uint32> AreaTriggerScriptContainer; - typedef UNORDERED_MAP<uint32, AccessRequirement> AccessRequirementContainer; + typedef UNORDERED_MAP<uint32, AccessRequirement*> AccessRequirementContainer; typedef UNORDERED_MAP<uint32, RepRewardRate > RepRewardRateContainer; typedef UNORDERED_MAP<uint32, ReputationOnKillEntry> RepOnKillContainer; @@ -647,17 +649,7 @@ class ObjectMgr void GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& baseHP, uint32& baseMana) const; - PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const - { - if (race >= MAX_RACES) - return NULL; - if (class_ >= MAX_CLASSES) - return NULL; - PlayerInfo const* info = &_playerInfo[race][class_]; - if (info->displayId_m == 0 || info->displayId_f == 0) - return NULL; - return info; - } + PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const; void GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const; @@ -718,7 +710,7 @@ class ObjectMgr { AccessRequirementContainer::const_iterator itr = _accessRequirementStore.find(MAKE_PAIR32(mapid, difficulty)); if (itr != _accessRequirementStore.end()) - return &itr->second; + return itr->second; return NULL; } @@ -1249,7 +1241,7 @@ class ObjectMgr void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const; - PlayerInfo _playerInfo[MAX_RACES][MAX_CLASSES]; + PlayerInfo* _playerInfo[MAX_RACES][MAX_CLASSES]; typedef std::vector<uint32> PlayerXPperLevel; // [level] PlayerXPperLevel _playerXPperLevel; diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 626cba7bb2f..357f5db7136 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -19,16 +19,14 @@ #ifndef TRINITYCORE_GROUP_H #define TRINITYCORE_GROUP_H -#include "Battleground.h" #include "DBCEnums.h" #include "GroupRefManager.h" #include "LootMgr.h" #include "QueryResult.h" #include "SharedDefines.h" -#include "Player.h" -#include "Battlefield.h" -#include "BattlefieldMgr.h" +class Battlefield; +class Battleground; class Creature; class GroupReference; class InstanceSave; diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index 77b3a304f6b..8283075a226 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -18,6 +18,8 @@ #include "Common.h" #include "GroupMgr.h" #include "InstanceSaveMgr.h" +#include "World.h" +#include "DBCStores.h" GroupMgr::GroupMgr() { diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 1a73974b906..3d06b266afb 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -27,6 +27,7 @@ #include "Log.h" #include "AccountMgr.h" #include "AchievementMgr.h" +#include "CalendarMgr.h" #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -1833,6 +1834,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, uint64 guid) @@ -2541,6 +2544,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 36d8d56b30c..fc90a492399 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -826,6 +826,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..3301b821f2b 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,25 @@ 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); -} - -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); + 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"); + + /* + 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 +682,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); } diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 7db49e50fa2..6e2314c2e16 100755 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -18,6 +18,7 @@ #include "ObjectMgr.h" // for normalizePlayerName #include "ChannelMgr.h" +#include "Player.h" void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) { diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index a285b38f46f..5017a2a7c9d 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -45,6 +45,7 @@ #include "AccountMgr.h" #include "DBCStores.h" #include "LFGMgr.h" +#include "CalendarMgr.h" class LoginQueryHolder : public SQLQueryHolder { @@ -753,6 +754,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData) } sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid); + sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid); Player::DeleteFromDB(guid, GetAccountId()); WorldPacket data(SMSG_CHAR_DELETE, 1); @@ -827,7 +829,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) Player* pCurrChar = new Player(this); // for send server info and strings (config) - ChatHandler chH = ChatHandler(pCurrChar); + ChatHandler chH = ChatHandler(pCurrChar->GetSession()); // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 1cd86afc6d2..391a6fc0831 100755 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -25,6 +25,7 @@ #include "ObjectDefines.h" #include "Vehicle.h" #include "VehicleDefines.h" +#include "Player.h" void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 5df7b20b596..428eee37db0 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -645,10 +645,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/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index bf260743d6a..2d34727bfbe 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -887,7 +887,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) } if (player->isDebugAreaTriggers) - ChatHandler(player).PSendSysMessage(LANG_DEBUG_AREATRIGGER_REACHED, triggerId); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_REACHED, triggerId); if (sScriptMgr->OnAreaTrigger(player, atEntry)) return; diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 2d3af13597a..785f39c4a8e 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -31,6 +31,7 @@ #include "World.h" #include "Group.h" #include "SpellInfo.h" +#include "Player.h" void WorldSession::HandleDismissCritter(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 33824fa0b49..d221a8ac80d 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -33,6 +33,7 @@ #include "ScriptMgr.h" #include "GameObjectAI.h" #include "SpellAuraEffects.h" +#include "Player.h" void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets) { diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 904f571c9d3..68f6626b3b1 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -25,6 +25,7 @@ #include "SpellMgr.h" #include "SpellInfo.h" #include "Group.h" +#include "Player.h" static Rates const qualityToRate[MAX_ITEM_QUALITY] = { 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 a514315f748..74394ced53a 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/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index f3c1a335f5e..cf773ba7ead 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -33,6 +33,7 @@ #include "LFGMgr.h" #include "DynamicTree.h" #include "Vehicle.h" +#include "Battleground.h" union u_map_magic { @@ -144,7 +145,7 @@ void Map::LoadMap(int gx, int gy, bool reload) // load grid map for base map if (!m_parentMap->GridMaps[gx][gy]) - m_parentMap->EnsureGridCreated(GridCoord(63-gx, 63-gy)); + m_parentMap->EnsureGridCreated_i(GridCoord(63-gx, 63-gy)); ((MapInstanced*)(m_parentMap))->AddGridMapReference(GridCoord(gx, gy)); GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy]; @@ -307,32 +308,34 @@ void Map::DeleteFromWorld(Player* player) delete player; } +void Map::EnsureGridCreated(const GridCoord &p) +{ + TRINITY_GUARD(ACE_Thread_Mutex, Lock); + EnsureGridCreated_i(p); +} + //Create NGrid so the object can be added to it //But object data is not loaded here -void Map::EnsureGridCreated(const GridCoord &p) +void Map::EnsureGridCreated_i(const GridCoord &p) { if (!getNGrid(p.x_coord, p.y_coord)) { - TRINITY_GUARD(ACE_Thread_Mutex, Lock); - if (!getNGrid(p.x_coord, p.y_coord)) - { - sLog->outDebug(LOG_FILTER_MAPS, "Creating grid[%u, %u] for map %u instance %u", p.x_coord, p.y_coord, GetId(), i_InstanceId); + sLog->outDebug(LOG_FILTER_MAPS, "Creating grid[%u, %u] for map %u instance %u", p.x_coord, p.y_coord, GetId(), i_InstanceId); - setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld->getBoolConfig(CONFIG_GRID_UNLOAD)), - p.x_coord, p.y_coord); + setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld->getBoolConfig(CONFIG_GRID_UNLOAD)), + p.x_coord, p.y_coord); - // build a linkage between this map and NGridType - buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); + // build a linkage between this map and NGridType + buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); - getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); + getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); - //z coord - int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; - int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; + //z coord + int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; + int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; - if (!GridMaps[gx][gy]) - LoadMapAndVMap(gx, gy); - } + if (!GridMaps[gx][gy]) + LoadMapAndVMap(gx, gy); } } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 53588c527e3..e3fa1ac6ae4 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -500,6 +500,7 @@ class Map : public GridRefManager<NGridType> bool IsGridLoaded(const GridCoord &) const; void EnsureGridCreated(const GridCoord &); + void EnsureGridCreated_i(const GridCoord &); bool EnsureGridLoaded(Cell const&); void EnsureGridLoadedForActiveObject(Cell const&, WorldObject* object); diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 5fcca05361b..9ca8155e83b 100755 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -24,6 +24,7 @@ #include "InstanceSaveMgr.h" #include "World.h" #include "Group.h" +#include "Player.h" MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL) { @@ -280,4 +281,4 @@ bool MapInstanced::CanEnter(Player* /*player*/) { //ASSERT(false); return true; -}
\ No newline at end of file +} diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 71f45a8b04e..0ead173ed95 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -33,6 +33,7 @@ #include "Language.h" #include "WorldPacket.h" #include "Group.h" +#include "Player.h" extern GridState* si_GridStates[]; // debugging code, should be deleted some day @@ -439,4 +440,4 @@ void MapManager::FreeInstanceId(uint32 instanceId) SetNextInstanceId(instanceId); _instanceIds[instanceId] = false; -}
\ No newline at end of file +} diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp index 194c89fc5c8..38c9b3fc6e9 100644 --- a/src/server/game/Maps/PhaseMgr.cpp +++ b/src/server/game/Maps/PhaseMgr.cpp @@ -18,6 +18,7 @@ #include "PhaseMgr.h" #include "Chat.h" #include "ObjectMgr.h" +#include "Player.h" ////////////////////////////////////////////////////////////////// // Updating @@ -174,31 +175,31 @@ void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect) void PhaseMgr::SendDebugReportToPlayer(Player* const debugger) { - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName().c_str(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName().c_str(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags); PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); if (itr == _PhaseDefinitionStore->end()) - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId()); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId()); else { for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) { if (CheckDefinition(&(*phase))) - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask); else - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId); if (phase->IsLastDefinition()) { - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId); break; } } } - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask); - ChatHandler(debugger).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask()); + ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask()); } void PhaseMgr::SetCustomPhase(uint32 const phaseMask) diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index 3cf4b1f96b7..6e6668ba4d6 100755 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -22,6 +22,7 @@ #include "World.h" #include "SharedDefines.h" #include "ScriptMgr.h" +#include "Player.h" namespace Trinity { diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index b5b7bb4a6cf..057895898e5 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3731,106 +3731,82 @@ enum ProfessionUI MAX_SECONDARY_SKILLS = 5 }; -// Calendar - start - -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 -}; - -// Calendar - end +enum DuelCompleteType +{ + DUEL_INTERRUPTED = 0, + DUEL_WON = 1, + DUEL_FLED = 2 +}; +// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time +enum BattlegroundQueueTypeId +{ + BATTLEGROUND_QUEUE_NONE = 0, + BATTLEGROUND_QUEUE_AV = 1, + BATTLEGROUND_QUEUE_WS = 2, + BATTLEGROUND_QUEUE_AB = 3, + BATTLEGROUND_QUEUE_EY = 4, + BATTLEGROUND_QUEUE_SA = 5, + BATTLEGROUND_QUEUE_IC = 6, + BATTLEGROUND_QUEUE_TP = 7, + BATTLEGROUND_QUEUE_BFG = 8, + BATTLEGROUND_QUEUE_RB = 9, + BATTLEGROUND_QUEUE_2v2 = 10, + BATTLEGROUND_QUEUE_3v3 = 11, + BATTLEGROUND_QUEUE_5v5 = 12, + MAX_BATTLEGROUND_QUEUE_TYPES +}; + +enum GroupJoinBattlegroundResult +{ + // positive values are indexes in BattlemasterList.dbc + ERR_GROUP_JOIN_BATTLEGROUND_FAIL = 0, // Your group has joined a battleground queue, but you are not eligible (showed for non existing BattlemasterList.dbc indexes) + ERR_BATTLEGROUND_NONE = -1, // not show anything + ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS = -2, // You cannot join the battleground yet because you or one of your party members is flagged as a Deserter. + ERR_ARENA_TEAM_PARTY_SIZE = -3, // Incorrect party size for this arena. + ERR_BATTLEGROUND_TOO_MANY_QUEUES = -4, // You can only be queued for 2 battles at once + ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED = -5, // You cannot queue for a rated match while queued for other battles + ERR_BATTLEDGROUND_QUEUED_FOR_RATED = -6, // You cannot queue for another battle while queued for a rated arena match + ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = -7, // Your team has left the arena queue + ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND = -8, // You can't do that in a battleground. + ERR_BATTLEGROUND_JOIN_XP_GAIN = -9, // wtf, doesn't exist in client... + ERR_BATTLEGROUND_JOIN_RANGE_INDEX = -10, // Cannot join the queue unless all members of your party are in the same battleground level range. + ERR_BATTLEGROUND_JOIN_TIMED_OUT = -11, // %s was unavailable to join the queue. (uint64 guid exist in client cache) + ERR_BATTLEGROUND_JOIN_FAILED = -12, // Join as a group failed (uint64 guid doesn't exist in client cache) + ERR_LFG_CANT_USE_BATTLEGROUND = -13, // You cannot queue for a battleground or arena while using the dungeon system. + ERR_IN_RANDOM_BG = -14, // Can't do that while in a Random Battleground queue. + ERR_IN_NON_RANDOM_BG = -15 // Can't queue for Random Battleground while in another Battleground queue. +}; + +enum PetNameInvalidReason +{ + // custom, not send + PET_NAME_SUCCESS = 0, + + PET_NAME_INVALID = 1, + PET_NAME_NO_NAME = 2, + PET_NAME_TOO_SHORT = 3, + PET_NAME_TOO_LONG = 4, + PET_NAME_MIXED_LANGUAGES = 6, + PET_NAME_PROFANE = 7, + PET_NAME_RESERVED = 8, + PET_NAME_THREE_CONSECUTIVE = 11, + PET_NAME_INVALID_SPACE = 12, + PET_NAME_CONSECUTIVE_SPACES = 13, + PET_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 14, + PET_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 15, + PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16 +}; + +enum DungeonStatusFlag +{ + DUNGEON_STATUSFLAG_NORMAL = 0x01, + DUNGEON_STATUSFLAG_HEROIC = 0x02, + + RAID_STATUSFLAG_10MAN_NORMAL = 0x01, + RAID_STATUSFLAG_25MAN_NORMAL = 0x02, + RAID_STATUSFLAG_10MAN_HEROIC = 0x04, + RAID_STATUSFLAG_25MAN_HEROIC = 0x08 +}; #define VOID_STORAGE_UNLOCK 100*GOLD #define VOID_STORAGE_STORE_ITEM 25*GOLD diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 313a29a1b59..b070e21ed5b 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -23,6 +23,7 @@ #include "ObjectAccessor.h" #include "MoveSplineInit.h" #include "MoveSpline.h" +#include "Player.h" #define MIN_QUIET_DISTANCE 28.0f #define MAX_QUIET_DISTANCE 43.0f diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 93dae4c63f2..570a508f7d2 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -30,6 +30,7 @@ #include "SpellScript.h" #include "GossipDef.h" #include "CreatureAI.h" +#include "Player.h" // This is the global static registry of scripts. template<class TScript> diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index b245039dc92..22625d74e10 100755 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -24,7 +24,6 @@ #include <ace/Atomic_Op.h> #include "DBCStores.h" -#include "Player.h" #include "SharedDefines.h" #include "World.h" #include "Weather.h" diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 116f953b2a3..93efc8d2132 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -493,7 +493,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_SET_PRIMARY_TALENT_TREE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend ); DEFINE_OPCODE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode ); DEFINE_OPCODE_HANDLER(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode ); DEFINE_OPCODE_HANDLER(CMSG_SET_TITLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode ); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 885c7017d62..0c4220e9ea6 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -32,8 +32,6 @@ #include "Cryptography/BigNumber.h" #include "Opcodes.h" -class CalendarEvent; -class CalendarInvite; class Creature; class GameObject; class InstanceSave; @@ -933,19 +931,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 Storage void HandleVoidStorageUnlock(WorldPacket& recvData); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index df3c2d77c02..73f19ba3f3c 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -29,7 +29,7 @@ #include "WorldSocket.h" #include "Common.h" - +#include "Player.h" #include "Util.h" #include "World.h" #include "WorldPacket.h" diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d66d60fece9..4c22328cd26 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5476,7 +5476,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetCharmerGUID()) return SPELL_FAILED_CHARMED; - + if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 9faf9a1f850..65eea69714a 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -21,7 +21,8 @@ #include "Spell.h" #include "DBCStores.h" #include "ConditionMgr.h" -#include "Object.h" +#include "Player.h" +#include "Battleground.h" uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) { diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 636ef607e2b..9abb82bbc4b 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -21,6 +21,7 @@ #include "SharedDefines.h" #include "Util.h" #include "DBCStructure.h" +#include "SpellAuraDefines.h" class Unit; class Player; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 600b9dc65a3..38e2155ba4a 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -32,6 +32,7 @@ #include "BattlegroundIC.h" #include "BattlefieldWG.h" #include "BattlefieldMgr.h" +#include "Player.h" bool IsPrimaryProfessionSkill(uint32 skill) { @@ -80,6 +81,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, // Gnaw else if (spellproto->Id == 47481) return DIMINISHING_CONTROLLED_STUN; + // ToC Icehowl Arctic Breath + else if (spellproto->SpellVisual[0] == 14153) + return DIMINISHING_NONE; break; } // Event spells @@ -373,7 +377,7 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg if (msg) { if (player) - ChatHandler(player).PSendSysMessage("Craft spell %u not have create item entry.", spellInfo->Id); + ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u not have create item entry.", spellInfo->Id); else sLog->outError(LOG_FILTER_SQL, "Craft spell %u not have create item entry.", spellInfo->Id); } @@ -387,7 +391,7 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg if (msg) { if (player) - ChatHandler(player).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType); + ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType); else sLog->outError(LOG_FILTER_SQL, "Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType); } @@ -405,7 +409,7 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg if (msg) { if (player) - ChatHandler(player).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell); + ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell); else sLog->outError(LOG_FILTER_SQL, "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell); } @@ -425,7 +429,7 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg if (msg) { if (player) - ChatHandler(player).PSendSysMessage("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]); + ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]); else sLog->outError(LOG_FILTER_SQL, "Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]); } diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index ffcb65bb14b..89dd28f6a30 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -24,6 +24,7 @@ #include "WorldSession.h" #include "Chat.h" #include "World.h" +#include "Player.h" inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; } diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index fce078a0a14..6148005ca6b 100755 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -25,6 +25,7 @@ #include "Log.h" #include "ObjectMgr.h" #include "AutoPtr.h" +#include "Player.h" namespace WeatherMgr { |
