From 070c35278c9270b800815687610222528a32f1f2 Mon Sep 17 00:00:00 2001 From: killerwife Date: Fri, 6 Sep 2024 14:50:04 +0200 Subject: [PATCH] More WIP --- src/game/Entities/Player.h | 3 ++ src/game/LFG/LFGDefines.h | 8 ++++ src/game/LFG/LFGHandler.cpp | 72 +++++++++++++++++++++------------- src/game/LFG/LFGQueue.cpp | 42 ++++++++++++++++++++ src/game/LFG/LFGQueue.h | 5 +++ src/game/Server/WorldSession.h | 3 -- 6 files changed, 103 insertions(+), 30 deletions(-) diff --git a/src/game/Entities/Player.h b/src/game/Entities/Player.h index 13ffafe085..c807eee271 100644 --- a/src/game/Entities/Player.h +++ b/src/game/Entities/Player.h @@ -41,6 +41,7 @@ #include "Server/SQLStorages.h" #include "Loot/LootMgr.h" #include "Cinematics/CinematicMgr.h" +#include "LFG/LFGDefines.h" #include #include @@ -2132,6 +2133,8 @@ class Player : public Unit void RemoveAtLoginFlag(AtLoginFlags f, bool in_db_also = false); static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create = false); + LfgPlayerInfo m_lfgInfo; + // Temporarily removed pet cache uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; } void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; } diff --git a/src/game/LFG/LFGDefines.h b/src/game/LFG/LFGDefines.h index b4f52fc0df..1b3feae853 100644 --- a/src/game/LFG/LFGDefines.h +++ b/src/game/LFG/LFGDefines.h @@ -41,4 +41,12 @@ enum class MeetingstoneFailedStatus : uint8 MEETINGSTONE_FAIL_RAID_GROUP = 3, }; +struct LfgPlayerInfo +{ + std::string comment; + bool autojoin; + bool autofill; + bool queued; // cached async information +}; + #endif \ No newline at end of file diff --git a/src/game/LFG/LFGHandler.cpp b/src/game/LFG/LFGHandler.cpp index 36a4d3e464..f239aa74fb 100644 --- a/src/game/LFG/LFGHandler.cpp +++ b/src/game/LFG/LFGHandler.cpp @@ -21,23 +21,11 @@ #include "Log/Log.h" #include "World/World.h" #include "LFG/LFGDefines.h" +#include "LFG/LFGQueue.h" static inline const Player* LookingForGroupGetCurrentLeader(Player* _this) { - if (Group* group = _this->GetGroup()) - { - if (!group->IsBattleGroup() && !group->IsFull() && !group->IsLeader(_this->GetObjectGuid())) - { - for (const GroupReference* itr = group->GetFirstMember(); itr; itr = itr->next()) - { - if (Player* member = itr->getSource()) - { - if (group->IsLeader(member->GetObjectGuid())) - return member; - } - } - } - } + return _this; } @@ -364,7 +352,7 @@ void WorldSession::HandleLfgSetAutoJoinOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFG_SET_AUTOJOIN"); - LookingForGroup_auto_join = true; + _player->m_lfgInfo.autojoin = true; if (!_player) // needed because STATUS_AUTHED return; @@ -376,7 +364,7 @@ void WorldSession::HandleLfgClearAutoJoinOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFG_CLEAR_AUTOJOIN"); - LookingForGroup_auto_join = false; + _player->m_lfgInfo.autojoin = false; LookingForGroupSetAutoJoin(_player, _player->GetSession(), false); } @@ -385,7 +373,7 @@ void WorldSession::HandleLfmSetAutoFillOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFM_SET_AUTOFILL"); - LookingForGroup_auto_add = true; + _player->m_lfgInfo.autofill = true; if (!_player) // needed because STATUS_AUTHED return; @@ -397,7 +385,7 @@ void WorldSession::HandleLfmClearAutoFillOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFM_CLEAR_AUTOFILL"); - LookingForGroup_auto_add = false; + _player->m_lfgInfo.autofill = false; LookingForGroupSetAutoFill(_player, _player->GetSession(), false); } @@ -406,6 +394,15 @@ void WorldSession::HandleLfgClearOpcode(WorldPacket& /*recv_data */) { DEBUG_LOG("CMSG_CLEAR_LOOKING_FOR_GROUP"); + ObjectGuid leaderGuid = _player->GetObjectGuid(); + if (Group* group = _player->GetGroup()) + leaderGuid = group->GetLeaderGuid(); + + sWorld.GetLFGQueue().GetMessager().AddMessage([leaderGuid, playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + { + queue->StopLookingForGroup(leaderGuid, playerGuid); + }); + LookingForGroupClearLFG(_player, this); } @@ -420,26 +417,47 @@ void WorldSession::HandleSetLfgOpcode(WorldPacket& recv_data) if (slot >= MAX_LOOKING_FOR_GROUP_SLOT) return; + LFGPlayerQueueInfo info; + + const Player* pov = _player; if (Group* _group = _player->GetGroup()) { - const Player* pov = LookingForGroupGetCurrentLeader(_player); - - if (pov != _player && pov->m_lookingForGroup.isLFM()) + if (Group* group = _player->GetGroup()) { - WorldPacket data(SMSG_LFG_LEADER_IS_LFM); - SendPacket(data); - return; + if (!group->IsBattleGroup() && !group->IsFull() && !group->IsLeader(_player->GetObjectGuid())) + { + for (const GroupReference* itr = group->GetFirstMember(); itr; itr = itr->next()) + { + if (Player* member = itr->getSource()) + { + if (group->IsLeader(member->GetObjectGuid())) + { + pov = member; + } + else + { + info.members.push_back(LFGGroupQueueInfo(member->GetObjectGuid(), member->GetLevel())); + } + } + } + } } - SendLFGUpdate(); - return; + pov = LookingForGroupGetCurrentLeader(_player); } uint16 entry = (data & 0xFFFF); uint16 type = ((data >> 24) & 0xFFFF); + info.leaderGuid = pov->GetObjectGuid(); + info.group[slot].set(entry, type); + DEBUG_LOG("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, data, type, entry); - _player->m_lookingForGroup.group[slot].set(entry, type); + sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid(), info](LFGQueue* queue) + { + queue->StartLookingForGroup(info, playerGuid); + }); + LookingForGroupClearLFM(_player, this); LookingForGroupUpdateQueueStatus(_player, this); diff --git a/src/game/LFG/LFGQueue.cpp b/src/game/LFG/LFGQueue.cpp index e9cba730ff..1d66c9b89d 100644 --- a/src/game/LFG/LFGQueue.cpp +++ b/src/game/LFG/LFGQueue.cpp @@ -45,6 +45,48 @@ void LFGQueue::SetMore(ObjectGuid playerGuid, uint16 entry, uint16 type) m_queuedPlayers[playerGuid].more.set(entry, type); } +void LFGQueue::StartLookingForGroup(LFGPlayerQueueInfo info, ObjectGuid invokerPlayer) +{ + auto itr = m_queuedPlayers.find(info.leaderGuid); + if (itr != m_queuedPlayers.end()) + { + sWorld.GetMessager().AddMessage([leaderGuid = info.leaderGuid, invokerPlayer](World* world) + { + Player* player = sObjectMgr.GetPlayer(invokerPlayer); + + if (leaderGuid != invokerPlayer) + { + WorldPacket data(SMSG_LFG_LEADER_IS_LFM); + player->GetSession()->SendPacket(data); + } + }); + + SendLFGUpdate(info.leaderGuid, invokerPlayer); + return; + } + + m_queuedPlayers[info.leaderGuid] = info; + + LookingForGroupClearLFM(_player, this); + + LookingForGroupUpdateQueueStatus(_player, this); + + if (LookingForGroup_auto_join) + LookingForGroupTryJoin(_player); +} + +void LFGQueue::StopLookingForGroup(ObjectGuid leaderGuid, ObjectGuid playerGuid) +{ + auto itr = m_queuedPlayers.find(leaderGuid); + bool success = false; + if (itr != m_queuedPlayers.end()) + { + m_queuedPlayers.erase(itr); + } + + // TODO: Send out packets +} + void LFGQueue::SendLFGUpdate(ObjectGuid leaderGuid, ObjectGuid playerGuid) const { auto itr = m_queuedPlayers.find(leaderGuid); diff --git a/src/game/LFG/LFGQueue.h b/src/game/LFG/LFGQueue.h index a4b8f4e1ed..9f5a2483c7 100644 --- a/src/game/LFG/LFGQueue.h +++ b/src/game/LFG/LFGQueue.h @@ -25,6 +25,8 @@ struct LFGGroupQueueInfo { ObjectGuid partyMember; uint32 level; + + LFGGroupQueueInfo(ObjectGuid partyMember, uint32 level) : partyMember(partyMember), level(level) {} }; struct LFGPlayerQueueInfo @@ -98,6 +100,9 @@ class LFGQueue void SetComment(ObjectGuid playerGuid, std::string const& comment); void SetMore(ObjectGuid playerGuid, uint16 entry, uint16 type); + void StartLookingForGroup(LFGPlayerQueueInfo info, ObjectGuid invokerPlayer); + void StopLookingForGroup(ObjectGuid leaderGuid, ObjectGuid playerGuid); + void SendLFGUpdate(ObjectGuid leaderGuid, ObjectGuid playerGuid) const; void SendLFGUpdateLFG(ObjectGuid playerGuid) const; void SendLFGUpdateLFM(ObjectGuid playerGuid) const; diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index eea4ca1149..46bda8904f 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -411,9 +411,6 @@ class WorldSession // Looking For Group // TRUE values set by client sending CMSG_LFG_SET_AUTOJOIN and CMSG_LFM_CLEAR_AUTOFILL before player login - bool LookingForGroup_auto_join = false; - bool LookingForGroup_auto_add = false; - bool LookingForGroup_queue = false; void SendMeetingStoneInProgress(); void SendMeetingStoneComplete(); void SendLFGListQueryResponse(LfgType type, uint32 entry);