Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- src/game/Channel.cpp | 3 +-
- src/game/CharacterHandler.cpp | 2 +-
- src/game/DBCStores.cpp | 4 +-
- src/game/DBCStores.h | 1 +
- src/game/DBCStructure.h | 23 +
- src/game/DBCfmt.h | 1 +
- src/game/Group.cpp | 29 +-
- src/game/Group.h | 3 +
- src/game/GroupHandler.cpp | 13 +
- src/game/LFG.h | 54 ++
- src/game/LFGHandler.cpp | 539 +++++++--------------
- src/game/LFGMgr.cpp | 1069 ++++++++++++++++++++++++++++++++++++++++
- src/game/LFGMgr.h | 261 ++++++++++
- src/game/Makefile.am | 3 +
- src/game/ObjectGuid.cpp | 2 +
- src/game/ObjectGuid.h | 4 +
- src/game/ObjectMgr.cpp | 2 +
- src/game/Opcodes.cpp | 22 +-
- src/game/Player.h | 69 +---
- src/game/World.cpp | 7 +
- src/game/WorldSession.cpp | 6 +
- src/game/WorldSession.h | 26 +-
- win/VC100/game.vcxproj | 3 +
- win/VC100/game.vcxproj.filters | 9 +
- win/VC80/game.vcproj | 12 +
- win/VC90/game.vcproj | 12 +
- 26 files changed, 1703 insertions(+), 476 deletions(-)
- create mode 100644 src/game/LFG.h
- create mode 100644 src/game/LFGMgr.cpp
- create mode 100644 src/game/LFGMgr.h
- diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
- index a749e1a..91c4c4b 100644
- --- a/src/game/Channel.cpp
- +++ b/src/game/Channel.cpp
- @@ -82,8 +82,7 @@ void Channel::Join(uint64 p, const char *pass)
- if(plr)
- {
- if(HasFlag(CHANNEL_FLAG_LFG) &&
- - sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER &&
- - (plr->GetGroup() || plr->m_lookingForGroup.Empty()) )
- + sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER && plr->GetGroup())
- {
- MakeNotInLfg(&data);
- SendToOne(&data, p);
- diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
- index a6860f8..0fc5f3e 100644
- --- a/src/game/CharacterHandler.cpp
- +++ b/src/game/CharacterHandler.cpp
- @@ -839,7 +839,7 @@ void WorldSession::HandleMeetingStoneInfo( WorldPacket & /*recv_data*/ )
- {
- DEBUG_LOG( "WORLD: Received CMSG_MEETING_STONE_INFO" );
- - SendLfgUpdate(0, 0, 0);
- + //SendLfgUpdate(0, 0, 0);
- }
- void WorldSession::HandleTutorialFlag( WorldPacket & recv_data )
- diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
- index 8f0fd71..04999f0 100644
- --- a/src/game/DBCStores.cpp
- +++ b/src/game/DBCStores.cpp
- @@ -93,6 +93,7 @@ DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomProp
- DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
- DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
- +DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt);
- DBCStorage <LockEntry> sLockStore(LockEntryfmt);
- DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
- @@ -334,7 +335,7 @@ void LoadDBCStores(const std::string& dataPath)
- exit(1);
- }
- - const uint32 DBCFilesCount = 85;
- + const uint32 DBCFilesCount = 86;
- barGoLink bar( (int)DBCFilesCount );
- @@ -421,6 +422,7 @@ void LoadDBCStores(const std::string& dataPath)
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc");
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc");
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc");
- + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLFGDungeonStore, dbcPath,"LFGDungeons.dbc");
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
- LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
- diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h
- index 5051236..5e3d271 100644
- --- a/src/game/DBCStores.h
- +++ b/src/game/DBCStores.h
- @@ -119,6 +119,7 @@ extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
- extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
- extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
- extern DBCStorage <ItemSetEntry> sItemSetStore;
- +extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
- extern DBCStorage <LockEntry> sLockStore;
- extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
- extern DBCStorage <MapEntry> sMapStore;
- diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
- index e63ae5c..cb8a8a9 100644
- --- a/src/game/DBCStructure.h
- +++ b/src/game/DBCStructure.h
- @@ -1075,6 +1075,29 @@ struct ItemSetEntry
- uint32 required_skill_value; // 52 m_requiredSkillRank
- };
- +struct LFGDungeonEntry
- +{
- + uint32 ID; // 0
- + //char* name[16]; // 1-17 Name lang
- + uint32 minlevel; // 18
- + uint32 maxlevel; // 19
- + uint32 reclevel; // 20
- + uint32 recminlevel; // 21
- + uint32 recmaxlevel; // 22
- + uint32 map; // 23
- + uint32 heroic; // 24
- + //uint32 unk; // 25
- + uint32 type; // 26
- + //uint32 unk2; // 27
- + //char* unk3; // 28
- + uint32 expansion; // 29
- + //uint32 unk4; // 30
- + uint32 grouptype; // 31
- + //char* desc[16]; // 32-47 Description
- + // Helpers
- + uint32 Entry() const { return ID + (type << 24); }
- +};
- +
- #define MAX_LOCK_CASE 8
- struct LockEntry
- diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
- index 5824944..fa6eb04 100644
- --- a/src/game/DBCfmt.h
- +++ b/src/game/DBCfmt.h
- @@ -70,6 +70,7 @@ const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
- const char ItemRandomPropertiesfmt[]="nxiiiiissssssssssssssssx";
- const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
- const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
- +const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx";
- const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
- const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
- const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx";
- diff --git a/src/game/Group.cpp b/src/game/Group.cpp
- index 1ba7e36..f97fd51 100644
- --- a/src/game/Group.cpp
- +++ b/src/game/Group.cpp
- @@ -34,13 +34,14 @@
- #include "MapInstanced.h"
- #include "Util.h"
- #include "LootMgr.h"
- +#include "LFGMgr.h"
- #define LOOT_ROLL_TIMEOUT (1*MINUTE*IN_MILLISECONDS)
- Group::Group() : m_Id(0), m_leaderGuid(0), m_mainTank(0), m_mainAssistant(0), m_groupType(GROUPTYPE_NORMAL),
- m_dungeonDifficulty(REGULAR_DIFFICULTY), m_raidDifficulty(REGULAR_DIFFICULTY),
- m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_looterGuid(0), m_lootThreshold(ITEM_QUALITY_UNCOMMON),
- - m_subGroupsCounts(NULL)
- + m_subGroupsCounts(NULL), m_guid(0), m_counter(0)
- {
- for (int i = 0; i < TARGET_ICON_COUNT; ++i)
- m_targetIcons[i] = 0;
- @@ -98,6 +99,7 @@ bool Group::Create(const uint64 &guid, const char * name)
- if(!isBGGroup())
- {
- m_Id = sObjectMgr.GenerateGroupId();
- + m_guid = MAKE_NEW_GUID(m_Id, 0, HIGHGUID_GROUP);
- Player *leader = sObjectMgr.GetPlayer(guid);
- if(leader)
- @@ -133,6 +135,7 @@ bool Group::LoadGroupFromDB(Field* fields)
- // result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty, leaderGuid, groupId FROM groups");
- m_Id = fields[17].GetUInt32();
- + m_guid = MAKE_NEW_GUID(m_Id, 0, HIGHGUID_GROUP);
- m_leaderGuid = MAKE_NEW_GUID(fields[16].GetUInt32(),0,HIGHGUID_PLAYER);
- // group leader not exist
- @@ -309,6 +312,11 @@ bool Group::AddMember(const uint64 &guid, const char* name)
- uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
- {
- + //BroadcastGroupUpdate();
- +
- + if (!isBGGroup())
- + sLFGMgr.Leave(NULL, this);
- +
- // remove member and change leader (if need) only if strong more 2 members _before_ member remove
- if(GetMembersCount() > uint32(isBGGroup() ? 1 : 2)) // in BG group case allow 1 members group
- {
- @@ -324,8 +332,9 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
- if(method == 1)
- {
- - data.Initialize( SMSG_GROUP_UNINVITE, 0 );
- - player->GetSession()->SendPacket( &data );
- + data.Initialize(SMSG_GROUP_UNINVITE, 0);
- + player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_LEADER);
- + player->GetSession()->SendPacket(&data);
- }
- //we already removed player from group and in player->GetGroup() is his original group!
- @@ -337,7 +346,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
- {
- data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8);
- data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
- - data << uint64(0) << uint32(0) << uint32(0) << uint64(0);
- + data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0);
- player->GetSession()->SendPacket(&data);
- }
- @@ -355,7 +364,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
- }
- // if group before remove <= 2 disband it
- else
- - Disband(true);
- + Disband();
- return m_memberSlots.size();
- }
- @@ -396,6 +405,8 @@ void Group::Disband(bool hideDestroy)
- player->SetOriginalGroup(NULL);
- else
- player->SetGroup(NULL);
- + player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_GROUP_DISBAND);
- + player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_LEADER);
- }
- // quest related GO state dependent from raid membership
- @@ -421,7 +432,7 @@ void Group::Disband(bool hideDestroy)
- {
- data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8);
- data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
- - data << uint64(0) << uint32(0) << uint32(0) << uint64(0);
- + data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0);
- player->GetSession()->SendPacket(&data);
- }
- @@ -442,6 +453,7 @@ void Group::Disband(bool hideDestroy)
- ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
- }
- + m_guid = 0;
- m_leaderGuid = 0;
- m_leaderName = "";
- }
- @@ -979,8 +991,8 @@ void Group::SendUpdate()
- data << uint8(0);
- data << uint32(0);
- }
- - data << uint64(0x50000000FFFFFFFELL); // related to voice chat?
- - data << uint32(0); // 3.3, this value increments every time SMSG_GROUP_LIST is sent
- + data << uint64(m_guid);
- + data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent
- data << uint32(GetMembersCount()-1);
- for(member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2)
- {
- @@ -1158,6 +1170,7 @@ bool Group::_removeMember(const uint64 &guid)
- player->SetOriginalGroup(NULL);
- else
- player->SetGroup(NULL);
- + player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_LEADER);
- }
- }
- diff --git a/src/game/Group.h b/src/game/Group.h
- index c9cffe3..97bde46 100644
- --- a/src/game/Group.h
- +++ b/src/game/Group.h
- @@ -209,6 +209,7 @@ class MANGOS_DLL_SPEC Group
- bool isBGGroup() const { return m_bgGroup != NULL; }
- bool IsCreated() const { return GetMembersCount() > 0; }
- const uint64& GetLeaderGUID() const { return m_leaderGuid; }
- + const uint64& GetGUID() const { return m_guid; }
- const char * GetLeaderName() const { return m_leaderName.c_str(); }
- LootMethod GetLootMethod() const { return m_lootMethod; }
- const uint64& GetLooterGuid() const { return m_looterGuid; }
- @@ -451,5 +452,7 @@ class MANGOS_DLL_SPEC Group
- Rolls RollId;
- BoundInstancesMap m_boundInstances[MAX_DIFFICULTY];
- uint8* m_subGroupsCounts;
- + uint64 m_guid;
- + uint32 m_counter; // used only in SMSG_GROUP_LIST
- };
- #endif
- diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
- index d73b233..8bdc202 100644
- --- a/src/game/GroupHandler.cpp
- +++ b/src/game/GroupHandler.cpp
- @@ -28,6 +28,7 @@
- #include "Group.h"
- #include "SocialMgr.h"
- #include "Util.h"
- +#include "LFG.h"
- /* differeces from off:
- -you can uninvite yourself - is is useful
- @@ -161,6 +162,8 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
- data << uint32(0); // unk
- player->GetSession()->SendPacket(&data);
- + SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK);
- }
- @@ -207,6 +210,16 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
- // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
- if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
- return;
- +
- + SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
- + if (Player *plrg = itr->getSource())
- + {
- + plrg->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_CLEAR_LOCK_LIST);
- + plrg->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_CLEAR_LOCK_LIST);
- + }
- +
- + //group->BroadcastGroupUpdate();
- }
- void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
- diff --git a/src/game/LFG.h b/src/game/LFG.h
- new file mode 100644
- index 0000000..4ef3d20
- --- /dev/null
- +++ b/src/game/LFG.h
- @@ -0,0 +1,54 @@
- +#ifndef _LFG_H
- +#define _LFG_H
- +
- +#include "Platform/Define.h"
- +#include "Object.h"
- +
- +enum LfgRoles
- +{
- + ROLE_NONE = 0x00,
- + ROLE_LEADER = 0x01,
- + ROLE_TANK = 0x02,
- + ROLE_HEALER = 0x04,
- + ROLE_DAMAGE = 0x08,
- +};
- +
- +enum LfgUpdateType
- +{
- + LFG_UPDATETYPE_LEADER = 1,
- + LFG_UPDATETYPE_ROLECHECK_ABORTED = 4,
- + LFG_UPDATETYPE_JOIN_PROPOSAL = 5,
- + LFG_UPDATETYPE_ROLECHECK_FAILED = 6,
- + LFG_UPDATETYPE_REMOVED_FROM_QUEUE = 7,
- + LFG_UPDATETYPE_PROPOSAL_FAILED = 8,
- + LFG_UPDATETYPE_PROPOSAL_DECLINED = 9,
- + LFG_UPDATETYPE_GROUP_FOUND = 10,
- + LFG_UPDATETYPE_ADDED_TO_QUEUE = 12,
- + LFG_UPDATETYPE_PROPOSAL_FOUND = 13,
- + LFG_UPDATETYPE_CLEAR_LOCK_LIST = 14,
- + LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 15,
- + LFG_UPDATETYPE_GROUP_DISBAND = 16,
- +};
- +
- +typedef std::set<uint32> LfgDungeonSet;
- +
- +struct LookingForGroup
- +{
- + LookingForGroup(): roles(0)
- + {
- + donerandomDungeons.clear();
- + applyDungeons.clear();
- + }
- + std::string comment;
- + int8 roles;
- +
- + bool isDungeonDone(const uint32 entry)
- + {
- + return donerandomDungeons.find(entry) != donerandomDungeons.end();
- + }
- +
- + LfgDungeonSet applyDungeons; // Dungeons the player have applied for
- + LfgDungeonSet donerandomDungeons; // Finished random Dungeons (to calculate the bonus);
- +};
- +
- +#endif
- diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
- index 8eaa56c..c077e50 100644
- --- a/src/game/LFGHandler.cpp
- +++ b/src/game/LFGHandler.cpp
- @@ -16,442 +16,235 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- +#include "LFGMgr.h"
- #include "WorldSession.h"
- -#include "Log.h"
- -#include "Database/DatabaseEnv.h"
- -#include "Player.h"
- #include "WorldPacket.h"
- -#include "ObjectMgr.h"
- -#include "World.h"
- +#include "Player.h"
- -static void AttemptJoin(Player* _player)
- +void WorldSession::HandleLfgJoinOpcode(WorldPacket &recv_data)
- {
- - // skip not can autojoin cases and player group case
- - if(!_player->m_lookingForGroup.canAutoJoin() || _player->GetGroup())
- - return;
- -
- - //TODO: Guard Player Map
- - HashMapHolder<Player>::MapType const& players = sObjectAccessor.GetPlayers();
- - for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- - {
- - Player *plr = iter->second;
- -
- - // skip enemies and self
- - if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
- - continue;
- -
- - //skip players not in world
- - if(!plr->IsInWorld())
- - continue;
- -
- - // skip not auto add, not group leader cases
- - if (!plr->GetSession()->LookingForGroup_auto_add || (plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID()))
- - continue;
- -
- - // skip non auto-join or empty slots, or non compatible slots
- - if(!plr->m_lookingForGroup.more.canAutoJoin() || !_player->m_lookingForGroup.HaveInSlot(plr->m_lookingForGroup.more))
- - continue;
- -
- - // attempt create group, or skip
- - if(!plr->GetGroup())
- - {
- - Group* group = new Group;
- - if(!group->Create(plr->GetGUID(), plr->GetName()))
- - {
- - delete group;
- - continue;
- - }
- -
- - sObjectMgr.AddGroup(group);
- - }
- -
- - // stop at success join
- - if(plr->GetGroup()->AddMember(_player->GetGUID(), _player->GetName()))
- - {
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
- - _player->LeaveLFGChannel();
- - break;
- - }
- - // full
- - else
- - {
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
- - plr->LeaveLFGChannel();
- - }
- - }
- -}
- + DEBUG_LOG("CMSG_LFG_JOIN");
- -static void AttemptAddMore(Player* _player)
- -{
- - // skip not group leader case
- - if(_player->GetGroup() && _player->GetGroup()->GetLeaderGUID()!=_player->GetGUID())
- - return;
- + uint8 numDungeons;
- + uint32 dungeon;
- + uint32 roles;
- + std::string comment;
- - if(!_player->m_lookingForGroup.more.canAutoJoin())
- + recv_data >> roles;
- + recv_data.read_skip<uint8>(); // unk - always 0
- + recv_data.read_skip<uint8>(); // unk - always 0
- + recv_data >> numDungeons;
- + if (!numDungeons)
- + {
- + sLog.outError("Invalid CMSG_LFG_JOIN packet sent by %s", GetPlayer()->GetName());
- + recv_data.rpos(recv_data.wpos());
- return;
- + }
- - //TODO: Guard Player map
- - HashMapHolder<Player>::MapType const& players = sObjectAccessor.GetPlayers();
- - for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- + GetPlayer()->m_lookingForGroup.roles = uint8(roles);
- + for (int8 i = 0 ; i < numDungeons; ++i)
- {
- - Player *plr = iter->second;
- -
- - // skip enemies and self
- - if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
- - continue;
- -
- - if(!plr->IsInWorld())
- - continue;
- -
- - // skip not auto join or in group
- - if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() )
- - continue;
- -
- - if(!plr->m_lookingForGroup.HaveInSlot(_player->m_lookingForGroup.more))
- - continue;
- -
- - // attempt create group if need, or stop attempts
- - if(!_player->GetGroup())
- - {
- - Group* group = new Group;
- - if(!group->Create(_player->GetGUID(), _player->GetName()))
- - {
- - delete group;
- - return; // can't create group (??)
- - }
- -
- - sObjectMgr.AddGroup(group);
- - }
- -
- - // stop at join fail (full)
- - if(!_player->GetGroup()->AddMember(plr->GetGUID(), plr->GetName()) )
- - {
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
- - _player->LeaveLFGChannel();
- -
- - break;
- - }
- -
- - // joined
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
- - plr->LeaveLFGChannel();
- -
- - // and group full
- - if(_player->GetGroup()->IsFull() )
- - {
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
- - _player->LeaveLFGChannel();
- -
- - break;
- - }
- + recv_data >> dungeon;
- + // remove the type from the dungeon entry
- + GetPlayer()->m_lookingForGroup.applyDungeons.insert((dungeon & 0x00FFFFFF));
- }
- -}
- -
- -void WorldSession::HandleLfgJoinOpcode( WorldPacket & recv_data )
- -{
- - DEBUG_LOG("CMSG_LFG_JOIN");
- - LookingForGroup_auto_join = true;
- - uint8 counter1, counter2;
- - std::string comment;
- -
- - recv_data >> Unused<uint32>(); // lfg roles
- - recv_data >> Unused<uint8>(); // unk1 (unused?)
- - recv_data >> Unused<uint8>(); // unk2 (unused?)
- -
- - recv_data >> counter1;
- - for (uint8 i = 0; i < counter1; i++)
- - recv_data >> Unused<uint32>(); // queue block? (type/zone?)
- -
- - recv_data >> counter2;
- - for (uint8 i = 0; i < counter2; i++)
- - recv_data >> Unused<uint8>(); // unk (unused?)
- -
- - recv_data >> comment; // lfg comment
- + recv_data >> numDungeons; // unk - always 3
- + for (int8 i = 0 ; i < numDungeons; ++i)
- + recv_data.read_skip<uint8>(); // unk - always 0
- - if(!_player) // needed because STATUS_AUTHED
- - return;
- + recv_data >> comment;
- - AttemptJoin(_player);
- + GetPlayer()->m_lookingForGroup.comment = comment;
- + sLFGMgr.Join(GetPlayer());
- }
- -void WorldSession::HandleLfgLeaveOpcode( WorldPacket & /*recv_data*/ )
- +void WorldSession::HandleLfgLeaveOpcode(WorldPacket & /*recv_data*/)
- {
- DEBUG_LOG("CMSG_LFG_LEAVE");
- - LookingForGroup_auto_join = false;
- +
- + // Check cheating - only leader can leave the queue
- + if (Group *grp = GetPlayer()->GetGroup())
- + {
- + if (grp->GetLeaderGUID() != GetPlayer()->GetGUID())
- + return;
- + else
- + sLFGMgr.Leave(GetPlayer(), grp);
- + }
- + else
- + sLFGMgr.Leave(GetPlayer());
- }
- -void WorldSession::HandleSearchLfgJoinOpcode( WorldPacket & recv_data )
- +void WorldSession::HandleLfgSetRolesOpcode(WorldPacket &recv_data)
- {
- - DEBUG_LOG("CMSG_SEARCH_LFG_JOIN");
- - LookingForGroup_auto_add = true;
- + DEBUG_LOG("CMSG_LFG_SET_ROLES");
- - recv_data >> Unused<uint32>(); // join id?
- + uint8 roles;
- + recv_data >> roles; // Player Group Roles
- - if(!_player) // needed because STATUS_AUTHED
- + Group *grp = GetPlayer()->GetGroup();
- + if (!grp)
- return;
- -
- - AttemptAddMore(_player);
- + GetPlayer()->m_lookingForGroup.roles = roles;
- + sLFGMgr.UpdateRoleCheck(grp, GetPlayer());
- }
- -void WorldSession::HandleSearchLfgLeaveOpcode( WorldPacket & recv_data )
- +void WorldSession::HandleSetLfgCommentOpcode(WorldPacket & recv_data)
- {
- - DEBUG_LOG("CMSG_SEARCH_LFG_LEAVE");
- - LookingForGroup_auto_add = false;
- -
- - recv_data >> Unused<uint32>(); // join id?
- -}
- -
- -void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ )
- -{
- - // empty packet
- - DEBUG_LOG("CMSG_CLEAR_LOOKING_FOR_GROUP");
- -
- - for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- - _player->m_lookingForGroup.slots[i].Clear();
- + DEBUG_LOG("CMSG_SET_LFG_COMMENT");
- - if( sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
- - _player->LeaveLFGChannel();
- + std::string comment;
- + recv_data >> comment;
- - SendLfgUpdate(0, 0, 0);
- + GetPlayer()->m_lookingForGroup.comment = comment;
- }
- -void WorldSession::HandleLfmClearOpcode( WorldPacket & /*recv_data */)
- +void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket &/*recv_data*/)
- {
- - // empty packet
- - DEBUG_LOG("CMSG_CLEAR_LOOKING_FOR_MORE");
- -
- - _player->m_lookingForGroup.more.Clear();
- + DEBUG_LOG("CMSG_LFD_PLAYER_LOCK_INFO_REQUEST");
- + sLFGMgr.SendLfgPlayerInfo(GetPlayer());
- }
- -void WorldSession::HandleSetLfmOpcode( WorldPacket & recv_data )
- +void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket &/*recv_data*/)
- {
- - DEBUG_LOG("CMSG_SET_LOOKING_FOR_MORE");
- - //recv_data.hexlike();
- - uint32 temp, entry, type;
- - uint8 unk1;
- - uint8 unk2[3];
- -
- - recv_data >> temp >> unk1 >> unk2[0] >> unk2[1] >> unk2[2];
- -
- - entry = ( temp & 0x00FFFFFF);
- - type = ( (temp >> 24) & 0x000000FF);
- -
- - _player->m_lookingForGroup.more.Set(entry,type);
- - DEBUG_LOG("LFM set: temp %u, zone %u, type %u", temp, entry, type);
- -
- - if(LookingForGroup_auto_add)
- - AttemptAddMore(_player);
- -
- - SendLfgResult(type, entry, 1);
- + DEBUG_LOG("CMSG_LFD_PARTY_LOCK_INFO_REQUEST");
- + sLFGMgr.SendLfgPartyInfo(GetPlayer());
- }
- -void WorldSession::HandleSetLfgCommentOpcode( WorldPacket & recv_data )
- +void WorldSession::SendLfgUpdatePlayer(uint8 updateType)
- {
- - DEBUG_LOG("CMSG_SET_LFG_COMMENT");
- - //recv_data.hexlike();
- + bool queued = false;
- + bool extrainfo = false;
- - std::string comment;
- - recv_data >> comment;
- - DEBUG_LOG("LFG comment %s", comment.c_str());
- -
- - _player->m_lookingForGroup.comment = comment;
- -}
- -
- -void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
- -{
- - DEBUG_LOG("MSG_LOOKING_FOR_GROUP");
- - //recv_data.hexlike();
- - uint32 type, entry, unk;
- -
- - recv_data >> type >> entry >> unk;
- - DEBUG_LOG("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type, entry, unk);
- -
- - if(LookingForGroup_auto_add)
- - AttemptAddMore(_player);
- + switch(updateType)
- + {
- + case LFG_UPDATETYPE_JOIN_PROPOSAL:
- + case LFG_UPDATETYPE_ADDED_TO_QUEUE:
- + queued = true;
- + extrainfo = true;
- + break;
- + //case LFG_UPDATETYPE_CLEAR_LOCK_LIST: // TODO: Sometimes has extrainfo - Check ocurrences...
- + case LFG_UPDATETYPE_PROPOSAL_FOUND:
- + extrainfo = true;
- + break;
- + }
- + DEBUG_LOG("SMSG_LFG_UPDATE_PLAYER");
- + WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + GetPlayer()->m_lookingForGroup.applyDungeons.size() * 4 + GetPlayer()->m_lookingForGroup.comment.length()));
- + data << uint8(updateType); // Lfg Update type
- + data << uint8(extrainfo); // Extra info
- + if (extrainfo)
- + {
- + data << uint8(queued); // Join the queue
- + data << uint8(0); // unk - Always 0
- + data << uint8(0); // unk - Always 0
- - if(LookingForGroup_auto_join)
- - AttemptJoin(_player);
- + uint8 size = GetPlayer()->m_lookingForGroup.applyDungeons.size();
- + data << uint8(size);
- - SendLfgResult(type, entry, 0);
- - SendLfgUpdate(0, 1, 0);
- + for (LfgDungeonSet::const_iterator it = GetPlayer()->m_lookingForGroup.applyDungeons.begin(); it != GetPlayer()->m_lookingForGroup.applyDungeons.end(); ++it)
- + data << uint32(*it);
- + data << GetPlayer()->m_lookingForGroup.comment;
- + }
- + SendPacket(&data);
- }
- -void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
- +void WorldSession::SendLfgUpdateParty(uint8 updateType)
- {
- - /*uint32 number = 0;
- + bool join = false;
- + bool extrainfo = false;
- + bool queued = false;
- - WorldPacket data(MSG_LOOKING_FOR_GROUP);
- - data << uint32(type); // type
- - data << uint32(entry); // entry from LFGDungeons.dbc
- -
- - data << uint8(0);
- - if(uint8)
- + switch(updateType)
- {
- - uint32 count1;
- - for(count1)
- - {
- - uint64; // player guid
- - }
- + case LFG_UPDATETYPE_JOIN_PROPOSAL:
- + extrainfo = true;
- + break;
- + case LFG_UPDATETYPE_ADDED_TO_QUEUE:
- + extrainfo = true;
- + join = true;
- + queued = true;
- + break;
- + case LFG_UPDATETYPE_CLEAR_LOCK_LIST:
- + // join = true; // TODO: Sometimes queued and extrainfo - Check ocurrences...
- + queued = true;
- + break;
- + case LFG_UPDATETYPE_PROPOSAL_FOUND:
- + extrainfo = true;
- + join = true;
- + break;
- }
- - data << uint32(0); // count2
- - data << uint32(0);
- - for(count2)
- + DEBUG_LOG("SMSG_LFG_UPDATE_PARTY");
- + WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + GetPlayer()->m_lookingForGroup.applyDungeons.size() * 4 + GetPlayer()->m_lookingForGroup.comment.length()));
- + data << uint8(updateType); // Lfg Update type
- + data << uint8(extrainfo); // Extra info
- + if (extrainfo)
- {
- - uint64 // not player guid
- - uint32 flags;
- - if(flags & 0x2)
- - {
- - data << uint8(0); // string
- - }
- - if(flags & 0x10)
- - {
- - data << uint8(0);
- - }
- - if(flags & 0x20)
- - {
- - for(int i = 0; i < 3; ++i)
- - {
- - data << uint8(0);
- - }
- - }
- - }
- + data << uint8(join); // LFG Join
- + data << uint8(queued); // Join the queue
- + data << uint8(0); // unk - Always 0
- + data << uint8(0); // unk - Always 0
- + for (uint8 i = 0; i < 3; ++i)
- + data << uint8(0); // unk - Always 0
- - size_t count3_pos = data.wpos();
- - data << uint32(0); // count3
- - data << uint32(0); // unk
- + uint8 size = GetPlayer()->m_lookingForGroup.applyDungeons.size();
- + data << uint8(size);
- - //TODO: Guard Player map
- - HashMapHolder<Player>::MapType const& players = sObjectAccessor.GetPlayers();
- - for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- - {
- - Player *plr = iter->second;
- -
- - if(!plr || plr->GetTeam() != _player->GetTeam())
- - continue;
- -
- - if(!plr->IsInWorld())
- - continue;
- -
- - if(!plr->m_lookingForGroup.HaveInSlot(entry, type))
- - continue;
- -
- - ++number;
- -
- - data << uint64(plr->GetGUID()); // guid
- -
- - uint32 flags = 0x1FF;
- - data << uint32(flags); // flags
- -
- - if(flags & 0x1)
- - {
- - data << uint8(plr->getLevel());
- - data << uint8(plr->getClass());
- - data << uint8(plr->getRace());
- -
- - for(int i = 0; i < 3; ++i)
- - data << uint8(0); // spent talents count in specific tab
- -
- - data << uint32(0); // resistances1
- - data << uint32(0); // spd/heal
- - data << uint32(0); // spd/heal
- - data << uint32(0); // combat_rating9
- - data << uint32(0); // combat_rating10
- - data << uint32(0); // combat_rating11
- - data << float(0); // mp5
- - data << float(0); // unk
- - data << uint32(0); // attack power
- - data << uint32(0); // stat1
- - data << uint32(0); // maxhealth
- - data << uint32(0); // maxpower1
- - data << uint32(0); // unk
- - data << float(0); // unk
- - data << uint32(0); // unk
- - data << uint32(0); // unk
- - data << uint32(0); // unk
- - data << uint32(0); // unk
- - data << uint32(0); // combat_rating20
- - data << uint32(0); // unk
- - }
- -
- - if(flags & 0x2)
- - data << plr->m_lookingForGroup.comment; // comment
- -
- - if(flags & 0x4)
- - data << uint8(0); // unk
- -
- - if(flags & 0x8)
- - data << uint64(0); // guid from count2 block, not player guid
- -
- - if(flags & 0x10)
- - data << uint8(0); // unk
- -
- - if(flags & 0x20)
- - data << uint8(plr->m_lookingForGroup.roles); // roles
- -
- - if(flags & 0x40)
- - data << uint32(plr->GetZoneId()); // areaid
- -
- - if(flags & 0x100)
- - data << uint8(0); // LFG/LFM flag?
- -
- - if(flags & 0x80)
- - {
- - for(uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j)
- - {
- - data << uint32(plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24));
- - }
- - }
- - }
- -
- - data.put<uint32>(count3_pos, number); // fill count placeholder
- + for (LfgDungeonSet::const_iterator it = GetPlayer()->m_lookingForGroup.applyDungeons.begin(); it != GetPlayer()->m_lookingForGroup.applyDungeons.end(); ++it)
- + data << uint32(*it);
- - SendPacket(&data);*/
- + data << GetPlayer()->m_lookingForGroup.comment;
- + }
- + SendPacket(&data);
- }
- -void WorldSession::HandleSetLfgOpcode( WorldPacket & recv_data )
- +void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles)
- {
- - DEBUG_LOG("CMSG_SET_LOOKING_FOR_GROUP");
- - recv_data.hexlike();
- - uint32 slot, temp, entry, type;
- - uint8 roles, unk1;
- -
- - recv_data >> slot >> temp >> roles >> unk1;
- + DEBUG_LOG("SMSG_LFG_ROLE_CHOSEN");
- - entry = ( temp & 0x00FFFFFF);
- - type = ( (temp >> 24) & 0x000000FF);
- + WorldPacket data(SMSG_LFG_ROLE_CHOSEN);
- + data << uint64(guid); // Guid
- + data << uint8(roles > 0); // Ready
- + data << uint32(roles); // Roles
- + SendPacket(&data);
- +}
- - if(slot >= MAX_LOOKING_FOR_GROUP_SLOT)
- +void WorldSession::SendLfgJoinResult(uint8 checkResult, uint8 checkValue)
- +{
- + if (checkResult == LFG_JOIN_PARTY_NOT_MEET_REQS) // Should never happen - its handled in Mgr
- return;
- - _player->m_lookingForGroup.slots[slot].Set(entry, type);
- - _player->m_lookingForGroup.roles = roles;
- - DEBUG_LOG("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, temp, type, entry);
- -
- - if(LookingForGroup_auto_join)
- - AttemptJoin(_player);
- + DEBUG_LOG("SMSG_LFG_JOIN_RESULT");
- - //SendLfgResult(type, entry, 0);
- - SendLfgUpdate(0, 1, 0);
- + WorldPacket data(SMSG_LFG_JOIN_RESULT);
- + data << uint32(checkResult); // Check Result
- + data << uint32(checkValue); // Check Value
- + SendPacket(&data);
- }
- -void WorldSession::HandleLfgSetRoles(WorldPacket &recv_data)
- +void WorldSession::SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps)
- {
- - DEBUG_LOG("CMSG_LFG_SET_ROLES");
- -
- - uint8 roles;
- - recv_data >> roles;
- -
- - _player->m_lookingForGroup.roles = roles;
- + DEBUG_LOG("SMSG_LFG_QUEUE_STATUS");
- + WorldPacket data(SMSG_LFG_QUEUE_STATUS);
- +
- + data << uint32(dungeon); // Dungeon
- + data << uint32(avgWaitTime); // Average Wait time
- + data << uint32(waitTime); // Wait Time
- + data << uint32(waitTimeTanks); // Wait Tanks
- + data << uint32(waitTimeHealer); // Wait Healers
- + data << uint32(waitTimeDps); // Wait Dps
- + data << uint8(tanks); // Tanks needed
- + data << uint8(healers); // Healers needed
- + data << uint8(dps); // Dps needed
- + data << uint32(queuedTime); // Player wait time in queue
- + SendPacket(&data);
- }
- -void WorldSession::SendLfgUpdate(uint8 /*unk1*/, uint8 /*unk2*/, uint8 /*unk3*/)
- +void WorldSession::SendLfgUpdateSearch(bool update)
- {
- - // disabled
- - /*WorldPacket data(SMSG_LFG_UPDATE, 3);
- - data << uint8(unk1);
- - data << uint8(unk2);
- - data << uint8(unk3);
- - SendPacket(&data);*/
- + DEBUG_LOG("SMSG_LFG_UPDATE_SEARCH");
- +
- + WorldPacket data(SMSG_LFG_UPDATE_SEARCH);
- + data << uint8(update); // In Lfg Queue?
- + SendPacket(&data);
- }
- diff --git a/src/game/LFGMgr.cpp b/src/game/LFGMgr.cpp
- new file mode 100644
- index 0000000..1112a42
- --- /dev/null
- +++ b/src/game/LFGMgr.cpp
- @@ -0,0 +1,1069 @@
- +#include "Policies/SingletonImp.h"
- +#include "Common.h"
- +#include "SharedDefines.h"
- +#include "Group.h"
- +#include "Player.h"
- +#include "LFGMgr.h"
- +#include "ObjectMgr.h"
- +#include "WorldPacket.h"
- +
- +INSTANTIATE_SINGLETON_1(LFGMgr);
- +
- +/*********************************************************/
- +/*** LFG QUEUES ***/
- +/*********************************************************/
- +
- +LFGQueue::LFGQueue()
- +{
- + m_LfgQueue.clear();
- + avgWaitTime = -1;
- + waitTimeTanks = -1;
- + waitTimeHealer = -1;
- + waitTimeDps = -1;
- +}
- +
- +LFGQueue::~LFGQueue()
- +{
- + m_LfgQueue.clear();
- +}
- +
- +void LFGQueue::AddToQueue(uint64 guid, LfgQueueInfo* pqInfo)
- +{
- + if (LfgQueueInfo* qInfo = m_LfgQueue[guid])
- + delete qInfo;
- + m_LfgQueue[guid] = pqInfo;
- + // ATM will only add it to the queue... No find group implementation... yet (on purpose)
- +}
- +
- +bool LFGQueue::RemoveFromQueue(uint64 guid)
- +{
- + if (m_LfgQueue.empty())
- + return false;
- +
- + LfgQueueInfoMap::iterator itr = m_LfgQueue.find(guid);
- + if (itr == m_LfgQueue.end())
- + return false;
- +
- + delete itr->second;
- + m_LfgQueue.erase(itr);
- + return true;
- +}
- +
- +LfgQueueInfo* LFGQueue::GetQueueInfo(uint64 guid)
- +{
- + return m_LfgQueue[guid];
- +}
- +
- +void LFGQueue::Update()
- +{
- + if (m_LfgQueue.empty())
- + return;
- +
- + Player *plr;
- + LfgQueueInfo *queue;
- + time_t currTime = time(NULL);
- + uint32 queuedTime;
- + uint8 role = 0;
- + int32 waitTime = -1;
- + for (LfgQueueInfoMap::const_iterator itQueue = m_LfgQueue.begin(); itQueue != m_LfgQueue.end(); ++itQueue)
- + {
- + queue = itQueue->second;
- + // Update queue status
- + queuedTime = uint32(currTime - queue->joinTime);
- + for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer)
- + {
- + plr = sObjectMgr.GetPlayer(itPlayer->first);
- + if (!plr)
- + continue;
- + role = itPlayer->second;
- + if (role & ROLE_TANK)
- + {
- + if (role & ROLE_HEALER || role & ROLE_DAMAGE)
- + waitTime = avgWaitTime;
- + else
- + waitTime = waitTimeTanks;
- + }
- + else if (role & ROLE_HEALER)
- + {
- + if (role & ROLE_DAMAGE)
- + waitTime = avgWaitTime;
- + else
- + waitTime = waitTimeDps;
- + }
- + plr->GetSession()->SendLfgQueueStatus(queue->dungeonId, waitTime, avgWaitTime, waitTimeTanks, waitTimeHealer, waitTimeDps, queuedTime, queue->tanks, queue->healers, queue->dps);
- + }
- + }
- +}
- +
- +LFGMgr::LFGMgr()
- +{
- + m_QueueTimer = 0;
- + m_update = true;
- +}
- +
- +LFGMgr::~LFGMgr()
- +{
- + // RewardList to be removed -> query quest system
- + for (LfgRewardList::iterator it = m_RewardList.begin(); it != m_RewardList.end(); ++it)
- + delete *it;
- + m_RewardList.clear();
- +
- + // RewardDoneList to be removed -> query quest system
- + for (LfgRewardList::iterator it = m_RewardDoneList.begin(); it != m_RewardDoneList.end(); ++it)
- + delete *it;
- + m_RewardDoneList.clear();
- +
- + for(LFGQueueMap::iterator it = m_Queues.begin(); it != m_Queues.end(); ++it)
- + delete it->second;
- + m_Queues.clear();
- +
- + for (LfgDungeonMap::iterator it = m_DungeonsMap.begin(); it != m_DungeonsMap.end(); ++it)
- + {
- + it->second->clear();
- + delete it->second;
- + }
- + m_DungeonsMap.clear();
- +
- + for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end(); ++it)
- + delete it->second;
- + m_RoleChecks.clear();
- +}
- +
- +void LFGMgr::Update(uint32 diff)
- +{
- + if (!m_update)
- + return;
- +
- + // Update all players status queue info
- + if (m_QueueTimer > LFG_QUEUEUPDATE_INTERVAL)
- + {
- + m_QueueTimer = 0;
- + for (LFGQueueMap::iterator it = m_Queues.begin(); it != m_Queues.end(); ++it)
- + it->second->Update();
- + }
- + else
- + m_QueueTimer += diff;
- +
- + time_t currTime = time(NULL);
- +
- + // Remove obsolete role checks
- + LfgRoleCheckMap::iterator itRoleCheck;
- + LfgRoleCheck *pRoleCheck;
- + for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end();)
- + {
- + itRoleCheck = it++;
- + pRoleCheck = itRoleCheck->second;
- + if (currTime < pRoleCheck->cancelTime)
- + continue;
- + pRoleCheck->result = LFG_ROLECHECK_MISSING_ROLE;
- +
- + WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + pRoleCheck->dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1));
- + DEBUG_LOG("SMSG_LFG_ROLE_CHECK_UPDATE");
- + BuildLfgRoleCheck(data, pRoleCheck);
- + Player *plr = NULL;
- + for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end(); ++itRoles)
- + {
- + plr = sObjectMgr.GetPlayer(itRoles->first);
- + if (!plr)
- + continue;
- + plr->GetSession()->SendPacket(&data);
- + plr->m_lookingForGroup.applyDungeons.clear();
- + plr->m_lookingForGroup.roles = 0;
- +
- + if (itRoles->first == pRoleCheck->leader)
- + plr->GetSession()->SendLfgJoinResult(LFG_JOIN_FAILED, pRoleCheck->result);
- + }
- + delete pRoleCheck;
- + m_RoleChecks.erase(itRoleCheck);
- + }
- +}
- +
- +/// <summary>
- +/// Initialize Looking For Group
- +/// </summary>
- +void LFGMgr::InitLFG()
- +{
- + // Fill reward data (to be removed -> query quest system)
- + LfgReward *reward;
- + for (uint8 i = 0; i <= LFG_REWARD_DATA_SIZE; ++i)
- + {
- + reward = new LfgReward();
- + reward->strangers = 0;
- + reward->baseXP = RewardDungeonData[i][0];
- + reward->baseMoney = RewardDungeonData[i][1];
- + reward->variableMoney = 0;
- + reward->variableXP = 0;
- + reward->itemId = RewardDungeonData[i][2];
- + reward->displayId = RewardDungeonData[i][3];
- + reward->stackCount = RewardDungeonData[i][4];
- + m_RewardList.push_back(reward);
- + }
- +
- + for (uint8 i = 0; i < LFG_REWARD_DATA_SIZE; ++i)
- + {
- + reward = new LfgReward();
- + reward->strangers = 0;
- + reward->baseXP = RewardDungeonDoneData[i][0];
- + reward->baseMoney = RewardDungeonDoneData[i][1];
- + reward->variableMoney = 0;
- + reward->variableXP = 0;
- + reward->itemId = RewardDungeonDoneData[i][2];
- + reward->displayId = RewardDungeonDoneData[i][3];
- + reward->stackCount = RewardDungeonDoneData[i][4];
- + m_RewardDoneList.push_back(reward);
- + }
- + // Initialize dungeonMap
- + m_DungeonsMap[LFG_ALL_DUNGEONS] = GetAllDungeons();
- + m_DungeonsMap[LFG_RANDOM_CLASSIC] = GetDungeonsByRandom(LFG_RANDOM_CLASSIC);
- + m_DungeonsMap[LFG_RANDOM_BC_NORMAL] = GetDungeonsByRandom(LFG_RANDOM_BC_NORMAL);
- + m_DungeonsMap[LFG_RANDOM_BC_HEROIC] = GetDungeonsByRandom(LFG_RANDOM_BC_HEROIC);
- + m_DungeonsMap[LFG_RANDOM_LK_NORMAL] = GetDungeonsByRandom(LFG_RANDOM_LK_NORMAL);
- + m_DungeonsMap[LFG_RANDOM_LK_HEROIC] = GetDungeonsByRandom(LFG_RANDOM_LK_HEROIC);
- +}
- +
- +/// <summary>
- +/// Adds the player to lfg queue
- +/// </summary>
- +/// <param name="plr">Player</param>
- +void LFGMgr::Join(Player *plr)
- +{
- + Group *grp = plr->GetGroup();
- +
- + // TODO - 2010-05-27 Anyone can init rolecheck when already in a LFD Group?
- + if (grp && grp->GetLeaderGUID() != plr->GetGUID())
- + return;
- +
- + // Previous checks before joining
- + LfgJoinResult result = LFG_JOIN_OK;
- + if (plr->InBattleGround() || plr->InArena())
- + result = LFG_JOIN_USING_BG_SYSTEM;
- + else if (plr->HasAura(LFG_SPELL_DESERTER))
- + result = LFG_JOIN_DESERTER;
- + else if (plr->HasAura(LFG_SPELL_COOLDOWN))
- + result = LFG_JOIN_RANDOM_COOLDOWN;
- + else
- + {
- + // Check if all dungeons are valid
- + for (LfgDungeonSet::const_iterator it = plr->m_lookingForGroup.applyDungeons.begin(); it != plr->m_lookingForGroup.applyDungeons.end(); ++it)
- + {
- + if ((m_DungeonsMap[LFG_ALL_DUNGEONS])->find(*it) == (m_DungeonsMap[LFG_ALL_DUNGEONS])->end())
- + {
- + result = LFG_JOIN_DUNGEON_INVALID;
- + break;
- + }
- + }
- + }
- +
- + if (grp && result == LFG_JOIN_OK)
- + {
- + if (grp->GetMembersCount() > MAX_GROUP_SIZE)
- + result = LFG_JOIN_TOO_MUCH_MEMBERS;
- + else if (grp->isRaidGroup())
- + result = LFG_JOIN_MIXED_RAID_DUNGEON;
- + else
- + {
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL && result == LFG_JOIN_OK; itr = itr->next())
- + {
- + if (Player *plrg = itr->getSource())
- + {
- + if (plrg->HasAura(LFG_SPELL_DESERTER))
- + result = LFG_JOIN_PARTY_DESERTER;
- + else if (plrg->HasAura(LFG_SPELL_COOLDOWN))
- + result = LFG_JOIN_PARTY_RANDOM_COOLDOWN;
- + }
- + else
- + result = LFG_JOIN_DISCONNECTED;
- + }
- + }
- + }
- +
- + if (result != LFG_JOIN_OK)
- + {
- + plr->m_lookingForGroup.applyDungeons.clear();
- + plr->m_lookingForGroup.roles = 0;
- + plr->GetSession()->SendLfgJoinResult(result, 0);
- + return;
- + }
- +
- + if (grp)
- + {
- + Player *plrg = NULL;
- + for (GroupReference *itr = plr->GetGroup()->GetFirstMember(); itr != NULL; itr = itr->next())
- + {
- + plrg = itr->getSource(); // Not null, checked earlier
- + plrg->m_lookingForGroup.applyDungeons = plr->m_lookingForGroup.applyDungeons;
- + plrg->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_JOIN_PROPOSAL);
- + }
- + UpdateRoleCheck(grp, plr);
- + }
- + else
- + {
- + plr->GetSession()->SendLfgJoinResult(LFG_JOIN_OK, 0);
- + plr->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_JOIN_PROPOSAL);
- +
- + // Add player to queue
- + LfgQueueInfo *pqInfo;
- + uint8 groupType = 0;
- + uint8 tanks = LFG_TANKS_NEEDED;
- + uint8 healers = LFG_HEALERS_NEEDED;
- + uint8 dps = LFG_DPS_NEEDED;
- + if (plr->m_lookingForGroup.roles & ROLE_TANK)
- + --tanks;
- + else if (plr->m_lookingForGroup.roles & ROLE_HEALER)
- + --healers;
- + else
- + --dps;
- + m_update = false;
- + for (LfgDungeonSet::const_iterator it = plr->m_lookingForGroup.applyDungeons.begin(); it != plr->m_lookingForGroup.applyDungeons.end(); ++it)
- + {
- + groupType = GetDungeonGroupType(*it);
- + pqInfo = m_Queues[groupType] ? m_Queues[groupType]->GetQueueInfo(plr->GetGUID()) : NULL;
- + // if exist we have already added the player with another dungeon sharing same GroupType
- + if (pqInfo)
- + continue;
- + pqInfo = new LfgQueueInfo();
- + pqInfo->dungeonId = *it;
- + pqInfo->joinTime = time_t(time(NULL));
- + pqInfo->tanks = tanks;
- + pqInfo->healers = healers;
- + pqInfo->dps = dps;
- + pqInfo->roles[plr->GetGUID()] = plr->m_lookingForGroup.roles;
- + if (!m_Queues[groupType])
- + m_Queues[groupType] = new LFGQueue();
- + m_Queues[groupType]->AddToQueue(plr->GetGUID(), pqInfo);
- + }
- + m_update = true;
- + }
- +}
- +
- +/// <summary>
- +/// Leave the lfg queue
- +/// </summary>
- +/// <param name="plr">Player (could be NULL)</param>
- +/// <param name="grp">Group (could be NULL)</param>
- +void LFGMgr::Leave(Player *plr, Group *grp /* = NULL*/)
- +{
- + uint64 guid = grp ? grp->GetGUID() : plr ? plr->GetGUID() : 0;
- + assert(guid);
- +
- + // Check if player was in a rolecheck
- + if (grp)
- + {
- + LfgRoleCheckMap::iterator itRoleCheck = m_RoleChecks.find(GUID_LOPART(grp->GetGUID()));
- + if (itRoleCheck != m_RoleChecks.end())
- + {
- + UpdateRoleCheck(grp); // No player to update role = LFG_ROLECHECK_ABORTED
- + return;
- + }
- + }
- +
- + // Check if player/group was in the queue
- + bool inQueue = false;
- + for (LFGQueueMap::iterator it = m_Queues.begin(); it != m_Queues.end(); ++it)
- + inQueue |= it->second->RemoveFromQueue(guid);
- +
- + // Not in queue
- + if (!inQueue)
- + return;
- +
- + if (grp)
- + {
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- + if (Player *plrg = itr->getSource())
- + {
- + plrg->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + plrg->m_lookingForGroup.applyDungeons.clear();
- + plrg->m_lookingForGroup.roles = 0;
- + }
- + }
- + else
- + {
- + plr->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + plr->m_lookingForGroup.applyDungeons.clear();
- + plr->m_lookingForGroup.roles = 0;
- + }
- +}
- +
- +/// <summary>
- +/// Update the Role check info with the player selected role.
- +/// </summary>
- +/// <param name="grp">Group</param>
- +/// <param name="plr">Player</param>
- +void LFGMgr::UpdateRoleCheck(Group *grp, Player *plr /* = NULL*/)
- +{
- + assert(grp);
- +
- + uint32 rolecheckId = GUID_LOPART(grp->GetGUID());
- + LfgRoleCheck *pRoleCheck = NULL;
- + LfgRolesMap check_roles;
- + LfgRoleCheckMap::iterator itRoleCheck = m_RoleChecks.find(rolecheckId);
- + bool newRoleCheck = itRoleCheck == m_RoleChecks.end();
- + if (newRoleCheck)
- + {
- + if (!grp->IsLeader(plr->GetGUID()))
- + return;
- +
- + pRoleCheck = new LfgRoleCheck();
- + pRoleCheck->cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK;
- + pRoleCheck->result = LFG_ROLECHECK_INITIALITING;
- + pRoleCheck->leader = plr->GetGUID();
- +
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- + if (Player *plrg = itr->getSource())
- + pRoleCheck->roles[plrg->GetGUID()] = 0;
- +
- + pRoleCheck->dungeons = plr->m_lookingForGroup.applyDungeons;
- + }
- + else
- + pRoleCheck = itRoleCheck->second;
- +
- + LfgLockStatusMap *playersLockMap = NULL;
- + if (plr)
- + {
- + // Player selected no role.
- + if (plr->m_lookingForGroup.roles < ROLE_TANK)
- + pRoleCheck->result = LFG_ROLECHECK_NO_ROLE;
- + else
- + {
- + // Check if all players have selected a role
- + pRoleCheck->roles[plr->GetGUID()] = plr->m_lookingForGroup.roles;
- + uint8 size = 0;
- + for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end() && itRoles->second != ROLE_NONE; ++itRoles)
- + ++size;
- +
- + if (pRoleCheck->roles.size() == size)
- + {
- + // use temporal var to check roles, CheckGroupRoles modifies the roles
- + for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end(); ++itRoles)
- + check_roles[itRoles->first] = itRoles->second;
- +
- + if (!CheckGroupRoles(check_roles)) // Group is not posible
- + pRoleCheck->result = LFG_ROLECHECK_WRONG_ROLES;
- + else
- + {
- + // Check if we can find a dungeon for that group
- + pRoleCheck->result = LFG_ROLECHECK_FINISHED;
- + if (pRoleCheck->dungeons.size() > 1)
- + playersLockMap = GetPartyLockStatusDungeons(plr, &pRoleCheck->dungeons);
- + else
- + {
- + LfgDungeonSet::const_iterator it = pRoleCheck->dungeons.begin();
- + LFGDungeonEntry const *dungeon = sLFGDungeonStore.LookupEntry(*it);
- + if (dungeon && dungeon->type == LFG_TYPE_RANDOM)
- + playersLockMap = GetPartyLockStatusDungeons(plr, m_DungeonsMap[*it]);
- + else
- + playersLockMap = GetPartyLockStatusDungeons(plr, &pRoleCheck->dungeons);
- + }
- + }
- + }
- + }
- + }
- + else
- + pRoleCheck->result = LFG_ROLECHECK_ABORTED;
- +
- + WorldSession *session;
- + WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + pRoleCheck->dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1));
- + DEBUG_LOG("SMSG_LFG_ROLE_CHECK_UPDATE");
- + BuildLfgRoleCheck(data, pRoleCheck);
- +
- + Player *plrg = NULL;
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- + {
- + plrg = itr->getSource();
- + if (!plrg)
- + continue;
- +
- + session = plrg->GetSession();
- + if (!newRoleCheck && plr)
- + session->SendLfgRoleChosen(plr->GetGUID(), plr->m_lookingForGroup.roles);
- + session->SendPacket(&data);
- +
- + switch(pRoleCheck->result)
- + {
- + case LFG_ROLECHECK_INITIALITING:
- + continue;
- + case LFG_ROLECHECK_FINISHED:
- + if (!playersLockMap)
- + {
- + session->SendLfgUpdateParty(LFG_UPDATETYPE_ADDED_TO_QUEUE);
- + }
- + else
- + {
- + if (grp->IsLeader(plrg->GetGUID()))
- + {
- + uint32 size = 0;
- + for (LfgLockStatusMap::const_iterator it = playersLockMap->begin(); it != playersLockMap->end(); ++it)
- + size += 8 + 4 + it->second->size() * (4 + 4);
- + WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
- + DEBUG_LOG("SMSG_LFG_JOIN_RESULT");
- + data << uint32(LFG_JOIN_PARTY_NOT_MEET_REQS); // Check Result
- + data << uint32(0); // Check Value (always 0 when PartyNotMeetReqs
- + BuildPartyLockDungeonBlock(data, playersLockMap);
- + session->SendPacket(&data);
- + }
- + session->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED);
- + plrg->m_lookingForGroup.applyDungeons.clear();
- + plrg->m_lookingForGroup.roles = 0;
- + }
- + break;
- + default:
- + if (grp->IsLeader(plrg->GetGUID()))
- + session->SendLfgJoinResult(LFG_JOIN_FAILED, pRoleCheck->result);
- + session->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED);
- + plrg->m_lookingForGroup.applyDungeons.clear();
- + plrg->m_lookingForGroup.roles = 0;
- + break;
- + }
- + }
- +
- + if (pRoleCheck->result == LFG_ROLECHECK_FINISHED)
- + {
- + // Add qroup to queue
- + LfgQueueInfo *pqInfo;
- + uint8 groupType = 0;
- + uint8 tanks = LFG_TANKS_NEEDED;
- + uint8 healers = LFG_HEALERS_NEEDED;
- + uint8 dps = LFG_DPS_NEEDED;
- + for (LfgRolesMap::const_iterator it = check_roles.begin(); it != check_roles.end(); ++it)
- + {
- + if (it->second & ROLE_TANK)
- + --tanks;
- + else if (it->second & ROLE_HEALER)
- + --healers;
- + else
- + --dps;
- + }
- + uint64 guid = grp->GetGUID();
- + m_update = false;
- + for (LfgDungeonSet::const_iterator it = pRoleCheck->dungeons.begin(); it != pRoleCheck->dungeons.end(); ++it)
- + {
- + groupType = GetDungeonGroupType(*it);
- + pqInfo = m_Queues[groupType] ? m_Queues[groupType]->GetQueueInfo(guid) : NULL;
- + // if exist we have already added the player with another dungeon sharing same GroupType
- + if (pqInfo)
- + continue;
- + pqInfo = new LfgQueueInfo();
- + pqInfo->dungeonId = *it;
- + pqInfo->joinTime = time_t(time(NULL));
- + pqInfo->tanks = tanks;
- + pqInfo->healers = healers;
- + pqInfo->dps = dps;
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- + {
- + if (Player *plrg = itr->getSource())
- + pqInfo->roles[plrg->GetGUID()] = plrg->m_lookingForGroup.roles;
- + }
- + if (!m_Queues[groupType])
- + m_Queues[groupType] = new LFGQueue();
- + m_Queues[groupType]->AddToQueue(guid, pqInfo);
- + }
- + m_update = true;
- + }
- +
- + if (pRoleCheck->result != LFG_ROLECHECK_INITIALITING)
- + {
- + delete pRoleCheck;
- + if (!newRoleCheck)
- + m_RoleChecks.erase(itRoleCheck);
- + }
- + else if (newRoleCheck)
- + m_RoleChecks[rolecheckId] = pRoleCheck;
- +}
- +
- +/// <summary>
- +/// Check if a group can be formed with the given group
- +/// </summary>
- +/// <param name="grp">Group</param>
- +/// <returns>bool</returns>
- +bool LFGMgr::CheckGroupRoles(LfgRolesMap &groles)
- +{
- + if (!groles.size())
- + return false;
- +
- + uint8 damage = 0;
- + uint8 tank = 0;
- + uint8 healer = 0;
- + uint64 tguid = 0;
- + uint64 hguid = 0;
- + uint64 dguid = 0;
- + uint64 guid = 0;
- + uint8 role = 0;
- +
- + for (LfgRolesMap::const_iterator it = groles.begin(); it != groles.end(); ++it)
- + {
- + guid = it->first;
- + role = it->second;
- +
- + if (role == ROLE_NONE || role == ROLE_LEADER)
- + return false;
- +
- + if (role & ROLE_TANK)
- + if (!tank)
- + {
- + tguid = guid;
- + ++tank;
- + }
- + else
- + {
- + if (groles[tguid] == ROLE_TANK)
- + tguid = guid;
- + groles[tguid] -= ROLE_TANK;
- + return CheckGroupRoles(groles);
- + }
- +
- + if (role & ROLE_HEALER)
- + if (!healer)
- + {
- + hguid = guid;
- + ++healer;
- + }
- + else
- + {
- + if (groles[hguid] == ROLE_HEALER)
- + hguid = guid;
- + groles[hguid] -= ROLE_HEALER;
- + return CheckGroupRoles(groles);
- + }
- +
- + if (role & ROLE_DAMAGE)
- + if (damage < 3)
- + {
- + if (!damage)
- + dguid = guid;
- + ++damage;
- + }
- + else
- + {
- + if (groles[dguid] == ROLE_DAMAGE)
- + dguid = guid;
- + groles[dguid] -= ROLE_DAMAGE;
- + return CheckGroupRoles(groles);
- + }
- + }
- + return true;
- +}
- +
- +
- +
- +// --------------------------------------------------------------------------//
- +// Packet Functions
- +// --------------------------------------------------------------------------//
- +
- +/// <summary>
- +/// Build lfgRolecheck packet
- +/// </summary>
- +/// <param name="data">WorldPacket</param>
- +/// <param name="plr">Player</param>
- +/// <param name="status">Player status in LFG system</param>
- +void LFGMgr::BuildLfgRoleCheck(WorldPacket &data, LfgRoleCheck *pRoleCheck)
- +{
- + assert(pRoleCheck);
- +
- + Player *plr;
- + uint8 roles;
- +
- + data << uint32(pRoleCheck->result); // Check result
- + data << uint8(pRoleCheck->result == LFG_ROLECHECK_INITIALITING);
- + data << uint8(pRoleCheck->dungeons.size()); // Number of dungeons
- + LFGDungeonEntry const *dungeon;
- + for (LfgDungeonSet::iterator it = pRoleCheck->dungeons.begin(); it != pRoleCheck->dungeons.end(); ++it)
- + {
- + dungeon = sLFGDungeonStore.LookupEntry(*it); // not null - been checked at join time
- + data << uint32(dungeon->Entry()); // Dungeon
- + }
- +
- + data << uint8(pRoleCheck->roles.size()); // Players in group
- + // Leader info MUST be sent 1st :S
- + roles = pRoleCheck->roles[pRoleCheck->leader];
- + data << uint64(pRoleCheck->leader); // Guid
- + data << uint8(roles > 0); // Ready
- + data << uint32(roles); // Roles
- + plr = sObjectMgr.GetPlayer(pRoleCheck->leader);
- + if (plr)
- + data << uint8(plr->getLevel()); // Level
- + else
- + data << uint8(0);
- +
- + for (LfgRolesMap::const_iterator itPlayers = pRoleCheck->roles.begin(); itPlayers != pRoleCheck->roles.end(); ++itPlayers)
- + {
- + if (itPlayers->first == pRoleCheck->leader)
- + continue;
- +
- + roles = itPlayers->second;
- + data << uint64(itPlayers->first); // Guid
- + data << uint8(roles > 0); // Ready
- + data << uint32(roles); // Roles
- + plr = sObjectMgr.GetPlayer(pRoleCheck->leader);
- + if (plr)
- + data << uint8(plr->getLevel()); // Level
- + else
- + data << uint8(0);
- + }
- +}
- +
- +/// <summary>
- +/// Build and Send LFG lock player info and reward
- +/// </summary>
- +/// <param name="plr">Player</param>
- +void LFGMgr::SendLfgPlayerInfo(Player *plr)
- +{
- + uint32 rsize = 0;
- + uint32 lsize = 0;
- + LfgDungeonSet *randomlist = GetRandomDungeons(plr->getLevel(), plr->GetSession()->Expansion());
- + LfgLockStatusSet *lockSet = GetPlayerLockStatusDungeons(plr, m_DungeonsMap[LFG_ALL_DUNGEONS]);
- + if (randomlist)
- + rsize = randomlist->size();
- + if (lockSet)
- + lsize = lockSet->size();
- +
- + DEBUG_LOG("SMSG_LFG_PLAYER_INFO");
- + WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (4 + 4));
- + if (!randomlist)
- + data << uint8(0);
- + else
- + {
- + data << uint8(randomlist->size()); // Random Dungeon count
- + for (LfgDungeonSet::iterator it = randomlist->begin(); it != randomlist->end(); ++it)
- + {
- + data << uint32(*it); // Entry
- + BuildRewardBlock(data, *it, plr);
- + }
- + randomlist->clear();
- + delete randomlist;
- + }
- + BuildPlayerLockDungeonBlock(data, lockSet);
- + plr->GetSession()->SendPacket(&data);
- +}
- +
- +/// <summary>
- +/// Build and Send LFG lock party info and reward
- +/// </summary>
- +/// <param name="plr">Player</param>
- +void LFGMgr::SendLfgPartyInfo(Player *plr)
- +{
- + if (LfgLockStatusMap *lockMap = GetPartyLockStatusDungeons(plr, m_DungeonsMap[LFG_ALL_DUNGEONS]))
- + {
- + uint32 size = 0;
- + for (LfgLockStatusMap::const_iterator it = lockMap->begin(); it != lockMap->end(); ++it)
- + size += 8 + 4 + it->second->size() * (4 + 4);
- + DEBUG_LOG("SMSG_LFG_PARTY_INFO");
- + WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
- + BuildPartyLockDungeonBlock(data, lockMap);
- + plr->GetSession()->SendPacket(&data);
- + }
- +}
- +
- +/// <summary>
- +/// Build Reward packet structure for a given dungeon
- +/// </summary>
- +/// <param name="data">WorldPacket</param>
- +/// <param name="dungeon">Dungeon entry</param>
- +/// <param name="plr">Player</param>
- +void LFGMgr::BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr)
- +{
- + bool done = plr->m_lookingForGroup.isDungeonDone(dungeon);
- + LfgReward *reward = GetRandomDungeonReward(dungeon, done, plr->getLevel());
- +
- + if (!reward)
- + return;
- +
- + data << uint8(done);
- + if (data.GetOpcode() == SMSG_LFG_PLAYER_REWARD)
- + data << uint32(reward->strangers);
- + data << uint32(reward->baseMoney);
- + data << uint32(reward->baseXP);
- + data << uint32(reward->variableMoney);
- + data << uint32(reward->variableXP);
- + data << uint8(reward->itemId != 0);
- + if (reward->itemId)
- + {
- + data << uint32(reward->itemId);
- + data << uint32(reward->displayId);
- + data << uint32(reward->stackCount);
- + }
- +}
- +
- +/// <summary>
- +/// Build Party Dungeon lock status packet
- +/// </summary>
- +/// <param name="data">WorldPacket</param>
- +/// <param name="lock">lock status map</param>
- +void LFGMgr::BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap)
- +{
- + assert(lockMap);
- +
- + data << uint8(lockMap->size());
- +
- + LfgLockStatusSet *lockSet;
- + uint64 guid;
- + for (LfgLockStatusMap::const_iterator it = lockMap->begin(); it != lockMap->end(); ++it)
- + {
- + guid = it->first;
- + lockSet = it->second;
- + if (!lockSet)
- + continue;
- +
- + data << uint64(guid); // Player guid
- + BuildPlayerLockDungeonBlock(data, lockSet);
- + }
- + lockMap->clear();
- + delete lockMap;
- +}
- +
- +/// <summary>
- +/// Build Player Dungeon lock status packet
- +/// </summary>
- +/// <param name="data">WorldPacket</param>
- +/// <param name="lock">lock status list</param>
- +void LFGMgr::BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet)
- +{
- + assert(lockSet);
- + data << uint32(lockSet->size()); // Size of lock dungeons
- + for (LfgLockStatusSet::iterator it = lockSet->begin(); it != lockSet->end(); ++it)
- + {
- + data << uint32((*it)->dungeon); // Dungeon entry + type
- + data << uint32((*it)->lockstatus); // Lock status
- + delete (*it);
- + }
- + lockSet->clear();
- + delete lockSet;
- +}
- +
- +
- +
- +
- +// --------------------------------------------------------------------------//
- +// Auxiliar Functions
- +// --------------------------------------------------------------------------//
- +
- +/// <summary>
- +/// Get all Group members list of dungeons that can't be done and reason
- +/// leader excluded as the list given is he list he can do
- +/// </summary>
- +/// <param name="grp">Group</param>
- +/// <param name="dungeons">Dungeons to check</param>
- +/// <returns>LfgLockStatusMap*</returns>
- +LfgLockStatusMap* LFGMgr::GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons)
- +{
- + assert(plr);
- + assert(dungeons);
- + Group *grp = plr->GetGroup();
- + if (!grp)
- + return NULL;
- +
- + Player *plrg;
- + LfgLockStatusSet *dungeonSet = NULL;
- + LfgLockStatusMap *dungeonMap = new LfgLockStatusMap();
- + for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- + {
- + plrg = itr->getSource();
- + if (!plrg || plrg == plr)
- + continue;
- +
- + dungeonSet = GetPlayerLockStatusDungeons(plrg, dungeons);
- + if (dungeonSet)
- + (*dungeonMap)[plrg->GetGUID()] = dungeonSet;
- + }
- +
- + if (!dungeonMap->size())
- + {
- + delete dungeonMap;
- + dungeonMap = NULL;
- + }
- + return dungeonMap;
- +}
- +
- +/// <summary>
- +/// Get list of dungeons player can't do and reasons
- +/// </summary>
- +/// <param name="plr">Player</param>
- +/// <param name="dungeons">Dungeons to check</param>
- +/// <returns>LfgLockStatusSet*</returns>
- +LfgLockStatusSet* LFGMgr::GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons)
- +{
- + LfgLockStatusSet *list = new LfgLockStatusSet();
- + LfgLockStatus *lockstatus = NULL;
- + LFGDungeonEntry const *dungeon;
- + LfgLockStatusType locktype;
- + uint8 level = plr->getLevel();
- + uint8 expansion = plr->GetSession()->Expansion();
- +
- + for (LfgDungeonSet::const_iterator it = dungeons->begin(); it != dungeons->end(); ++it)
- + {
- + dungeon = sLFGDungeonStore.LookupEntry(*it);
- + assert(dungeon); // Will never happen - We provide a list from sLFGDungeonStore
- +
- + locktype = LFG_LOCKSTATUS_OK;
- + if (dungeon->expansion > expansion)
- + locktype = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION;
- + else if (dungeon->minlevel > level)
- + locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
- + else if (dungeon->maxlevel < level)
- + locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL;
- + /* TODO - Use these types when needed...
- + else if ()
- + locktype = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE;
- + else if ()
- + locktype = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE;
- + else if () // Locked due to WG, closed by GM, done daily, etc
- + locktype = LFG_LOCKSTATUS_RAID_LOCKED;
- + else if ()
- + locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL;
- + else if ()
- + locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL;
- + else if () // Need list of instances and needed quest to enter
- + locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED;
- + else if () // Need list of instances and needed key to enter
- + locktype = LFG_LOCKSTATUS_MISSING_ITEM;
- + else if () // Need list of instances and needed season to open
- + locktype = LFG_LOCKSTATUS_NOT_IN_SEASON;
- + */
- +
- + if (locktype != LFG_LOCKSTATUS_OK)
- + {
- + lockstatus = new LfgLockStatus();
- + lockstatus->dungeon = dungeon->Entry();
- + lockstatus->lockstatus = locktype;
- + list->insert(lockstatus);
- + }
- + }
- + if (!list->size())
- + {
- + delete list;
- + list = NULL;
- + }
- + return list;
- +}
- +
- +/// <summary>
- +/// Get the dungeon list that can be done.
- +/// </summary>
- +/// <returns>LfgDungeonSet*</returns>
- +LfgDungeonSet* LFGMgr::GetAllDungeons()
- +{
- + LfgDungeonSet *dungeons = new LfgDungeonSet();
- + LFGDungeonEntry const *dungeon;
- + for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
- + {
- + dungeon = sLFGDungeonStore.LookupEntry(i);
- + if (!dungeon || dungeon->type == LFG_TYPE_ZONE)
- + continue;
- + dungeons->insert(dungeon->ID);
- + }
- + if (!dungeons->size())
- + {
- + delete dungeons;
- + return NULL;
- + }
- + else
- + return dungeons;
- +}
- +
- +/// <summary>
- +/// Get the dungeon list that can be done given a random dungeon entry.
- +/// </summary>
- +/// <param name="randomdungeon">Random dungeon entry</param>
- +/// <returns>LfgDungeonSet*</returns>
- +LfgDungeonSet* LFGMgr::GetDungeonsByRandom(uint32 randomdungeon)
- +{
- + LFGDungeonEntry const *dungeon = sLFGDungeonStore.LookupEntry(randomdungeon);
- + if (!dungeon)
- + return NULL;
- +
- + uint32 grouptype = dungeon->grouptype;
- + LfgDungeonSet *random = new LfgDungeonSet();
- + for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
- + {
- + dungeon = sLFGDungeonStore.LookupEntry(i);
- + if (!dungeon || dungeon->type == LFG_TYPE_RANDOM || dungeon->grouptype != grouptype)
- + continue;
- + random->insert(dungeon->ID);
- + }
- + if (!random->size())
- + {
- + delete random;
- + return NULL;
- + }
- + else
- + return random;
- +}
- +
- +/// <summary>
- +/// Get the random dungeon list that can be done at a certain level and expansion.
- +/// </summary>
- +/// <param name="level">Player level</param>
- +/// <param name="expansion">Player account expansion</param>
- +/// <returns>LfgDungeonSet*</returns>
- +LfgDungeonSet* LFGMgr::GetRandomDungeons(uint8 level, uint8 expansion)
- +{
- + LfgDungeonSet *list = new LfgDungeonSet();
- + LFGDungeonEntry const *dungeon;
- + for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
- + {
- + dungeon = sLFGDungeonStore.LookupEntry(i);
- + if (dungeon && dungeon->expansion <= expansion && dungeon->type == LFG_TYPE_RANDOM &&
- + dungeon->minlevel <= level && level <= dungeon->maxlevel)
- + list->insert(dungeon->Entry());
- + }
- + return list;
- +}
- +
- +/// <summary>
- +/// Get the reward of a given random dungeon
- +/// </summary>
- +/// <param name="dungeon">random dungeon id</param>
- +/// <param name="done">Dungeon previously done</param>
- +/// <returns></returns>
- +LfgReward* LFGMgr::GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level)
- +{
- + uint8 index = 0;
- + switch((dungeon & 0x00FFFFFF)) // Get dungeon id from dungeon entry
- + {
- + case LFG_RANDOM_CLASSIC:
- + if (level < 15)
- + index = LFG_REWARD_LEVEL0;
- + else if (level < 24)
- + index = LFG_REWARD_LEVEL1;
- + else if (level < 35)
- + index = LFG_REWARD_LEVEL2;
- + else if (level < 46)
- + index = LFG_REWARD_LEVEL3;
- + else if (level < 56)
- + index = LFG_REWARD_LEVEL4;
- + else
- + index = LFG_REWARD_LEVEL5;
- + break;
- + case LFG_RANDOM_BC_NORMAL:
- + index = LFG_REWARD_BC_NORMAL;
- + break;
- + case LFG_RANDOM_BC_HEROIC:
- + index = LFG_REWARD_BC_HEROIC;
- + break;
- + case LFG_RANDOM_LK_NORMAL:
- + index = level == 80 ? LFG_REWARD_LK_NORMAL80 : LFG_REWARD_LK_NORMAL;
- + break;
- + case LFG_RANDOM_LK_HEROIC:
- + index = LFG_REWARD_LK_HEROIC;
- + break;
- + default: // This should never happen!
- + done = false;
- + index = LFG_REWARD_LEVEL0;
- + sLog.outError("LFGMgr::GetRandomDungeonReward: Dungeon %u is not random dungeon!", dungeon);
- + break;
- + }
- + return done ? m_RewardDoneList.at(index) : m_RewardList.at(index);
- +}
- +
- +/// <summary>
- +/// Given a Dungeon id returns the dungeon Group Type
- +/// </summary>
- +/// <param name="dungeonId">Dungeon id</param>
- +/// <returns>uint8: GroupType</returns>
- +uint8 LFGMgr::GetDungeonGroupType(uint32 dungeonId)
- +{
- + LFGDungeonEntry const *dungeon = sLFGDungeonStore.LookupEntry(dungeonId);
- + if (!dungeon)
- + return 0;
- +
- + return dungeon->grouptype;
- +}
- diff --git a/src/game/LFGMgr.h b/src/game/LFGMgr.h
- new file mode 100644
- index 0000000..cddc74f
- --- /dev/null
- +++ b/src/game/LFGMgr.h
- @@ -0,0 +1,261 @@
- +#ifndef _LFGMGR_H
- +#define _LFGMGR_H
- +
- +#include "Common.h"
- +#include "Policies/Singleton.h"
- +#include "Group.h"
- +#include "LFG.h"
- +
- +enum LFGenum
- +{
- + LFG_TIME_ROLECHECK = 2*MINUTE,
- + LFG_TANKS_NEEDED = 1,
- + LFG_HEALERS_NEEDED = 1,
- + LFG_DPS_NEEDED = 3,
- + LFG_QUEUEUPDATE_INTERVAL = 15000,
- + LFG_SPELL_COOLDOWN = 71328,
- + LFG_SPELL_DESERTER = 71041,
- +};
- +
- +enum LfgType
- +{
- + LFG_TYPE_DUNGEON = 1,
- + LFG_TYPE_RAID = 2,
- + LFG_TYPE_QUEST = 3,
- + LFG_TYPE_ZONE = 4,
- + LFG_TYPE_HEROIC = 5,
- + LFG_TYPE_RANDOM = 6,
- +};
- +
- +enum LfgGroupType
- +{
- + LFG_GROUPTYPE_CLASSIC = 1,
- + LFG_GROUPTYPE_BC_NORMAL = 2,
- + LFG_GROUPTYPE_BC_HEROIC = 3,
- + LFG_GROUPTYPE_WTLK_NORMAL = 4,
- + LFG_GROUPTYPE_WTLK_HEROIC = 5,
- + LFG_GROUPTYPE_CLASSIC_RAID = 6,
- + LFG_GROUPTYPE_BC_RAID = 7,
- + LFG_GROUPTYPE_WTLK_RAID_10 = 8,
- + LFG_GROUPTYPE_WTLK_RAID_25 = 9,
- +};
- +
- +enum LfgLockStatusType
- +{
- + LFG_LOCKSTATUS_OK = 0, // Internal use only
- + LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION = 1,
- + LFG_LOCKSTATUS_TOO_LOW_LEVEL = 2,
- + LFG_LOCKSTATUS_TOO_HIGH_LEVEL = 3,
- + LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE = 4,
- + LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE = 5,
- + LFG_LOCKSTATUS_RAID_LOCKED = 6,
- + LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL = 1001,
- + LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL = 1002,
- + LFG_LOCKSTATUS_QUEST_NOT_COMPLETED = 1022,
- + LFG_LOCKSTATUS_MISSING_ITEM = 1025,
- + LFG_LOCKSTATUS_NOT_IN_SEASON = 1031,
- +};
- +
- +enum LfgJoinResult
- +{
- + LFG_JOIN_OK = 0, // Joined (no client msg)
- + LFG_JOIN_FAILED = 1, // RoleCheck Failed
- + LFG_JOIN_GROUPFULL = 2, // Your group is full
- + LFG_JOIN_UNK3 = 3, // No client reaction
- + LFG_JOIN_INTERNAL_ERROR = 4, // Internal LFG Error
- + LFG_JOIN_NOT_MEET_REQS = 5, // You do not meet the requirements for the chosen dungeons
- + LFG_JOIN_PARTY_NOT_MEET_REQS = 6, // One or more party members do not meet the requirements for the chosen dungeons
- + LFG_JOIN_MIXED_RAID_DUNGEON = 7, // You cannot mix dungeons, raids, and random when picking dungeons
- + LFG_JOIN_MULTI_REALM = 8, // The dungeon you chose does not support players from multiple realms
- + LFG_JOIN_DISCONNECTED = 9, // One or more party members are pending invites or disconnected
- + LFG_JOIN_PARTY_INFO_FAILED = 10, // Could not retrieve information about some party members
- + LFG_JOIN_DUNGEON_INVALID = 11, // One or more dungeons was not valid
- + LFG_JOIN_DESERTER = 12, // You can not queue for dungeons until your deserter debuff wears off
- + LFG_JOIN_PARTY_DESERTER = 13, // One or more party members has a deserter debuff
- + LFG_JOIN_RANDOM_COOLDOWN = 14, // You can not queue for random dungeons while on random dungeon cooldown
- + LFG_JOIN_PARTY_RANDOM_COOLDOWN = 15, // One or more party members are on random dungeon cooldown
- + LFG_JOIN_TOO_MUCH_MEMBERS = 16, // You can not enter dungeons with more that 5 party members
- + LFG_JOIN_USING_BG_SYSTEM = 17, // You can not use the dungeon system while in BG or arenas
- + LFG_JOIN_FAILED2 = 18, // RoleCheck Failed
- +};
- +
- +enum LfgRoleCheckResult
- +{
- + LFG_ROLECHECK_FINISHED = 1, // Role check finished
- + LFG_ROLECHECK_INITIALITING = 2, // Role check begins
- + LFG_ROLECHECK_MISSING_ROLE = 3, // Someone didn't selected a role after 2 mins
- + LFG_ROLECHECK_WRONG_ROLES = 4, // Can't form a group with that role selection
- + LFG_ROLECHECK_ABORTED = 5, // Someone leave the group
- + LFG_ROLECHECK_NO_ROLE = 6, // Someone selected no role
- +};
- +
- +enum LfgRandomDungeonEntries
- +{
- + LFG_ALL_DUNGEONS = 0,
- + LFG_RANDOM_CLASSIC = 258,
- + LFG_RANDOM_BC_NORMAL = 259,
- + LFG_RANDOM_BC_HEROIC = 260,
- + LFG_RANDOM_LK_NORMAL = 261,
- + LFG_RANDOM_LK_HEROIC = 262,
- +};
- +
- +enum LfgRewardEnums
- +{
- + LFG_REWARD_LEVEL0 = 10,
- + LFG_REWARD_LEVEL1 = 0,
- + LFG_REWARD_LEVEL2 = 1,
- + LFG_REWARD_LEVEL3 = 2,
- + LFG_REWARD_LEVEL4 = 3,
- + LFG_REWARD_LEVEL5 = 4,
- + LFG_REWARD_BC_NORMAL = 5,
- + LFG_REWARD_BC_HEROIC = 6,
- + LFG_REWARD_LK_NORMAL = 7,
- + LFG_REWARD_LK_NORMAL80 = 7,
- + LFG_REWARD_LK_HEROIC = 8,
- + LFG_REWARD_DATA_SIZE = 10,
- +};
- +
- +const uint32 RewardDungeonData[LFG_REWARD_DATA_SIZE+1][5] =
- +{ // XP, money, item, item display, count
- + {310, 3500, 51999, 56915, 1}, // Classic 15-23
- + {470, 7000, 52000, 56915, 1}, // Classic 24-34
- + {825, 13000, 52001, 56915, 1}, // Classic 35-45
- + {12250, 16500, 52002, 56915, 1}, // Classic 46-55
- + {14300, 18000, 52003, 56915, 1}, // Classic 56-60
- + {1600, 62000, 52004, 56915, 1}, // BC Normal
- + {1900, 88000, 52005, 56915, 1}, // BC Heroic
- + {33100, 148000, 47241, 62232, 2}, // LK Normal
- + {0, 198600, 47241, 62232, 2}, // LK Normal - Level 80
- + {0, 264600, 49426, 64062, 2}, // LK Heroic
- + {0, 0, 0, 0, 0}, // Classic - No level
- +};
- +
- +const uint32 RewardDungeonDoneData[LFG_REWARD_DATA_SIZE][5] =
- +{ // XP, money, item, item display, count
- + {200, 1800, 51999, 56915, 1}, // Classic 15-23
- + {310, 3500, 52000, 56915, 1}, // Classic 24-34
- + {550, 6500, 52001, 56915, 1}, // Classic 35-45
- + {8150, 8500, 52002, 56915, 1}, // Classic 46-55
- + {9550, 9000, 52003, 56915, 1}, // Classic 56-60
- + {1100, 31000, 52004, 56915, 1}, // BC Normal
- + {12650, 44000, 52005, 56915, 1}, // BC Heroic
- + {16550, 74000, 0, 0, 0}, // LK Normal
- + {0, 99300, 0, 0, 0}, // LK Normal - Level 80
- + {0, 132300, 47241, 62232, 2}, // LK Heroic
- +};
- +
- +// Dungeon and reason why player can't join
- +struct LfgLockStatus
- +{
- + uint32 dungeon;
- + LfgLockStatusType lockstatus;
- +};
- +
- +// Reward info
- +struct LfgReward
- +{
- + uint32 strangers;
- + uint32 baseMoney;
- + uint32 baseXP;
- + uint32 variableMoney;
- + uint32 variableXP;
- + uint32 itemId;
- + uint32 displayId;
- + uint32 stackCount;
- +};
- +
- +typedef std::set<LfgLockStatus*> LfgLockStatusSet;
- +typedef std::vector<LfgReward*> LfgRewardList;
- +typedef std::map<uint64, LfgLockStatusSet*> LfgLockStatusMap;
- +typedef std::map<uint32, LfgDungeonSet*> LfgDungeonMap;
- +
- +typedef std::map<uint64, int8> LfgAnswerMap;
- +typedef std::map<uint64, uint8> LfgRolesMap;
- +typedef std::set<uint64> LfgGuidSet;
- +
- +// Stores player or group queue info
- +struct LfgQueueInfo
- +{
- + time_t joinTime; // Player queue join time (to calculate wait times)
- + uint32 dungeonId; // Selected Player/Group Dungeon
- + LfgRolesMap roles; // Selected Player Role/s
- + uint8 tanks; // Tanks needed
- + uint8 healers; // Healers needed
- + uint8 dps; // Dps needed
- +};
- +
- +// Stores all rolecheck info of a group that wants to join LFG
- +struct LfgRoleCheck
- +{
- + time_t cancelTime;
- + LfgRolesMap roles;
- + LfgRoleCheckResult result;
- + LfgDungeonSet dungeons;
- + uint64 leader;
- +};
- +
- +typedef std::map<uint64, LfgQueueInfo*> LfgQueueInfoMap;
- +typedef std::map<uint32, LfgRoleCheck*> LfgRoleCheckMap;
- +
- +class LFGQueue
- +{
- + public:
- + LFGQueue();
- + ~LFGQueue();
- +
- + void Update();
- + void AddToQueue(uint64 guid, LfgQueueInfo *pqInfo);
- + bool RemoveFromQueue(uint64 guid);
- + LfgQueueInfo* GetQueueInfo(uint64 guid);
- + private:
- + LfgQueueInfoMap m_LfgQueue;
- + int32 avgWaitTime;
- + int32 waitTimeTanks;
- + int32 waitTimeHealer;
- + int32 waitTimeDps;
- +};
- +
- +typedef std::map<uint8, LFGQueue *> LFGQueueMap;
- +
- +class LFGMgr
- +{
- +public:
- + LFGMgr();
- + ~LFGMgr();
- +
- + void InitLFG();
- + void SendLfgPlayerInfo(Player *plr);
- + void SendLfgPartyInfo(Player *plr);
- + void Join(Player *plr);
- + void Leave(Player *plr, Group *grp = NULL);
- + void UpdateRoleCheck(Group *grp, Player *plr = NULL);
- + void Update(uint32 diff);
- +
- +private:
- + void BuildLfgRoleCheck(WorldPacket &data, LfgRoleCheck *pRoleCheck);
- + void BuildAvailableRandomDungeonList(WorldPacket &data, Player *plr);
- + void BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr);
- + void BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet);
- + void BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap);
- + bool CheckGroupRoles(LfgRolesMap &groles);
- +
- + LfgLockStatusMap* GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons);
- + LfgLockStatusSet* GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons);
- + LfgDungeonSet* GetRandomDungeons(uint8 level, uint8 expansion);
- + LfgDungeonSet* GetDungeonsByRandom(uint32 randomdungeon);
- + LfgDungeonSet* GetAllDungeons();
- + LfgReward* GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level);
- + uint8 GetDungeonGroupType(uint32 dungeon);
- +
- + LfgRewardList m_RewardList;
- + LfgRewardList m_RewardDoneList;
- + LfgDungeonMap m_DungeonsMap;
- +
- + LFGQueueMap m_Queues;
- + LfgRoleCheckMap m_RoleChecks;
- + uint32 m_QueueTimer;
- + bool m_update;
- +};
- +
- +#define sLFGMgr MaNGOS::Singleton<LFGMgr>::Instance()
- +#endif
- diff --git a/src/game/Makefile.am b/src/game/Makefile.am
- index 575b4c0..cb2a398 100644
- --- a/src/game/Makefile.am
- +++ b/src/game/Makefile.am
- @@ -170,7 +170,10 @@ libmangosgame_a_SOURCES =
- Level1.cpp
- Level2.cpp
- Level3.cpp
- + LFG.h
- LFGHandler.cpp
- + LFGMgr.cpp
- + LFGMgr.h
- LootHandler.cpp
- LootMgr.cpp
- LootMgr.h
- diff --git a/src/game/ObjectGuid.cpp b/src/game/ObjectGuid.cpp
- index b8a41f0..f0aceaf 100644
- --- a/src/game/ObjectGuid.cpp
- +++ b/src/game/ObjectGuid.cpp
- @@ -37,6 +37,7 @@ char const* ObjectGuid::GetTypeName(HighGuid high)
- case HIGHGUID_DYNAMICOBJECT:return "DynObject";
- case HIGHGUID_CORPSE: return "Corpse";
- case HIGHGUID_MO_TRANSPORT: return "MoTransport";
- + case HIGHGUID_GROUP: return "Group";
- default:
- return "<unknown>";
- }
- @@ -105,3 +106,4 @@ template uint32 ObjectGuidGenerator<HIGHGUID_PET>::Generate();
- template uint32 ObjectGuidGenerator<HIGHGUID_VEHICLE>::Generate();
- template uint32 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT>::Generate();
- template uint32 ObjectGuidGenerator<HIGHGUID_CORPSE>::Generate();
- +template uint32 ObjectGuidGenerator<HIGHGUID_GROUP>::Generate();
- diff --git a/src/game/ObjectGuid.h b/src/game/ObjectGuid.h
- index 777e753..a07ef80 100644
- --- a/src/game/ObjectGuid.h
- +++ b/src/game/ObjectGuid.h
- @@ -70,6 +70,7 @@ enum HighGuid
- HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100/F500
- HIGHGUID_CORPSE = 0xF500, // blizz F100/F500 used second variant to resolve conflict with HIGHGUID_DYNAMICOBJECT
- HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
- + HIGHGUID_GROUP = 0x1F50,
- };
- //*** Must be replaced by ObjectGuid use ***
- @@ -95,6 +96,7 @@ inline bool IsGuidHaveEnPart(uint64 const& guid)
- case HIGHGUID_DYNAMICOBJECT:
- case HIGHGUID_CORPSE:
- case HIGHGUID_MO_TRANSPORT:
- + case HIGHGUID_GROUP:
- return false;
- case HIGHGUID_GAMEOBJECT:
- case HIGHGUID_TRANSPORT:
- @@ -170,6 +172,7 @@ class MANGOS_DLL_SPEC ObjectGuid
- bool IsCorpse() const { return GetHigh() == HIGHGUID_CORPSE; }
- bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; }
- bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; }
- + bool IsGroup() const { return GetHigh() == HIGHGUID_GROUP; }
- static TypeID GetTypeId(HighGuid high)
- {
- @@ -211,6 +214,7 @@ class MANGOS_DLL_SPEC ObjectGuid
- case HIGHGUID_DYNAMICOBJECT:
- case HIGHGUID_CORPSE:
- case HIGHGUID_MO_TRANSPORT:
- + case HIGHGUID_GROUP:
- return false;
- case HIGHGUID_GAMEOBJECT:
- case HIGHGUID_TRANSPORT:
- diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
- index 9874aec..3251b5f 100644
- --- a/src/game/ObjectMgr.cpp
- +++ b/src/game/ObjectMgr.cpp
- @@ -5835,6 +5835,8 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
- return m_GameobjectGuids.Generate();
- case HIGHGUID_CORPSE:
- return m_CorpseGuids.Generate();
- + case HIGHGUID_GROUP:
- + return m_GroupIds.Generate();
- default:
- ASSERT(0);
- }
- diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
- index 6c26ded..e2c12e8 100644
- --- a/src/game/Opcodes.cpp
- +++ b/src/game/Opcodes.cpp
- @@ -537,8 +537,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
- /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FD*/ { "CMSG_PLAYER_DIFFICULTY_CHANGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
- - /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
- + /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- + /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
- /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- @@ -888,8 +888,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
- /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgLeaveOpcode },
- - /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgJoinOpcode },
- - /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgLeaveOpcode },
- + /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- + /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- @@ -900,14 +900,14 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
- /*0x367*/ { "SMSG_LFG_UPDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x368*/ { "SMSG_LFG_UPDATE_PARTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x369*/ { "SMSG_LFG_UPDATE_SEARCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_NEVER, &WorldSession::Handle_NULL },
- - /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_NEVER, &WorldSession::Handle_NULL },
- - /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_NEVER, &WorldSession::Handle_NULL },
- + /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRolesOpcode },
- + /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- + /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- /*0x36D*/ { "SMSG_LFG_BOOT_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- + /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode },
- /*0x36F*/ { "SMSG_LFG_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- - /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- + /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- + /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLfgPartyLockInfoRequestOpcode },
- /*0x372*/ { "SMSG_LFG_PARTY_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleSetTitleOpcode },
- @@ -1234,7 +1234,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
- /*0x4B5*/ { "SMSG_ITEM_REFUND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseMapPositionQuery },
- /*0x4B7*/ { "SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- - /*0x4B8*/ { "CMSG_LFG_SET_ROLES_2", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRoles },
- + /*0x4B8*/ { "CMSG_LFG_SET_ROLES_2", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- /*0x4B9*/ { "UMSG_UNKNOWN_1209", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4BA*/ { "CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4BB*/ { "SMSG_CALENDAR_ACTION_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- diff --git a/src/game/Player.h b/src/game/Player.h
- index 047bccf..e0eb788 100644
- --- a/src/game/Player.h
- +++ b/src/game/Player.h
- @@ -37,6 +37,7 @@
- #include "ReputationMgr.h"
- #include "BattleGround.h"
- #include "DBCEnums.h"
- +#include "LFG.h"
- #include<string>
- #include<vector>
- @@ -394,74 +395,6 @@ struct EnchantDuration
- typedef std::list<EnchantDuration> EnchantDurationList;
- typedef std::list<Item*> ItemDurationList;
- -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
- -};
- -
- -enum LfgRoles
- -{
- - LEADER = 0x01,
- - TANK = 0x02,
- - HEALER = 0x04,
- - DAMAGE = 0x08
- -};
- -
- -struct LookingForGroupSlot
- -{
- - LookingForGroupSlot() : entry(0), type(0) {}
- - bool Empty() const { return !entry && !type; }
- - void Clear() { entry = 0; type = 0; }
- - void Set(uint32 _entry, uint32 _type ) { entry = _entry; type = _type; }
- - bool Is(uint32 _entry, uint32 _type) const { return entry == _entry && type == _type; }
- - bool canAutoJoin() const { return entry && (type == LFG_TYPE_DUNGEON || type == LFG_TYPE_HEROIC_DUNGEON); }
- -
- - uint32 entry;
- - uint32 type;
- -};
- -
- -#define MAX_LOOKING_FOR_GROUP_SLOT 3
- -
- -struct LookingForGroup
- -{
- - LookingForGroup() {}
- - bool HaveInSlot(LookingForGroupSlot const& slot) const { return HaveInSlot(slot.entry, slot.type); }
- - bool HaveInSlot(uint32 _entry, uint32 _type) const
- - {
- - for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- - if(slots[i].Is(_entry, _type))
- - return true;
- - return false;
- - }
- -
- - bool canAutoJoin() const
- - {
- - for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- - if(slots[i].canAutoJoin())
- - return true;
- - return false;
- - }
- -
- - bool Empty() const
- - {
- - for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- - if(!slots[i].Empty())
- - return false;
- - return more.Empty();
- - }
- -
- - LookingForGroupSlot slots[MAX_LOOKING_FOR_GROUP_SLOT];
- - LookingForGroupSlot more;
- - std::string comment;
- - uint8 roles;
- -};
- -
- enum RaidGroupError
- {
- ERR_RAID_GROUP_NONE = 0,
- diff --git a/src/game/World.cpp b/src/game/World.cpp
- index e59d07d..9ddb0c4 100644
- --- a/src/game/World.cpp
- +++ b/src/game/World.cpp
- @@ -62,6 +62,7 @@
- #include "GMTicketMgr.h"
- #include "Util.h"
- #include "CharacterDatabaseCleaner.h"
- +#include "LFGMgr.h"
- INSTANTIATE_SINGLETON_1( World );
- @@ -1194,6 +1195,10 @@ void World::SetInitialWorldSettings()
- sLog.outString( "Loading GM tickets...");
- sTicketMgr.LoadGMTickets();
- + ///- Initialize Looking For Group
- + sLog.outString("Starting Looking For Group System");
- + sLFGMgr.InitLFG();
- +
- ///- Handle outdated emails (delete/return)
- sLog.outString( "Returning old mails..." );
- sObjectMgr.ReturnOrDeleteOldMails(false);
- @@ -1452,6 +1457,8 @@ void World::Update(uint32 diff)
- Player::DeleteOldCharacters();
- }
- + sLFGMgr.Update(diff);
- +
- // execute callbacks from sql queries that were queued recently
- UpdateResultQueue();
- diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
- index 8a8b383..2e5d27b 100644
- --- a/src/game/WorldSession.cpp
- +++ b/src/game/WorldSession.cpp
- @@ -38,6 +38,7 @@
- #include "Auth/AuthCrypt.h"
- #include "Auth/HMACSHA1.h"
- #include "zlib/zlib.h"
- +#include "LFGMgr.h"
- /// WorldSession constructor
- WorldSession::WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
- @@ -289,6 +290,11 @@ void WorldSession::LogoutPlayer(bool Save)
- if (_player)
- {
- + sLFGMgr.Leave(_player);
- + GetPlayer()->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + GetPlayer()->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
- + GetPlayer()->GetSession()->SendLfgUpdateSearch(false);
- +
- sLog.outChar("Account: %d (IP: %s) Logout Character:[%s] (guid: %u)", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName() ,_player->GetGUIDLow());
- if (uint64 lguid = GetPlayer()->GetLootGUID())
- diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
- index af857e2..9b14df5 100644
- --- a/src/game/WorldSession.h
- +++ b/src/game/WorldSession.h
- @@ -161,8 +161,6 @@ class MANGOS_DLL_SPEC WorldSession
- void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
- void SendNotification(int32 string_id,...);
- void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName);
- - void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
- - void SendLfgUpdate(uint8 unk1, uint8 unk2, uint8 unk3);
- void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
- void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
- void SendSetPhaseShift(uint32 phaseShift);
- @@ -677,19 +675,9 @@ class MANGOS_DLL_SPEC WorldSession
- void HandleMinimapPingOpcode(WorldPacket& recv_data);
- void HandleRandomRollOpcode(WorldPacket& recv_data);
- void HandleFarSightOpcode(WorldPacket& recv_data);
- - void HandleSetLfgOpcode(WorldPacket& recv_data);
- void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data);
- void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data);
- void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data);
- - void HandleLfgJoinOpcode(WorldPacket& recv_data);
- - void HandleLfgLeaveOpcode(WorldPacket& recv_data);
- - void HandleSearchLfgJoinOpcode(WorldPacket& recv_data);
- - void HandleSearchLfgLeaveOpcode(WorldPacket& recv_data);
- - void HandleLfgClearOpcode(WorldPacket& recv_data);
- - void HandleLfmClearOpcode(WorldPacket& recv_data);
- - void HandleSetLfmOpcode(WorldPacket& recv_data);
- - void HandleSetLfgCommentOpcode(WorldPacket& recv_data);
- - void HandleLfgSetRoles(WorldPacket& recv_data);
- void HandleSetTitleOpcode(WorldPacket& recv_data);
- void HandleRealmSplitOpcode(WorldPacket& recv_data);
- void HandleTimeSyncResp(WorldPacket& recv_data);
- @@ -697,6 +685,20 @@ class MANGOS_DLL_SPEC WorldSession
- void HandleResetInstancesOpcode(WorldPacket& recv_data);
- void HandleHearthandResurrect(WorldPacket & recv_data);
- + // Looking for Dungeon/Raid
- + void HandleSetLfgCommentOpcode(WorldPacket & recv_data);
- + void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recv_data);
- + void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recv_data);
- + void HandleLfgJoinOpcode(WorldPacket &recv_data);
- + void HandleLfgLeaveOpcode(WorldPacket & /*recv_data*/);
- + void HandleLfgSetRolesOpcode(WorldPacket &recv_data);
- + void SendLfgUpdatePlayer(uint8 updateType);
- + void SendLfgUpdateParty(uint8 updateType);
- + void SendLfgRoleChosen(uint64 guid, uint8 roles);
- + void SendLfgUpdateSearch(bool update);
- + void SendLfgJoinResult(uint8 checkResult, uint8 checkValue);
- + void SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps);
- +
- // Arena Team
- void HandleInspectArenaTeamsOpcode(WorldPacket& recv_data);
- void HandleArenaTeamQueryOpcode(WorldPacket& recv_data);
- diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj
- index 44858d5..5559b6a 100644
- --- a/win/VC100/game.vcxproj
- +++ b/win/VC100/game.vcxproj
- @@ -421,6 +421,7 @@
- <ClCompile Include="..\..\src\game\Level2.cpp" />
- <ClCompile Include="..\..\src\game\Level3.cpp" />
- <ClCompile Include="..\..\src\game\LFGHandler.cpp" />
- + <ClCompile Include="..\..\src\game\LFGMgr.cpp" />
- <ClCompile Include="..\..\src\game\LootHandler.cpp" />
- <ClCompile Include="..\..\src\game\LootMgr.cpp" />
- <ClCompile Include="..\..\src\game\Mail.cpp" />
- @@ -568,6 +569,8 @@
- <ClInclude Include="..\..\src\game\ItemEnchantmentMgr.h" />
- <ClInclude Include="..\..\src\game\ItemPrototype.h" />
- <ClInclude Include="..\..\src\game\Language.h" />
- + <ClInclude Include="..\..\src\game\LFG.h" />
- + <ClInclude Include="..\..\src\game\LFGMgr.h" />
- <ClInclude Include="..\..\src\game\LootMgr.h" />
- <ClInclude Include="..\..\src\game\Mail.h" />
- <ClInclude Include="..\..\src\game\Map.h" />
- diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters
- index 804e667..97cb4a6 100644
- --- a/win/VC100/game.vcxproj.filters
- +++ b/win/VC100/game.vcxproj.filters
- @@ -150,6 +150,9 @@
- <ClCompile Include="..\..\src\game\LFGHandler.cpp">
- <Filter>World/Handlers</Filter>
- </ClCompile>
- + <ClCompile Include="..\..\src\game\LFGMgr.cpp">
- + <Filter>World/Handlers</Filter>
- + </ClCompile>
- <ClCompile Include="..\..\src\game\LootHandler.cpp">
- <Filter>World/Handlers</Filter>
- </ClCompile>
- @@ -543,6 +546,12 @@
- <ClInclude Include="..\..\src\game\InstanceSaveMgr.h">
- <Filter>World/Handlers</Filter>
- </ClInclude>
- + <ClInclude Include="..\..\src\game\LFG.h">
- + <Filter>World/Handlers</Filter>
- + </ClInclude>
- + <ClInclude Include="..\..\src\game\LFGMgr.h">
- + <Filter>World/Handlers</Filter>
- + </ClInclude>
- <ClInclude Include="..\..\src\game\Mail.h">
- <Filter>World/Handlers</Filter>
- </ClInclude>
- diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj
- index 8f1c431..20d9369 100644
- --- a/win/VC80/game.vcproj
- +++ b/win/VC80/game.vcproj
- @@ -818,10 +818,22 @@
- >
- </File>
- <File
- + RelativePath="..\..\src\game\LFG.h"
- + >
- + </File>
- + <File
- RelativePath="..\..\src\game\LFGHandler.cpp"
- >
- </File>
- <File
- + RelativePath="..\..\src\game\LFGMgr.cpp"
- + >
- + </File>
- + <File
- + RelativePath="..\..\src\game\LFGMgr.h"
- + >
- + </File>
- + <File
- RelativePath="..\..\src\game\LootHandler.cpp"
- >
- </File>
- diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
- index 1eb6872..0a6f0eb 100644
- --- a/win/VC90/game.vcproj
- +++ b/win/VC90/game.vcproj
- @@ -811,10 +811,22 @@
- >
- </File>
- <File
- + RelativePath="..\..\src\game\LFG.h"
- + >
- + </File>
- + <File
- RelativePath="..\..\src\game\LFGHandler.cpp"
- >
- </File>
- <File
- + RelativePath="..\..\src\game\LFGMgr.cpp"
- + >
- + </File>
- + <File
- + RelativePath="..\..\src\game\LFGMgr.h"
- + >
- + </File>
- + <File
- RelativePath="..\..\src\game\LootHandler.cpp"
- >
- </File>
- --
- 1.7.0.2.msysgit.0 [/PHP]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement