mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
LFGMgr.cpp and LFGMgr.h added to Three
LFGMgr.cpp and LFGMgr.h added to Three. This is part of the current build error fixes,
This commit is contained in:
parent
165cfba9c4
commit
8ef55a922f
10 changed files with 3053 additions and 49 deletions
|
|
@ -708,6 +708,28 @@ class ObjectMgr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
DungeonFinderRequirements const* GetDungeonFinderRequirements(uint32 mapId, uint32 difficulty) const
|
||||
{
|
||||
DungeonFinderRequirementsMap::const_iterator itr = mDungeonFinderRequirementsMap.find(MAKE_PAIR32(mapId, difficulty));
|
||||
if (itr != mDungeonFinderRequirementsMap.end())
|
||||
return &itr->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DungeonFinderRewards const* GetDungeonFinderRewards(uint32 level) const
|
||||
{
|
||||
DungeonFinderRewardsMap::const_iterator itr = mDungeonFinderRewardsMap.find(level);
|
||||
if (itr != mDungeonFinderRewardsMap.end())
|
||||
{
|
||||
return &itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DungeonFinderRequirementsMap const& GetDungeonFinderRequirementsMap() const { return mDungeonFinderRequirementsMap; }
|
||||
DungeonFinderRewardsMap const& GetDungeonFinderRewardsMap() const { return mDungeonFinderRewardsMap; }
|
||||
DungeonFinderItemsMap const& GetDungeonFinderItemsMap() const { return mDungeonFinderItemsMap; }
|
||||
|
||||
// Static wrappers for various accessors
|
||||
static GameObjectInfo const* GetGameObjectInfo(uint32 id); ///< Wrapper for sGOStorage.LookupEntry
|
||||
static Player* GetPlayer(const char* name); ///< Wrapper for ObjectAccessor::FindPlayerByName
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
|
|||
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
|
||||
extern DBCStorage <ItemReforgeEntry> sItemReforgeStore;
|
||||
extern DBCStorage <ItemSetEntry> sItemSetStore;
|
||||
extern DBCStorage <LfgDungeonsEntry> sLfgDungeonsStore;
|
||||
extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
|
||||
extern DBCStorage <LockEntry> sLockStore;
|
||||
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
||||
|
|
|
|||
|
|
@ -1249,26 +1249,28 @@ struct ItemSetEntry
|
|||
uint32 required_skill_value; // 36 m_requiredSkillRank
|
||||
};
|
||||
|
||||
/*struct LfgDungeonsEntry
|
||||
struct LfgDungeonsEntry
|
||||
{
|
||||
m_ID
|
||||
m_name_lang
|
||||
m_minLevel
|
||||
m_maxLevel
|
||||
m_target_level
|
||||
m_target_level_min
|
||||
m_target_level_max
|
||||
m_mapID
|
||||
m_difficulty
|
||||
m_flags
|
||||
m_typeID
|
||||
m_faction
|
||||
m_textureFilename
|
||||
m_expansionLevel
|
||||
m_order_index
|
||||
m_group_id
|
||||
m_description_lang
|
||||
};*/
|
||||
uint32 ID; // 0 m_ID
|
||||
char* name[16]; // 1-16 m_name_lang
|
||||
uint32 minLevel; // 18 m_minLevel
|
||||
uint32 maxLevel; // 19 m_maxLevel
|
||||
uint32 targetLevel; // 20 m_target_level
|
||||
uint32 targetLevelMin; // 21 m_target_level_min
|
||||
uint32 targetLevelMax; // 22 m_target_level_max
|
||||
int32 mapID; // 23 m_mapID
|
||||
uint32 difficulty; // 24 m_difficulty
|
||||
uint32 flags; // 25 m_flags
|
||||
uint32 typeID; // 26 m_typeID
|
||||
//uint32 faction; // 27 m_faction
|
||||
//char* textureFilename; // 28 m_textureFilename
|
||||
uint32 expansionLevel; // 29 m_expansionLevel
|
||||
uint32 orderIndex; // 30 m_order_index
|
||||
uint32 groupID; // 31 m_group_id
|
||||
//char* description[16]; // 32-49 m_Description_lang
|
||||
|
||||
uint32 Entry() const { return ID + ((uint8)typeID << 24); }
|
||||
};
|
||||
|
||||
/*struct LfgDungeonGroupEntry
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "ObjectGuid.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Item.h"
|
||||
#include "LFGMgr.h"
|
||||
|
||||
struct ItemPrototype;
|
||||
struct AuctionEntry;
|
||||
|
|
@ -140,28 +141,9 @@ enum PartyResult
|
|||
ERR_PARTY_LFG_TELEPORT_IN_COMBAT = 30
|
||||
};
|
||||
|
||||
enum LfgJoinResult
|
||||
{
|
||||
ERR_LFG_OK = 0x00,
|
||||
ERR_LFG_ROLE_CHECK_FAILED = 0x01,
|
||||
ERR_LFG_GROUP_FULL = 0x02,
|
||||
ERR_LFG_NO_LFG_OBJECT = 0x04,
|
||||
ERR_LFG_NO_SLOTS_PLAYER = 0x05,
|
||||
ERR_LFG_NO_SLOTS_PARTY = 0x06,
|
||||
ERR_LFG_MISMATCHED_SLOTS = 0x07,
|
||||
ERR_LFG_PARTY_PLAYERS_FROM_DIFFERENT_REALMS = 0x08,
|
||||
ERR_LFG_MEMBERS_NOT_PRESENT = 0x09,
|
||||
ERR_LFG_GET_INFO_TIMEOUT = 0x0A,
|
||||
ERR_LFG_INVALID_SLOT = 0x0B,
|
||||
ERR_LFG_DESERTER_PLAYER = 0x0C,
|
||||
ERR_LFG_DESERTER_PARTY = 0x0D,
|
||||
ERR_LFG_RANDOM_COOLDOWN_PLAYER = 0x0E,
|
||||
ERR_LFG_RANDOM_COOLDOWN_PARTY = 0x0F,
|
||||
ERR_LFG_TOO_MANY_MEMBERS = 0x10,
|
||||
ERR_LFG_CANT_USE_DUNGEONS = 0x11,
|
||||
ERR_LFG_ROLE_CHECK_FAILED2 = 0x12,
|
||||
};
|
||||
|
||||
/*
|
||||
* these have been moved to LFGMgr.h for dev21
|
||||
* delete from here once all is good with the move
|
||||
enum LfgUpdateType
|
||||
{
|
||||
LFG_UPDATE_JOIN = 5,
|
||||
|
|
@ -178,6 +160,7 @@ enum LfgType
|
|||
LFG_TYPE_HEROIC_DUNGEON = 5,
|
||||
LFG_TYPE_RANDOM_DUNGEON = 6
|
||||
};
|
||||
*/
|
||||
|
||||
enum ChatRestrictionType
|
||||
{
|
||||
|
|
@ -255,8 +238,20 @@ class WorldSession
|
|||
void SendNotification(int32 string_id, ...);
|
||||
void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName* declinedName);
|
||||
void SendLfgSearchResults(LfgType type, uint32 entry);
|
||||
void SendLfgJoinResult(LfgJoinResult result);
|
||||
void SendLfgUpdate(bool isGroup, LfgUpdateType updateType, uint32 id);
|
||||
|
||||
// void SendLfgJoinResult(LfgJoinResult result); // delete this if the below proves to work
|
||||
void SendLfgJoinResult(LfgJoinResult result, LFGState state, partyForbidden const& lockedDungeons);
|
||||
|
||||
// void SendLfgUpdate(bool isGroup, LfgUpdateType updateType, uint32 id); // delete this if the below proves to work
|
||||
void SendLfgUpdate(bool isGroup, LFGPlayerStatus status);
|
||||
void SendLfgQueueStatus(LFGQueueStatus const& status);
|
||||
void SendLfgRoleCheckUpdate(LFGRoleCheck const& roleCheck);
|
||||
void SendLfgRoleChosen(uint64 rawGuid, uint8 roles);
|
||||
void SendLfgProposalUpdate(LFGProposal const& proposal);
|
||||
void SendLfgTeleportError(uint8 error);
|
||||
void SendLfgRewards(LFGRewards const& rewards);
|
||||
void SendLfgBootUpdate(LFGBoot const& boot);
|
||||
|
||||
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
|
||||
void SendGuildInvite(Player* player, bool alreadyInGuild = false);
|
||||
void SendGroupInvite(Player* player, bool alreadyInGroup = false);
|
||||
|
|
|
|||
|
|
@ -255,13 +255,14 @@ class Group
|
|||
void SetLootThreshold(ItemQualities threshold) { m_lootThreshold = threshold; }
|
||||
void Disband(bool hideDestroy = false);
|
||||
|
||||
// properties accessories
|
||||
// properties accessors
|
||||
uint32 GetId() const { return m_Id; }
|
||||
ObjectGuid GetObjectGuid() const { return ObjectGuid(HIGHGUID_GROUP, GetId()); }
|
||||
bool IsFull() const { return (m_groupType == GROUPTYPE_NORMAL) ? (m_memberSlots.size() >= MAX_GROUP_SIZE) : (m_memberSlots.size() >= MAX_RAID_SIZE); }
|
||||
GroupType GetGroupType() const { return m_groupType; }
|
||||
bool isRaidGroup() const { return m_groupType & GROUPTYPE_RAID; }
|
||||
bool isBGGroup() const { return m_bgGroup != NULL; }
|
||||
bool isLFGGroup() const { return m_groupType & GROUPTYPE_LFD; }
|
||||
bool IsCreated() const { return GetMembersCount() > 0; }
|
||||
ObjectGuid GetLeaderGuid() const { return m_leaderGuid; }
|
||||
const char* GetLeaderName() const { return m_leaderName.c_str(); }
|
||||
|
|
@ -270,6 +271,7 @@ class Group
|
|||
ItemQualities GetLootThreshold() const { return m_lootThreshold; }
|
||||
|
||||
// member manipulation methods
|
||||
void SetAsLfgGroup() { m_groupType = GroupType(m_groupType | GROUPTYPE_LFD); }
|
||||
bool IsMember(ObjectGuid guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); }
|
||||
bool IsLeader(ObjectGuid guid) const { return GetLeaderGuid() == guid; }
|
||||
ObjectGuid GetMemberGuid(const std::string& name)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "Log.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
|
|
@ -222,6 +223,9 @@ void WorldSession::SendLfgSearchResults(LfgType type, uint32 entry)
|
|||
SendPacket(&data);
|
||||
}
|
||||
|
||||
/*
|
||||
* pre dev21 version
|
||||
* delete this if the one below it proves to be good (chucky)
|
||||
void WorldSession::SendLfgJoinResult(LfgJoinResult result)
|
||||
{
|
||||
WorldPacket data(SMSG_LFG_JOIN_RESULT, 0);
|
||||
|
|
@ -246,7 +250,41 @@ void WorldSession::SendLfgJoinResult(LfgJoinResult result)
|
|||
|
||||
SendPacket(&data);
|
||||
}
|
||||
*/
|
||||
|
||||
void WorldSession::SendLfgJoinResult(LfgJoinResult result, LFGState state, partyForbidden const& lockedDungeons)
|
||||
{
|
||||
uint32 packetSize = 0;
|
||||
for (partyForbidden::const_iterator it = lockedDungeons.begin(); it != lockedDungeons.end(); ++it)
|
||||
packetSize += 12 + uint32(it->second.size()) * 8;
|
||||
|
||||
WorldPacket data(SMSG_LFG_JOIN_RESULT, packetSize);
|
||||
data << uint32(result);
|
||||
data << uint32(state);
|
||||
|
||||
if (!lockedDungeons.empty())
|
||||
{
|
||||
for (partyForbidden::const_iterator it = lockedDungeons.begin(); it != lockedDungeons.end(); ++it)
|
||||
{
|
||||
dungeonForbidden dungeonInfo = it->second;
|
||||
|
||||
data << uint64(it->first); // object guid of player
|
||||
data << uint32(dungeonInfo.size()); // amount of their locked dungeons
|
||||
|
||||
for (dungeonForbidden::iterator itr = dungeonInfo.begin(); itr != dungeonInfo.end(); ++itr)
|
||||
{
|
||||
data << uint32(itr->first); // dungeon entry
|
||||
data << uint32(itr->second); // reason for dungeon being forbidden/locked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
/*
|
||||
* new version hass been added below for dev21
|
||||
* delete this once the new one proves to work (chucky)
|
||||
void WorldSession::SendLfgUpdate(bool isGroup, LfgUpdateType updateType, uint32 id)
|
||||
{
|
||||
WorldPacket data(isGroup ? SMSG_LFG_UPDATE_PARTY : SMSG_LFG_UPDATE_PLAYER, 0);
|
||||
|
|
@ -276,3 +314,258 @@ void WorldSession::SendLfgUpdate(bool isGroup, LfgUpdateType updateType, uint32
|
|||
}
|
||||
SendPacket(&data);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The following functions were added for dev21, teken from Two
|
||||
* If tey prove to work, then delete/alter this comment (chucky)
|
||||
*/
|
||||
|
||||
void WorldSession::SendLfgUpdate(bool isGroup, LFGPlayerStatus status)
|
||||
{
|
||||
uint8 dungeonSize = uint8(status.dungeonList.size());
|
||||
|
||||
bool isQueued = false, joinLFG = false;
|
||||
|
||||
switch (status.updateType)
|
||||
{
|
||||
case LFG_UPDATE_JOIN:
|
||||
case LFG_UPDATE_ADDED_TO_QUEUE:
|
||||
isQueued = true;
|
||||
case LFG_UPDATE_PROPOSAL_BEGIN:
|
||||
if (isGroup)
|
||||
joinLFG = true;
|
||||
break;
|
||||
case LFG_UPDATE_STATUS:
|
||||
isQueued = (status.state == LFG_STATE_QUEUED);
|
||||
|
||||
if (isGroup)
|
||||
joinLFG = (status.state != LFG_STATE_ROLECHECK) && (status.state != LFG_STATE_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
WorldPacket data(isGroup ? SMSG_LFG_UPDATE_PARTY : SMSG_LFG_UPDATE_PLAYER);
|
||||
data << uint8(status.updateType);
|
||||
|
||||
data << uint8(dungeonSize > 0);
|
||||
|
||||
if (dungeonSize)
|
||||
{
|
||||
if (isGroup)
|
||||
data << uint8(joinLFG);
|
||||
data << uint8(isQueued);
|
||||
data << uint8(0);
|
||||
data << uint8(0);
|
||||
|
||||
if (isGroup)
|
||||
{
|
||||
for (uint32 i = 0; i < 3; ++i)
|
||||
data << uint8(0);
|
||||
}
|
||||
|
||||
data << uint8(dungeonSize);
|
||||
for (std::set<uint32>::iterator it = status.dungeonList.begin(); it != status.dungeonList.end(); ++it)
|
||||
data << uint32(*it);
|
||||
|
||||
data << status.comment;
|
||||
}
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgQueueStatus(LFGQueueStatus const& status)
|
||||
{
|
||||
WorldPacket data(SMSG_LFG_QUEUE_STATUS, 31);
|
||||
|
||||
data << uint32(status.dungeonID);
|
||||
data << int32(status.playerAvgWaitTime);
|
||||
data << int32(status.avgWaitTime);
|
||||
data << int32(status.tankAvgWaitTime);
|
||||
data << int32(status.healerAvgWaitTime);
|
||||
data << int32(status.dpsAvgWaitTime);
|
||||
data << uint8(status.neededTanks);
|
||||
data << uint8(status.neededHeals);
|
||||
data << uint8(status.neededDps);
|
||||
data << uint32(status.timeSpentInQueue);
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgRoleCheckUpdate(LFGRoleCheck const& roleCheck)
|
||||
{
|
||||
WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE);
|
||||
|
||||
data << uint32(roleCheck.state);
|
||||
data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING);
|
||||
|
||||
std::set<uint32> dungeons;
|
||||
if (roleCheck.randomDungeonID)
|
||||
dungeons.insert(roleCheck.randomDungeonID);
|
||||
else
|
||||
dungeons = roleCheck.dungeonList;
|
||||
|
||||
data << uint8(dungeons.size());
|
||||
if (!dungeons.empty())
|
||||
for (std::set<uint32>::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
|
||||
data << uint32(sLFGMgr.GetDungeonEntry(*it));
|
||||
|
||||
data << uint8(roleCheck.currentRoles.size());
|
||||
if (!roleCheck.currentRoles.empty())
|
||||
{
|
||||
ObjectGuid leaderGuid = ObjectGuid(roleCheck.leaderGuidRaw);
|
||||
uint8 leaderRoles = roleCheck.currentRoles.find(leaderGuid)->second;
|
||||
Player* pLeader = ObjectAccessor::FindPlayer(leaderGuid);
|
||||
|
||||
data << uint64(leaderGuid.GetRawValue());
|
||||
data << uint8(leaderRoles > 0);
|
||||
data << uint32(leaderRoles);
|
||||
data << uint8(pLeader->getLevel());
|
||||
|
||||
for (roleMap::const_iterator rItr = roleCheck.currentRoles.begin(); rItr != roleCheck.currentRoles.end(); ++rItr)
|
||||
{
|
||||
if (rItr->first == leaderGuid)
|
||||
continue; // exclude the leader
|
||||
|
||||
ObjectGuid plrGuid = rItr->first;
|
||||
|
||||
Player* pPlayer = ObjectAccessor::FindPlayer(plrGuid);
|
||||
|
||||
data << uint64(plrGuid.GetRawValue());
|
||||
data << uint8(rItr->second > 0);
|
||||
data << uint32(rItr->second);
|
||||
data << uint8(pPlayer->getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgRoleChosen(uint64 rawGuid, uint8 roles)
|
||||
{
|
||||
WorldPacket data(SMSG_ROLE_CHOSEN, 13);
|
||||
data << uint64(rawGuid);
|
||||
data << uint8(roles > 0);
|
||||
data << uint32(roles);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgProposalUpdate(LFGProposal const& proposal)
|
||||
{
|
||||
Player* pPlayer = GetPlayer();
|
||||
ObjectGuid plrGuid = pPlayer->GetObjectGuid();
|
||||
ObjectGuid plrGroupGuid = proposal.groups.find(plrGuid)->second;
|
||||
|
||||
uint32 dungeonEntry = sLFGMgr.GetDungeonEntry(proposal.dungeonID);
|
||||
bool showProposal = !proposal.isNew && proposal.groupRawGuid == plrGroupGuid.GetRawValue();
|
||||
|
||||
WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 15 + (9 * proposal.currentRoles.size()));
|
||||
|
||||
data << uint32(dungeonEntry); // Dungeon Entry
|
||||
data << uint8(proposal.state); // Proposal state
|
||||
data << uint32(proposal.id); // ID of proposal
|
||||
data << uint32(proposal.encounters); // Encounters done
|
||||
data << uint8(showProposal); // Show or hide proposal window [todo-this]
|
||||
data << uint8(proposal.currentRoles.size()); // Size of group
|
||||
|
||||
for (playerGroupMap::const_iterator it = proposal.groups.begin(); it != proposal.groups.end(); ++it)
|
||||
{
|
||||
ObjectGuid grpPlrGuid = it->first;
|
||||
uint8 grpPlrRole = proposal.currentRoles.find(grpPlrGuid)->second;
|
||||
LFGProposalAnswer grpPlrAnswer = proposal.answers.find(grpPlrGuid)->second;
|
||||
|
||||
data << uint32(grpPlrRole); // Player's role
|
||||
data << uint8(grpPlrGuid == plrGuid); // Is this player me?
|
||||
|
||||
if (it->second != 0)
|
||||
{
|
||||
data << uint8(it->second == ObjectGuid(proposal.groupRawGuid)); // Is player in the proposed group?
|
||||
data << uint8(it->second == plrGroupGuid); // Is player in the same group as myself?
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint8(0);
|
||||
data << uint8(0);
|
||||
}
|
||||
|
||||
data << uint8(grpPlrAnswer != LFG_ANSWER_PENDING); // Has the player selected an answer?
|
||||
data << uint8(grpPlrAnswer == LFG_ANSWER_AGREE); // Has the player agreed to do the dungeon?
|
||||
}
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgTeleportError(uint8 error)
|
||||
{
|
||||
DEBUG_LOG("SMSG_LFG_TELEPORT_DENIED");
|
||||
WorldPacket data(SMSG_LFG_TELEPORT_DENIED, 4);
|
||||
data << uint32(error);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgRewards(LFGRewards const& rewards)
|
||||
{
|
||||
DEBUG_LOG("SMSG_LFG_PLAYER_REWARD");
|
||||
|
||||
WorldPacket data(SMSG_LFG_PLAYER_REWARD, 42);
|
||||
data << uint32(rewards.randomDungeonEntry);
|
||||
data << uint32(rewards.groupDungeonEntry);
|
||||
data << uint8(rewards.hasDoneDaily);
|
||||
data << uint32(1);
|
||||
data << uint32(rewards.moneyReward);
|
||||
data << uint32(rewards.expReward);
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
if (rewards.itemID != 0)
|
||||
{
|
||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(rewards.itemID);
|
||||
if (pProto)
|
||||
{
|
||||
data << uint8(1);
|
||||
data << uint32(rewards.itemID);
|
||||
data << uint32(pProto->DisplayInfoID);
|
||||
data << uint32(rewards.itemAmount);
|
||||
}
|
||||
}
|
||||
else
|
||||
data << uint8(0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgBootUpdate(LFGBoot const& boot)
|
||||
{
|
||||
DEBUG_LOG("SMSG_LFG_BOOT_PLAYER");
|
||||
|
||||
ObjectGuid plrGuid = GetPlayer()->GetObjectGuid();
|
||||
LFGProposalAnswer plrAnswer = boot.answers.find(plrGuid)->second;
|
||||
|
||||
uint32 voteCount = 0, yayCount = 0;
|
||||
for (proposalAnswerMap::const_iterator it = boot.answers.begin(); it != boot.answers.end(); ++it)
|
||||
{
|
||||
if (it->second != LFG_ANSWER_PENDING)
|
||||
{
|
||||
++voteCount;
|
||||
if (it->second == LFG_ANSWER_AGREE)
|
||||
++yayCount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 timeLeft = uint8(((boot.startTime + LFG_TIME_BOOT) - time(NULL)) / 1000);
|
||||
|
||||
WorldPacket data(SMSG_LFG_BOOT_PLAYER, 27 + boot.reason.length());
|
||||
|
||||
data << uint8(boot.inProgress); // Is boot still ongoing?
|
||||
data << uint8(plrAnswer != LFG_ANSWER_PENDING); // Did this player vote yet?
|
||||
data << uint8(plrAnswer == LFG_ANSWER_AGREE); // Did this player agree to boot them?
|
||||
data << uint64(boot.playerVotedOn.GetRawValue()); // Potentially booted player's objectguid value
|
||||
data << uint32(voteCount); // Number of players who've voted so far
|
||||
data << uint32(yayCount); // Number of players who've voted against the plr so far
|
||||
data << uint32(timeLeft); // Time left in seconds
|
||||
data << uint32(REQUIRED_VOTES_FOR_BOOT); // Number of votes needed to win
|
||||
data << boot.reason.c_str(); // Reason given for booting
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
1958
src/game/WorldHandlers/LFGMgr.cpp
Normal file
1958
src/game/WorldHandlers/LFGMgr.cpp
Normal file
File diff suppressed because it is too large
Load diff
700
src/game/WorldHandlers/LFGMgr.h
Normal file
700
src/game/WorldHandlers/LFGMgr.h
Normal file
|
|
@ -0,0 +1,700 @@
|
|||
/**
|
||||
* MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
||||
*
|
||||
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MANGOS_LFGMGR_H
|
||||
#define __MANGOS_LFGMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "Group.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
class Object;
|
||||
class ObjectGuid;
|
||||
class Player;
|
||||
class Group;
|
||||
|
||||
struct LFGBoot;
|
||||
struct LFGGroupStatus;
|
||||
struct LFGPlayers;
|
||||
struct LFGPlayerStatus;
|
||||
struct LFGProposal;
|
||||
struct LFGRoleCheck;
|
||||
struct LFGWait;
|
||||
|
||||
// Begin Section: Enumerations
|
||||
|
||||
enum LFGFlags
|
||||
{
|
||||
LFG_FLAG_UNK1 = 0x1,
|
||||
LFG_FLAG_UNK2 = 0x2,
|
||||
LFG_FLAG_SEASONAL = 0x4,
|
||||
LFG_FLAG_UNK3 = 0x8
|
||||
};
|
||||
|
||||
/// Possible statuses to send after a request to join the dungeon finder
|
||||
enum LfgJoinResult
|
||||
{
|
||||
ERR_LFG_OK = 0x00,
|
||||
ERR_LFG_ROLE_CHECK_FAILED = 0x01,
|
||||
ERR_LFG_GROUP_FULL = 0x02,
|
||||
ERR_LFG_NO_LFG_OBJECT = 0x04,
|
||||
ERR_LFG_NO_SLOTS_PLAYER = 0x05,
|
||||
ERR_LFG_NO_SLOTS_PARTY = 0x06,
|
||||
ERR_LFG_MISMATCHED_SLOTS = 0x07,
|
||||
ERR_LFG_PARTY_PLAYERS_FROM_DIFFERENT_REALMS = 0x08,
|
||||
ERR_LFG_MEMBERS_NOT_PRESENT = 0x09,
|
||||
ERR_LFG_GET_INFO_TIMEOUT = 0x0A,
|
||||
ERR_LFG_INVALID_SLOT = 0x0B,
|
||||
ERR_LFG_DESERTER_PLAYER = 0x0C,
|
||||
ERR_LFG_DESERTER_PARTY = 0x0D,
|
||||
ERR_LFG_RANDOM_COOLDOWN_PLAYER = 0x0E,
|
||||
ERR_LFG_RANDOM_COOLDOWN_PARTY = 0x0F,
|
||||
ERR_LFG_TOO_MANY_MEMBERS = 0x10,
|
||||
ERR_LFG_CANT_USE_DUNGEONS = 0x11,
|
||||
ERR_LFG_ROLE_CHECK_FAILED2 = 0x12,
|
||||
};
|
||||
|
||||
enum LfgUpdateType
|
||||
{
|
||||
LFG_UPDATE_DEFAULT = 0,
|
||||
LFG_UPDATE_LEADER_LEAVE = 1,
|
||||
LFG_UPDATE_ROLECHECK_ABORTED = 4,
|
||||
LFG_UPDATE_JOIN = 5,
|
||||
LFG_UPDATE_ROLECHECK_FAILED = 6,
|
||||
LFG_UPDATE_LEAVE = 7,
|
||||
LFG_UPDATE_PROPOSAL_FAILED = 8,
|
||||
LFG_UPDATE_PROPOSAL_DECLINED = 9,
|
||||
LFG_UPDATE_GROUP_FOUND = 10,
|
||||
LFG_UPDATE_ADDED_TO_QUEUE = 12,
|
||||
LFG_UPDATE_PROPOSAL_BEGIN = 13,
|
||||
LFG_UPDATE_STATUS = 14,
|
||||
LFG_UPDATE_GROUP_MEMBER_OFFLINE = 15,
|
||||
LFG_UPDATE_GROUP_DISBAND = 16,
|
||||
};
|
||||
|
||||
enum LfgType
|
||||
{
|
||||
LFG_TYPE_NONE = 0,
|
||||
LFG_TYPE_DUNGEON = 1,
|
||||
LFG_TYPE_RAID = 2,
|
||||
LFG_TYPE_QUEST = 3,
|
||||
LFG_TYPE_ZONE = 4,
|
||||
LFG_TYPE_HEROIC_DUNGEON = 5,
|
||||
LFG_TYPE_RANDOM_DUNGEON = 6
|
||||
};
|
||||
|
||||
/// Reasons a player cannot enter a dungeon
|
||||
enum LFGForbiddenTypes
|
||||
{
|
||||
LFG_FORBIDDEN_EXPANSION = 1,
|
||||
LFG_FORBIDDEN_LOW_LEVEL = 2,
|
||||
LFG_FORBIDDEN_HIGH_LEVEL = 3,
|
||||
LFG_FORBIDDEN_LOW_GEAR_SCORE = 4,
|
||||
LFG_FORBIDDEN_HIGH_GEAR_SCORE = 5,
|
||||
LFG_FORBIDDEN_RAID = 6,
|
||||
LFG_FORBIDDEN_ATTUNEMENT_LOW_LEVEL = 1001,
|
||||
LFG_FORBIDDEN_ATTUNEMENT_HIGH_LEVEL = 1002,
|
||||
LFG_FORBIDDEN_QUEST_INCOMPLETE = 1022,
|
||||
LFG_FORBIDDEN_MISSING_ITEM = 1025,
|
||||
LFG_FORBIDDEN_NOT_IN_SEASON = 1031,
|
||||
LFG_FORBIDDEN_MISSING_ACHIEVEMENT = 1034
|
||||
};
|
||||
|
||||
/// Spells that affect the mechanisms of the dungeon finder
|
||||
enum LFGSpells
|
||||
{
|
||||
LFG_DESERTER_SPELL = 71041,
|
||||
LFG_COOLDOWN_SPELL = 71328,
|
||||
};
|
||||
|
||||
enum LFGTimes
|
||||
{
|
||||
LFG_TIME_ROLECHECK = 45*IN_MILLISECONDS,
|
||||
LFG_TIME_BOOT = 120,
|
||||
LFG_TIME_PROPOSAL = 45,
|
||||
};
|
||||
|
||||
/// Proposal answers
|
||||
enum LFGProposalAnswer
|
||||
{
|
||||
LFG_ANSWER_PENDING = -1,
|
||||
LFG_ANSWER_DENY = 0,
|
||||
LFG_ANSWER_AGREE = 1
|
||||
};
|
||||
|
||||
/// Player states in the lfg system
|
||||
enum LFGState
|
||||
{
|
||||
LFG_STATE_NONE,
|
||||
LFG_STATE_ROLECHECK,
|
||||
LFG_STATE_QUEUED,
|
||||
LFG_STATE_PROPOSAL,
|
||||
LFG_STATE_BOOT,
|
||||
LFG_STATE_IN_DUNGEON,
|
||||
LFG_STATE_FINISHED_DUNGEON,
|
||||
LFG_STATE_RAIDBROWSER
|
||||
};
|
||||
|
||||
/// Proposal states
|
||||
enum LFGProposalState
|
||||
{
|
||||
LFG_PROPOSAL_INITIATING = 0,
|
||||
LFG_PROPOSAL_FAILED = 1,
|
||||
LFG_PROPOSAL_SUCCESS = 2
|
||||
};
|
||||
|
||||
/// Role check states
|
||||
enum LFGRoleCheckState
|
||||
{
|
||||
LFG_ROLECHECK_DEFAULT = 0, // Internal use = Not initialized.
|
||||
LFG_ROLECHECK_FINISHED = 1, // Role check finished
|
||||
LFG_ROLECHECK_INITIALITING = 2, // Role check begins
|
||||
LFG_ROLECHECK_MISSING_ROLE = 3, // Someone hasn't selected a role after 2 mins
|
||||
LFG_ROLECHECK_WRONG_ROLES = 4, // Can't form a group with the role selection
|
||||
LFG_ROLECHECK_ABORTED = 5, // Someone left the group
|
||||
LFG_ROLECHECK_NO_ROLE = 6 // Someone didn't select a role
|
||||
};
|
||||
|
||||
/// Role types
|
||||
enum LFGRoles
|
||||
{
|
||||
PLAYER_ROLE_NONE = 0x00,
|
||||
PLAYER_ROLE_LEADER = 0x01,
|
||||
PLAYER_ROLE_TANK = 0x02,
|
||||
PLAYER_ROLE_HEALER = 0x04,
|
||||
PLAYER_ROLE_DAMAGE = 0x08
|
||||
};
|
||||
|
||||
/// Role amounts
|
||||
enum LFGRoleCount
|
||||
{
|
||||
NORMAL_TANK_OR_HEALER_COUNT = 1, // Tanks / Heals
|
||||
NORMAL_DAMAGE_COUNT = 3, // DPS
|
||||
NORMAL_TOTAL_ROLE_COUNT = 5 // Amount of players total per normal dungeon
|
||||
};
|
||||
|
||||
/// Teleport errors
|
||||
enum LFGTeleportError
|
||||
{
|
||||
// 7 = "You can't do that right now" | 5 = No client reaction
|
||||
LFG_TELEPORTERROR_OK = 0,
|
||||
LFG_TELEPORTERROR_PLAYER_DEAD = 1,
|
||||
LFG_TELEPORTERROR_FALLING = 2,
|
||||
LFG_TELEPORTERROR_IN_VEHICLE = 3,
|
||||
LFG_TELEPORTERROR_FATIGUE = 4,
|
||||
LFG_TELEPORTERROR_INVALID_LOCATION = 6,
|
||||
LFG_TELEPORTERROR_CHARMING = 8
|
||||
};
|
||||
|
||||
enum DungeonTypes
|
||||
{
|
||||
DUNGEON_CLASSIC = 0,
|
||||
DUNGEON_TBC = 1,
|
||||
DUNGEON_TBC_HEROIC = 2,
|
||||
DUNGEON_WOTLK = 3,
|
||||
DUNGEON_WOTLK_HEROIC = 4,
|
||||
DUNGEON_UNKNOWN
|
||||
};
|
||||
|
||||
// End Section: Enumerations
|
||||
|
||||
// Begin Section: Constants & Definitions
|
||||
|
||||
/// Heroic dungeon rewards in WoTLK after already doing a dungeon
|
||||
const uint32 WOTLK_SPECIAL_HEROIC_ITEM = 47241;
|
||||
const uint32 WOTLK_SPECIAL_HEROIC_AMNT = 2;
|
||||
|
||||
/// Default average queue time (in case we don't have data to base calculations on)
|
||||
const int32 QUEUE_DEFAULT_TIME = 15*MINUTE; // 15 minutes [system is measured in seconds]
|
||||
|
||||
/// Amount of votes needed to kick a player out of a group
|
||||
const int32 REQUIRED_VOTES_FOR_BOOT = 3;
|
||||
|
||||
typedef std::set<uint32> dailyEntries; // for players who did one of X type instance per day
|
||||
typedef std::set<ObjectGuid> queueSet; // List of players / groups in the queue
|
||||
typedef std::set<ObjectGuid> groupSet; // List of groups doing a dungeon via the finder
|
||||
|
||||
typedef UNORDERED_MAP<uint32, uint32> dungeonEntries; // ID, Entry
|
||||
typedef UNORDERED_MAP<uint32, uint32> dungeonForbidden; // Entry, LFGForbiddenTypes
|
||||
typedef UNORDERED_MAP<uint32, LFGProposal> proposalMap; // Proposal ID, info on a proposal
|
||||
typedef UNORDERED_MAP<uint32, LFGWait> waitTimeMap; // DungeonID, wait info
|
||||
typedef UNORDERED_MAP<ObjectGuid, dungeonForbidden> partyForbidden; // ObjectGuid of player, map of locked dungeons
|
||||
typedef UNORDERED_MAP<ObjectGuid, uint8> roleMap; // ObjectGuid of player, role(s) selected
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGRoleCheck> roleCheckMap; // ObjectGuid of group, role information
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGPlayerStatus> playerStatusMap; // ObjectGuid of player, info on specific players only
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGPlayers> playerData; // ObjectGuid of plr/group, info on specific player or group. TODO: rename to queueData
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGProposalAnswer> proposalAnswerMap; // ObjectGuid of player, answer to proposal
|
||||
typedef UNORDERED_MAP<ObjectGuid, ObjectGuid> playerGroupMap; // ObjectGuid of player, ObjectGuid of group
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGGroupStatus> groupStatusMap; // ObjectGuid of group, group status structure
|
||||
typedef UNORDERED_MAP<ObjectGuid, LFGBoot> bootStatusMap; // ObjectGuid of group, boot vote status
|
||||
|
||||
// End Section: Constants & Definitions
|
||||
|
||||
// Begin Section: Structures
|
||||
|
||||
/// Item rewards taken from DungeonFinderItems in ObjectMgr, parsed by dbc values
|
||||
struct ItemRewards
|
||||
{
|
||||
uint32 itemId;
|
||||
uint32 itemAmount;
|
||||
|
||||
ItemRewards() : itemId(0), itemAmount(0) {}
|
||||
ItemRewards(uint32 ItemId, uint32 ItemAmount) : itemId(ItemId), itemAmount(ItemAmount) {}
|
||||
};
|
||||
|
||||
/// Information the dungeon finder needs about each player (or group)
|
||||
struct LFGPlayers //TODO: rename to LFGQueueData
|
||||
{
|
||||
LFGState currentState; // where the player is at with the dungeon finder
|
||||
std::set<uint32> dungeonList; // The dungeons this player or group are queued for (ID, not entry)
|
||||
roleMap currentRoles; // tank, dps, healer, etc..
|
||||
std::string comments;
|
||||
bool isGroup;
|
||||
|
||||
time_t joinedTime;
|
||||
uint8 neededTanks;
|
||||
uint8 neededHealers;
|
||||
uint8 neededDps;
|
||||
|
||||
LFGPlayers() : currentState(LFG_STATE_NONE), currentRoles(0), isGroup(false) {}
|
||||
LFGPlayers(LFGState state, std::set<uint32> dungeonSelection, roleMap CurrentRoles, std::string comment, bool IsGroup, time_t JoinedTime,
|
||||
uint8 NeededTanks, uint8 NeededHealers, uint8 NeededDps) : currentState(state), dungeonList(dungeonSelection),
|
||||
currentRoles(CurrentRoles), comments(comment), isGroup(IsGroup), joinedTime(JoinedTime), neededTanks(NeededTanks),
|
||||
neededHealers(NeededHealers), neededDps(NeededDps) {}
|
||||
};
|
||||
|
||||
struct LFGRoleCheck
|
||||
{
|
||||
LFGRoleCheckState state; // current status of the role check
|
||||
roleMap currentRoles; // map of players to roles
|
||||
std::set<uint32> dungeonList; // The dungeons this player or group are queued for
|
||||
uint32 randomDungeonID; // The random dungeon ID
|
||||
uint64 leaderGuidRaw; // ObjectGuid(raw) of leader
|
||||
time_t waitForRoleTime; // How long we'll wait for the players to confirm their roles
|
||||
};
|
||||
|
||||
struct LFGWait
|
||||
{
|
||||
int32 time; // current wait time for x (in seconds, so (time_t x / IN_MILLISECONDS)
|
||||
int32 previousTime; // how long it took for the last person to go from queue to instance
|
||||
uint32 playerCount; // amount of players in x queue for calculations [not sure if needed when finished implementing system]
|
||||
bool doAverage; // tells the lfgmgr during a world update whether or not to recalculate waiting time
|
||||
|
||||
LFGWait() : time(-1), previousTime(-1), playerCount(0), doAverage(false) {}
|
||||
LFGWait(int32 currentTime, int32 lastTime, uint32 currentPlayerCount, bool shouldRecalculate)
|
||||
: time(currentTime), previousTime(lastTime), playerCount(currentPlayerCount), doAverage(shouldRecalculate) {}
|
||||
};
|
||||
|
||||
/// For SMSG_LFG_QUEUE_STATUS
|
||||
struct LFGQueueStatus
|
||||
{
|
||||
uint32 dungeonID; // queue info for x dungeon
|
||||
int32 playerAvgWaitTime; // average wait time for the current player
|
||||
int32 avgWaitTime; // average wait time for the dungeon
|
||||
int32 tankAvgWaitTime; // average wait time for the tank(s)
|
||||
int32 healerAvgWaitTime; // average wait time for the healer(s)
|
||||
int32 dpsAvgWaitTime; // average wait time for the dps'
|
||||
uint8 neededTanks; // amount of tanks needed
|
||||
uint8 neededHeals; // amount of healers needed
|
||||
uint8 neededDps; // amount of dps needed
|
||||
uint32 timeSpentInQueue; // time already spent in the queue
|
||||
};
|
||||
|
||||
/// For CMSG_LFG_GET_STATUS, SMSG_LFG_UPDATE_PARTY, and SMSG_LFG_UPDATE_PLAYER
|
||||
struct LFGPlayerStatus
|
||||
{
|
||||
LFGState state;
|
||||
LfgUpdateType updateType;
|
||||
std::set<uint32> dungeonList;
|
||||
std::string comment;
|
||||
|
||||
LFGPlayerStatus() { }
|
||||
LFGPlayerStatus(LFGState State, LfgUpdateType UpdateType, std::set<uint32> DungeonList, std::string Comment)
|
||||
: state(State), updateType(UpdateType), dungeonList(DungeonList), comment(Comment) { }
|
||||
};
|
||||
|
||||
/// Information on a group currently in a dungeon
|
||||
struct LFGGroupStatus //todo: check for this in joinlfg function, not lfgplayers struct
|
||||
{
|
||||
LFGState state; // State of the group
|
||||
uint32 dungeonID; // ID of the dungeon the group should be in
|
||||
roleMap playerRoles; // Container holding each player's objectguid and their roles
|
||||
ObjectGuid leaderGuid; // The group leader's object guid
|
||||
|
||||
LFGGroupStatus() { }
|
||||
LFGGroupStatus(LFGState State, uint32 DungeonID, roleMap PlayerRoles, ObjectGuid LeaderGuid)
|
||||
: state(State), dungeonID(DungeonID), playerRoles(PlayerRoles), leaderGuid(LeaderGuid) { }
|
||||
};
|
||||
|
||||
/// For SMSG_LFG_PROPOSAL_UPDATE
|
||||
struct LFGProposal
|
||||
{
|
||||
uint32 id; // proposal id
|
||||
uint32 dungeonID; // dungeon id
|
||||
LFGProposalState state; // proposal state
|
||||
uint32 encounters; // encounters done
|
||||
uint64 groupRawGuid; // group raw guid value
|
||||
uint64 groupLeaderGuid; // group leader's guid
|
||||
bool isNew; // is new or old group
|
||||
roleMap currentRoles; // group player's roles
|
||||
proposalAnswerMap answers; // answers to a proposal
|
||||
playerGroupMap groups; // data on which groups players belong/belonged to
|
||||
time_t joinedQueue; // time from when the players joined the queue
|
||||
};
|
||||
|
||||
// For SMSG_LFG_PLAYER_REWARD
|
||||
struct LFGRewards
|
||||
{
|
||||
uint32 randomDungeonEntry; // Entry of the random dungeon done (0 if not random)
|
||||
uint32 groupDungeonEntry; // Entry of the dungeon done by your group
|
||||
bool hasDoneDaily; // First dungeon of the day?
|
||||
uint32 moneyReward; // Amount of money rewarded
|
||||
uint32 expReward; // Amount of experience rewarded
|
||||
uint32 itemID; // ID of item reward
|
||||
uint32 itemAmount; // How many of x item is rewarded
|
||||
|
||||
LFGRewards() { }
|
||||
LFGRewards(uint32 RandomDungeonEntry, uint32 GroupDungeonEntry, bool HasDoneDaily,
|
||||
uint32 MoneyReward, uint32 ExpReward, uint32 ItemID, uint32 ItemAmount) :
|
||||
randomDungeonEntry(RandomDungeonEntry), groupDungeonEntry(GroupDungeonEntry),
|
||||
hasDoneDaily(HasDoneDaily), moneyReward(MoneyReward), expReward(ExpReward),
|
||||
itemID(ItemID), itemAmount(ItemAmount) { }
|
||||
};
|
||||
|
||||
// For SMSG_LFG_BOOT_PLAYER
|
||||
struct LFGBoot
|
||||
{
|
||||
bool inProgress; // Is the boot vote still occurring?
|
||||
ObjectGuid playerVotedOn; // ObjectGuid of the player being voted on
|
||||
std::string reason; // Reason stated for the vote
|
||||
proposalAnswerMap answers; // Player's votes
|
||||
time_t startTime; // When the vote started
|
||||
|
||||
LFGBoot() { }
|
||||
LFGBoot(bool InProgress, ObjectGuid PlayerVotedOn, std::string Reason, proposalAnswerMap Answers, time_t StartTime)
|
||||
: inProgress(InProgress), playerVotedOn(PlayerVotedOn), reason(Reason), answers(Answers), startTime(StartTime) { }
|
||||
};
|
||||
|
||||
// End Section: Structures
|
||||
|
||||
class LFGMgr
|
||||
{
|
||||
public:
|
||||
LFGMgr();
|
||||
~LFGMgr();
|
||||
|
||||
/// Update queue information and such
|
||||
void Update();
|
||||
|
||||
/**
|
||||
* @brief Attempt to join the dungeon finder queue, as long as the player(s)
|
||||
* fit the criteria.
|
||||
*
|
||||
* @param roles Roles selected in lfg window
|
||||
* @param dungeons List of dungeon(s) selected
|
||||
* @param comments Comments made by the player
|
||||
* @param plr Pointer to the player sending the packet
|
||||
*/
|
||||
void JoinLFG(uint32 roles, std::set<uint32> dungeons, std::string comments, Player* plr);
|
||||
|
||||
/**
|
||||
* @brief Leave the lfg/dungeon finder system.
|
||||
*
|
||||
* @param plr The pointer to the player sending the request
|
||||
* @param isGroup Whether or not they are the leader of a group / in a group
|
||||
*/
|
||||
void LeaveLFG(Player* plr, bool isGroup);
|
||||
|
||||
/**
|
||||
* @brief Go through a number of checks to see if the player/group can join
|
||||
* the LFG queue
|
||||
*
|
||||
* @param plr The pointer to the player
|
||||
*/
|
||||
LfgJoinResult GetJoinResult(Player* plr);
|
||||
|
||||
/**
|
||||
* @brief Fetch the playerstatus struct of a player on request, if existant
|
||||
*
|
||||
* @param guid the player's objectguid
|
||||
*/
|
||||
LFGPlayerStatus GetPlayerStatus(ObjectGuid guid);
|
||||
|
||||
/**
|
||||
* @brief Set the player's comment string
|
||||
*
|
||||
* @param guid The player's objectguid
|
||||
* @param comment Their comments
|
||||
*/
|
||||
void SetPlayerComment(ObjectGuid guid, std::string comment);
|
||||
|
||||
/**
|
||||
* @brief Set the player's LFG state
|
||||
*
|
||||
* @param guid The player's objectguid
|
||||
* @param state the LFGState value
|
||||
*/
|
||||
void SetPlayerState(ObjectGuid guid, LFGState state);
|
||||
|
||||
/**
|
||||
* @brief Set the player's LFG update type
|
||||
*
|
||||
* @param guid The player's objectguid
|
||||
* @param updateType The LfgUpdateType value
|
||||
*/
|
||||
void SetPlayerUpdateType(ObjectGuid guid, LfgUpdateType updateType);
|
||||
|
||||
/**
|
||||
* @brief Used to fetch the item rewards of a dungeon from the database
|
||||
*
|
||||
* @param dungeonId the dungeon ID used in the DBCs
|
||||
* @param type the type of dungeon
|
||||
*/
|
||||
ItemRewards GetDungeonItemRewards(uint32 dungeonId, DungeonTypes type);
|
||||
|
||||
/**
|
||||
* @brief Used to determine the type of dungeon for ease of use.
|
||||
*
|
||||
* @param dungeonId the dungeon ID used in the DBCs
|
||||
*/
|
||||
DungeonTypes GetDungeonType(uint32 dungeonId);
|
||||
|
||||
/**
|
||||
* @brief Used to record the first time a player has entered x type of dungeon in the day.
|
||||
*
|
||||
* @param guidLow the player's guidLow
|
||||
* @param dungeon the specific type/expansion of dungeon
|
||||
*/
|
||||
void RegisterPlayerDaily(uint32 guidLow, DungeonTypes dungeon);
|
||||
|
||||
/**
|
||||
* @brief Used to find whether or not the player has done x type of dungeon today.
|
||||
*
|
||||
* @param guidLow the player's guidLow
|
||||
* @param dungeon the specific type/expansion of dungeon
|
||||
*/
|
||||
bool HasPlayerDoneDaily(uint32 guidLow, DungeonTypes dungeon);
|
||||
|
||||
/// Reset accounts of players completing a/any dungeon for the day for new rewards
|
||||
void ResetDailyRecords();
|
||||
|
||||
/**
|
||||
* @brief Find out whether or not a special dungeon is available for that season
|
||||
*
|
||||
* @param dungeonId the ID of the dungeon in question
|
||||
*/
|
||||
bool IsSeasonActive(uint32 dungeonId);
|
||||
|
||||
/**
|
||||
* @brief Find the random dungeons applicable for a player
|
||||
*
|
||||
* @param level The level of said player
|
||||
* @param expansion The player's expansion
|
||||
*/
|
||||
dungeonEntries FindRandomDungeonsForPlayer(uint32 level, uint8 expansion);
|
||||
|
||||
/**
|
||||
* @brief Find the random dungeons not applicable for a player
|
||||
*
|
||||
* @param level The level of said player
|
||||
* @param expansion The player's expansion
|
||||
*/
|
||||
dungeonForbidden FindRandomDungeonsNotForPlayer(Player* plr);
|
||||
|
||||
/// Given the ID of a dungeon, spit out its entry
|
||||
uint32 GetDungeonEntry(uint32 ID);
|
||||
|
||||
/// Teleports a player out of a dungeon (called by CMSG_LFG_TELEPORT)
|
||||
void TeleportPlayer(Player* pPlayer, bool out);
|
||||
|
||||
/// Queue Functions Below
|
||||
|
||||
/**
|
||||
* Find the player's or group's information and update the system with
|
||||
* the amount of each role they need to find.
|
||||
*
|
||||
* @param guid The guid assigned to the structure
|
||||
* @param information The LFGPlayers structure containing their information
|
||||
*/
|
||||
void UpdateNeededRoles(ObjectGuid guid, LFGPlayers* information);
|
||||
|
||||
/**
|
||||
* @brief Add the player or group to the Dungeon Finder queue
|
||||
*
|
||||
* @param guid the player/group's ObjectGuid
|
||||
*/
|
||||
void AddToQueue(ObjectGuid guid);
|
||||
|
||||
/**
|
||||
* @brief Remove the player or group from the Dungeon Finder queue
|
||||
*
|
||||
* @param guid the player/group's ObjectGuid
|
||||
*/
|
||||
void RemoveFromQueue(ObjectGuid guid);
|
||||
|
||||
/// Search the queue for compatible matches
|
||||
void FindQueueMatches();
|
||||
|
||||
/**
|
||||
* @brief Search the queue for matches based off of one's guid
|
||||
*
|
||||
* @param guid The player or group's guid
|
||||
*/
|
||||
void FindSpecificQueueMatches(ObjectGuid guid);
|
||||
|
||||
/// Send a periodic status update for queued players
|
||||
void SendQueueStatus();
|
||||
|
||||
/// Role-Related Functions
|
||||
|
||||
/**
|
||||
* @brief Set and/or confirm roles for a group.
|
||||
*
|
||||
* @param pPlayer The pointer to the player issuing the request
|
||||
* @param pGroup The pointer to that player's group
|
||||
* @param roles The group leader's role(s)
|
||||
*/
|
||||
void PerformRoleCheck(Player* pPlayer, Group* pGroup, uint8 roles);
|
||||
|
||||
/// Make sure role selections are okay
|
||||
bool ValidateGroupRoles(roleMap groupMap);
|
||||
|
||||
/// Proposal-Related Functions
|
||||
|
||||
void ProposalUpdate(uint32 proposalID, ObjectGuid plrGuid, bool accepted);
|
||||
|
||||
/// Handles reward hooks -- called by achievement manager
|
||||
void HandleBossKilled(Player* pPlayer);
|
||||
|
||||
/// Group kick hook
|
||||
void AttemptToKickPlayer(Group* pGroup, ObjectGuid guid, ObjectGuid kicker, std::string reason);
|
||||
|
||||
// Called when a player votes yes or no on a boot vote
|
||||
void CastVote(Player* pPlayer, bool vote);
|
||||
|
||||
protected:
|
||||
bool IsSeasonal(uint32 dbcFlags) { return ((dbcFlags & LFG_FLAG_SEASONAL) != 0) ? true : false; }
|
||||
|
||||
/// Check if player/party is already in the system, return that data
|
||||
LFGPlayers* GetPlayerOrPartyData(ObjectGuid guid);
|
||||
|
||||
/// Get a proposal structure given its id
|
||||
LFGProposal* GetProposalData(uint32 proposalID);
|
||||
|
||||
/// Get information on a group currently in a dungeon
|
||||
LFGGroupStatus* GetGroupStatus(ObjectGuid guid);
|
||||
|
||||
/// Add the player to their respective waiting map for their dungeon
|
||||
void AddToWaitMap(uint8 role, std::set<uint32> dungeons);
|
||||
|
||||
/// Checks if any players have the leader flag for their roles
|
||||
bool HasLeaderFlag(roleMap const& roles);
|
||||
|
||||
/// Compares two groups/players to see if their role combinations are compatible
|
||||
bool RoleMapsAreCompatible(LFGPlayers* groupOne, LFGPlayers* groupTwo);
|
||||
|
||||
/// Checks whether or not two combinations of players/groups are on the same team (alliance/horde)
|
||||
bool MatchesAreOfSameTeam(LFGPlayers* groupOne, LFGPlayers* groupTwo);
|
||||
|
||||
/// Are the players in a proposal already grouped up?
|
||||
bool IsProposalSameGroup(LFGProposal const& proposal);
|
||||
|
||||
/// Update a proposal after a player refused to join
|
||||
void ProposalDeclined(ObjectGuid guid, LFGProposal* proposal);
|
||||
|
||||
/// Updates a wait map with the amount of time it took the last player to join
|
||||
void UpdateWaitMap(LFGRoles role, uint32 dungeonID, time_t waitTime);
|
||||
|
||||
/// Creates a group so they can enter a dungeon together
|
||||
void CreateDungeonGroup(LFGProposal* proposal);
|
||||
|
||||
/// Sends a group to the dungeon assigned to them
|
||||
void TeleportToDungeon(uint32 dungeonID, Group* pGroup);
|
||||
|
||||
/**
|
||||
* @brief Merges two players/groups/etc into one for dungeon assignment.
|
||||
*
|
||||
* @param guidOne The guid assigned to the first group in m_playerData
|
||||
* @param guidTwo The guid assigned to the second group in m_playerData
|
||||
* @param compatibleDungeons The dungeons that both players or groups agreed to doing
|
||||
*/
|
||||
void MergeGroups(ObjectGuid guidOne, ObjectGuid guidTwo, std::set<uint32> compatibleDungeons);
|
||||
|
||||
/// Send a proposal to each member of a group
|
||||
void SendDungeonProposal(LFGPlayers* lfgGroup);
|
||||
|
||||
/// Tell a group member that someone else just confirmed their role
|
||||
void SendRoleChosen(ObjectGuid plrGuid, ObjectGuid confirmedGuid, uint8 roles);
|
||||
|
||||
/// Send SMSG_LFG_ROLE_CHECK_UPDATE to a specific player
|
||||
void SendRoleCheckUpdate(ObjectGuid plrGuid, LFGRoleCheck const& roleCheck);
|
||||
|
||||
/// Send SMSG_LFG_UPDATE_PARTY or SMSG_LFG_UPDATE_PLAYER
|
||||
void SendLfgUpdate(ObjectGuid plrGuid, LFGPlayerStatus status, bool isGroup);
|
||||
|
||||
/// Send SMSG_LFG_JOIN_RESULT
|
||||
void SendLfgJoinResult(ObjectGuid plrGuid, LfgJoinResult result, LFGState state, partyForbidden const& lockedDungeons);
|
||||
|
||||
/// Get rid of expired role checks
|
||||
void RemoveOldRoleChecks();
|
||||
|
||||
private:
|
||||
/// Daily occurences of a player doing X type dungeon
|
||||
dailyEntries m_dailyAny;
|
||||
dailyEntries m_dailyTBCHeroic;
|
||||
dailyEntries m_dailyLKNormal;
|
||||
dailyEntries m_dailyLKHeroic;
|
||||
|
||||
/// General info related to joining / leaving the dungeon finder
|
||||
playerData m_playerData;
|
||||
queueSet m_queueSet;
|
||||
|
||||
/// Dungeon Finder Status for players
|
||||
playerStatusMap m_playerStatusMap;
|
||||
|
||||
groupSet m_groupSet;
|
||||
groupStatusMap m_groupStatusMap;
|
||||
|
||||
/// Role check information
|
||||
roleCheckMap m_roleCheckMap;
|
||||
|
||||
/// Boot vote information
|
||||
bootStatusMap m_bootStatusMap;
|
||||
|
||||
/// Wait times for the queue
|
||||
waitTimeMap m_tankWaitTime;
|
||||
waitTimeMap m_healerWaitTime;
|
||||
waitTimeMap m_dpsWaitTime;
|
||||
waitTimeMap m_avgWaitTime;
|
||||
|
||||
/// Proposal information
|
||||
uint32 m_proposalId;
|
||||
proposalMap m_proposalMap;
|
||||
};
|
||||
|
||||
#define sLFGMgr MaNGOS::Singleton<LFGMgr>::Instance()
|
||||
|
||||
#endif
|
||||
|
|
@ -35,7 +35,6 @@
|
|||
#include "Opcodes.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Weather.h"
|
||||
#include "Player.h"
|
||||
#include "SkillExtraItems.h"
|
||||
#include "SkillDiscovery.h"
|
||||
|
|
@ -76,6 +75,8 @@
|
|||
#include "CreatureLinkingMgr.h"
|
||||
#include "Calendar.h"
|
||||
#include "PhaseMgr.h"
|
||||
#include "Weather.h"
|
||||
#include "LFGMgr.h"
|
||||
#ifdef ENABLE_ELUNA
|
||||
#include "LuaEngine.h"
|
||||
#endif /*ENABLE_ELUNA*/
|
||||
|
|
@ -2271,6 +2272,36 @@ void World::InitCurrencyResetTime()
|
|||
delete result;
|
||||
}
|
||||
|
||||
void World::InitRandomBGResetTime()
|
||||
{
|
||||
QueryResult * result = CharacterDatabase.Query("SELECT NextRandomBGResetTime FROM saved_variables");
|
||||
if (!result)
|
||||
m_NextRandomBGReset = time_t(time(NULL)); // game time not yet init
|
||||
else
|
||||
m_NextRandomBGReset = time_t((*result)[0].GetUInt64());
|
||||
|
||||
// generate time by config
|
||||
time_t curTime = time(NULL);
|
||||
tm localTm = *localtime(&curTime);
|
||||
localTm.tm_hour = getConfig(CONFIG_UINT32_RANDOM_BG_RESET_HOUR);
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
|
||||
// current day reset time
|
||||
time_t nextDayResetTime = mktime(&localTm);
|
||||
|
||||
// next reset time before current moment
|
||||
if (curTime >= nextDayResetTime)
|
||||
nextDayResetTime += DAY;
|
||||
|
||||
// normalize reset time
|
||||
m_NextRandomBGReset = m_NextRandomBGReset < curTime ? nextDayResetTime - DAY : nextDayResetTime;
|
||||
if (!result)
|
||||
CharacterDatabase.PExecute("INSERT INTO saved_variables (NextRandomBGResetTime) VALUES ('" UI64FMTD "')", uint64(m_NextRandomBGReset));
|
||||
else
|
||||
delete result;
|
||||
}
|
||||
|
||||
void World::ResetDailyQuests()
|
||||
{
|
||||
DETAIL_LOG("Daily quests reset for all characters.");
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ enum eConfigUInt32Values
|
|||
CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE,
|
||||
CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT,
|
||||
CONFIG_UINT32_MIN_LEVEL_FOR_RAID,
|
||||
CONFIG_UINT32_RANDOM_BG_RESET_HOUR,
|
||||
CONFIG_UINT32_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
|
@ -640,6 +641,7 @@ class World
|
|||
|
||||
void InitCurrencyResetTime();
|
||||
void InitDailyQuestResetTime();
|
||||
void InitRandomBGResetTime();
|
||||
void InitWeeklyQuestResetTime();
|
||||
void SetMonthlyQuestResetTime(bool initialize = true);
|
||||
void ResetCurrencyWeekCounts();
|
||||
|
|
@ -722,12 +724,10 @@ class World
|
|||
// scheduled reset times
|
||||
time_t m_NextCurrencyReset;
|
||||
time_t m_NextDailyQuestReset;
|
||||
time_t m_NextRandomBGReset;
|
||||
time_t m_NextWeeklyQuestReset;
|
||||
time_t m_NextMonthlyQuestReset;
|
||||
|
||||
// next daily quests reset time
|
||||
time_t m_NextRandomBGReset;
|
||||
|
||||
// Player Queue
|
||||
Queue m_QueuedSessions;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue