From a6cc4b94584798617559b56554c97a62d7a54fdb Mon Sep 17 00:00:00 2001 From: killerwife Date: Mon, 9 Sep 2024 18:19:35 +0200 Subject: [PATCH] Make it work again --- src/game/Chat/Channel.cpp | 2 +- src/game/Entities/CharacterHandler.cpp | 4 - src/game/Entities/Player.cpp | 6 ++ src/game/Entities/Player.h | 3 - src/game/LFG/LFGDefines.h | 16 ++- src/game/LFG/LFGHandler.cpp | 94 ++++++++++++------ src/game/LFG/LFGQueue.cpp | 132 +++++++++++++++++++++++-- src/game/LFG/LFGQueue.h | 6 +- src/game/Server/WorldSession.h | 3 + src/game/World/World.cpp | 2 + src/game/World/World.h | 1 + src/mangosd/mangosd.conf.dist.in | 12 +++ 12 files changed, 230 insertions(+), 51 deletions(-) diff --git a/src/game/Chat/Channel.cpp b/src/game/Chat/Channel.cpp index 179be44045e..17b827027e5 100644 --- a/src/game/Chat/Channel.cpp +++ b/src/game/Chat/Channel.cpp @@ -93,7 +93,7 @@ void Channel::Join(Player* player, const char* password) if (HasFlag(CHANNEL_FLAG_LFG) && sWorld.getConfig(CONFIG_BOOL_CHANNEL_RESTRICTED_LFG)) { - if (player->GetSession()->GetSecurity() == SEC_PLAYER && !player->m_lfgInfo.queued) + if (player->GetSession()->GetSecurity() == SEC_PLAYER && !player->GetSession()->m_lfgInfo.queued) { MakeNotInLFG(data, m_name); SendToOne(data, guid); diff --git a/src/game/Entities/CharacterHandler.cpp b/src/game/Entities/CharacterHandler.cpp index 617efe4c623..437f773c2ff 100644 --- a/src/game/Entities/CharacterHandler.cpp +++ b/src/game/Entities/CharacterHandler.cpp @@ -1158,10 +1158,6 @@ void WorldSession::HandleSetFactionAtWarOpcode(WorldPacket& recv_data) void WorldSession::HandleMeetingStoneInfoOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("WORLD: Received CMSG_MEETING_STONE_INFO"); - - WorldPacket data(SMSG_MEETINGSTONE_SETQUEUE, 5); - data << uint32(0) << uint8(6); - SendPacket(data); } void WorldSession::HandleTutorialFlagOpcode(WorldPacket& recv_data) diff --git a/src/game/Entities/Player.cpp b/src/game/Entities/Player.cpp index 5bfccea4409..558a1fad6e7 100644 --- a/src/game/Entities/Player.cpp +++ b/src/game/Entities/Player.cpp @@ -19636,6 +19636,12 @@ void Player::SendInitialPacketsAfterAddToMap() SendExtraAuraDurationsOnLogin(true); SendExtraAuraDurationsOnLogin(false); + + if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLED)) + { + WorldPacket data(SMSG_LFG_DISABLED); + GetSession()->SendPacket(data); + } } void Player::SendUpdateToOutOfRangeGroupMembers() diff --git a/src/game/Entities/Player.h b/src/game/Entities/Player.h index c807eee2719..13ffafe0852 100644 --- a/src/game/Entities/Player.h +++ b/src/game/Entities/Player.h @@ -41,7 +41,6 @@ #include "Server/SQLStorages.h" #include "Loot/LootMgr.h" #include "Cinematics/CinematicMgr.h" -#include "LFG/LFGDefines.h" #include #include @@ -2133,8 +2132,6 @@ 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 1b3feae8534..08400cc747f 100644 --- a/src/game/LFG/LFGDefines.h +++ b/src/game/LFG/LFGDefines.h @@ -41,12 +41,22 @@ enum class MeetingstoneFailedStatus : uint8 MEETINGSTONE_FAIL_RAID_GROUP = 3, }; +enum class MeetingstoneSetqueue : uint8 +{ + LEFT_QUEUE = 0, + IN_QUEUE = 1, + UNK = 2, + OTHER_MEMBER_LEFT = 3, + KICKED_FROM_QUEUE = 4, + JOINED_GROUP = 5, +}; + struct LfgPlayerInfo { std::string comment; - bool autojoin; - bool autofill; - bool queued; // cached async information + bool autojoin = false; + bool autofill = false; + bool queued = false; // 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 50a799d7da8..3884b2cd00e 100644 --- a/src/game/LFG/LFGHandler.cpp +++ b/src/game/LFG/LFGHandler.cpp @@ -27,30 +27,36 @@ void WorldSession::HandleLfgSetAutoJoinOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFG_SET_AUTOJOIN"); - _player->m_lfgInfo.autojoin = true; + m_lfgInfo.autojoin = true; - sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + if (_player) { - queue->SetAutoJoin(playerGuid, true); - }); + sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + { + queue->SetAutoJoin(playerGuid, true); + }); + } uint8 result = uint8(MeetingstoneFailedStatus::MEETINGSTONE_FAIL_NONE); WorldPacket data(SMSG_MEETINGSTONE_JOINFAILED, 1); data << uint8(result); - _player->GetSession()->SendPacket(data); + SendPacket(data); } void WorldSession::HandleLfgClearAutoJoinOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFG_CLEAR_AUTOJOIN"); - _player->m_lfgInfo.autojoin = false; + m_lfgInfo.autojoin = false; - sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + if (_player) { - queue->SetAutoJoin(playerGuid, false); - }); + sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + { + queue->SetAutoJoin(playerGuid, false); + }); + } } void WorldSession::HandleLfmSetAutoFillOpcode(WorldPacket& /*recv_data*/) @@ -59,40 +65,46 @@ void WorldSession::HandleLfmSetAutoFillOpcode(WorldPacket& /*recv_data*/) MeetingstoneFailedStatus result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_NONE; - if (Group* _group = _player->GetGroup()) + if (_player) // can be sent during login { - if (_group->IsRaidGroup()) - result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_RAID_GROUP; - else if (!_group->IsLeader(_player->GetObjectGuid())) - result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_PARTYLEADER; - else - result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_FULL_GROUP; - } + if (Group* _group = _player->GetGroup()) + { + if (_group->IsRaidGroup()) + result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_RAID_GROUP; + else if (!_group->IsLeader(_player->GetObjectGuid())) + result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_PARTYLEADER; + else + result = MeetingstoneFailedStatus::MEETINGSTONE_FAIL_FULL_GROUP; + } - if (result == MeetingstoneFailedStatus::MEETINGSTONE_FAIL_NONE) - { - _player->m_lfgInfo.autofill = true; - sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + if (result == MeetingstoneFailedStatus::MEETINGSTONE_FAIL_NONE) { - queue->SetAutoFill(playerGuid, true); - }); + m_lfgInfo.autofill = true; + sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + { + queue->SetAutoFill(playerGuid, true); + }); + } } WorldPacket data(SMSG_MEETINGSTONE_JOINFAILED, 1); data << uint8(result); - _player->GetSession()->SendPacket(data); + SendPacket(data); } void WorldSession::HandleLfmClearAutoFillOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("CMSG_LFM_CLEAR_AUTOFILL"); - _player->m_lfgInfo.autofill = false; + m_lfgInfo.autofill = false; - sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + if (_player) { - queue->SetAutoFill(playerGuid, false); - }); + sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid()](LFGQueue* queue) + { + queue->SetAutoFill(playerGuid, false); + }); + } } void WorldSession::HandleLfgClearOpcode(WorldPacket& /*recv_data */) @@ -147,8 +159,21 @@ void WorldSession::HandleSetLfgOpcode(WorldPacket& recv_data) uint16 entry = (data & 0xFFFF); uint16 type = ((data >> 24) & 0xFFFF); + if (m_lfgInfo.queued) // setting a slot instead of starting lfg entirely + { + sWorld.GetLFGQueue().GetMessager().AddMessage([leaderGuid, slot, entry, type](LFGQueue* queue) + { + queue->SetLfgSlot(leaderGuid, slot, entry, type); + }); + return; + } + info.leaderGuid = leaderGuid; info.group[slot].set(entry, type); + info.team = _player->GetTeam(); + info.level = _player->GetLevel(); + info.zoneId = _player->GetZoneId(); + info.autoJoin = m_lfgInfo.autojoin; DEBUG_LOG("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, data, type, entry); sWorld.GetLFGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid(), info](LFGQueue* queue) @@ -207,8 +232,21 @@ void WorldSession::HandleSetLfmOpcode(WorldPacket& recv_data) uint16 entry = (data & 0xFFFF); uint16 type = ((data >> 24) & 0xFFFF); + if (m_lfgInfo.queued) // setting a slot instead of starting lfg entirely + { + sWorld.GetLFGQueue().GetMessager().AddMessage([leaderGuid, entry, type](LFGQueue* queue) + { + queue->SetLfmData(leaderGuid, entry, type); + }); + return; + } + info.leaderGuid = leaderGuid; info.more.set(entry, type); + info.team = _player->GetTeam(); + info.level = _player->GetLevel(); + info.zoneId = _player->GetZoneId(); + info.autoFill = m_lfgInfo.autofill; DEBUG_LOG("LFM set: temp %u, zone %u, type %u", data, entry, type); sWorld.GetLFGQueue().GetMessager().AddMessage([objectGuid = _player->GetObjectGuid(), info](LFGQueue* queue) diff --git a/src/game/LFG/LFGQueue.cpp b/src/game/LFG/LFGQueue.cpp index 9a92f7678c4..2135225e220 100644 --- a/src/game/LFG/LFGQueue.cpp +++ b/src/game/LFG/LFGQueue.cpp @@ -32,7 +32,11 @@ void LFGQueue::Update() void LFGQueue::SetComment(ObjectGuid playerGuid, std::string const& comment) { - m_queuedPlayers[playerGuid].comment = comment; + auto itr = m_queuedPlayers.find(playerGuid); + if (itr == m_queuedPlayers.end()) + return; + + itr->second.comment = comment; } void LFGQueue::SetAutoFill(ObjectGuid playerGuid, bool state) @@ -42,6 +46,7 @@ void LFGQueue::SetAutoFill(ObjectGuid playerGuid, bool state) return; itr->second.autoFill = state; + TryFill(playerGuid, false); } void LFGQueue::SetAutoJoin(ObjectGuid playerGuid, bool state) @@ -51,6 +56,7 @@ void LFGQueue::SetAutoJoin(ObjectGuid playerGuid, bool state) return; itr->second.autoJoin = state; + TryJoin(playerGuid, false); } void LFGQueue::StartLookingForMore(ObjectGuid playerGuid, LFGPlayerQueueInfo info) @@ -73,7 +79,15 @@ void LFGQueue::StartLookingForMore(ObjectGuid playerGuid, LFGPlayerQueueInfo inf return; } - m_queuedPlayers[info.leaderGuid] = info; + m_queuedPlayers.emplace(info.leaderGuid, info); + + sWorld.GetMessager().AddMessage([playerGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = true; + }); // TODO broadcast LFM preference to party as well instead of full ui update? GroupUpdateUI(playerGuid, false); @@ -89,6 +103,14 @@ void LFGQueue::StopLookingForMore(ObjectGuid playerGuid) return; m_queuedPlayers.erase(itr); + + sWorld.GetMessager().AddMessage([playerGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = false; + }); } void LFGQueue::StartLookingForGroup(LFGPlayerQueueInfo info, ObjectGuid invokerPlayer) @@ -111,7 +133,15 @@ void LFGQueue::StartLookingForGroup(LFGPlayerQueueInfo info, ObjectGuid invokerP return; } - m_queuedPlayers[info.leaderGuid] = info; + m_queuedPlayers.emplace(info.leaderGuid, info); + + sWorld.GetMessager().AddMessage([invokerPlayer](World* world) + { + Player* player = sObjectMgr.GetPlayer(invokerPlayer); + + if (player) + player->GetSession()->m_lfgInfo.queued = true; + }); SendLFGUpdate(info.leaderGuid, invokerPlayer); @@ -129,9 +159,78 @@ void LFGQueue::StopLookingForGroup(ObjectGuid leaderGuid, ObjectGuid playerGuid) m_queuedPlayers.erase(itr); } - SendLFGUpdate(leaderGuid, playerGuid); + GroupUpdateUI(leaderGuid, false); + + sWorld.GetMessager().AddMessage([playerGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = false; + }); +} + +void LFGQueue::SetLfgSlot(ObjectGuid leaderGuid, uint32 slot, uint16 entry, uint16 type) +{ + auto itr = m_queuedPlayers.find(leaderGuid); + if (itr == m_queuedPlayers.end()) + return; + + auto& info = itr->second; + info.group[slot].set(entry, type); + + bool found = false; + for (auto& slot : info.group) + { + if (!slot.empty()) + { + found = true; + break; + } + } + + if (!found) // last slot cleared + m_queuedPlayers.erase(itr); + + GroupUpdateUI(leaderGuid, false); + + if (!found) + { + sWorld.GetMessager().AddMessage([leaderGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(leaderGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = false; + }); + } +} + +void LFGQueue::SetLfmData(ObjectGuid leaderGuid, uint16 entry, uint16 type) +{ + auto itr = m_queuedPlayers.find(leaderGuid); + if (itr == m_queuedPlayers.end()) + return; + + auto& info = itr->second; + info.more.set(entry, type); - GroupUpdateUI(leaderGuid, true); + bool found = !info.more.empty(); + if (!found) // last slot cleared + m_queuedPlayers.erase(itr); + + GroupUpdateUI(leaderGuid, false); + + if (!found) + { + sWorld.GetMessager().AddMessage([leaderGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(leaderGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = false; + }); + } } void LFGQueue::TryJoin(ObjectGuid playerGuid, bool initial) @@ -309,6 +408,7 @@ void LFGQueue::PendingJoinSuccess(ObjectGuid leaderGuid, ObjectGuid playerGuid, { auto leaderItr = m_queuedPlayers.find(leaderGuid); auto playerItr = m_queuedPlayers.find(playerGuid); + bool erasedPlayer = false; if (leaderItr != m_queuedPlayers.end()) { leaderItr->second.pendingMembers.erase(std::remove(leaderItr->second.pendingMembers.begin(), leaderItr->second.pendingMembers.end(), playerGuid), leaderItr->second.pendingMembers.end()); @@ -316,6 +416,7 @@ void LFGQueue::PendingJoinSuccess(ObjectGuid leaderGuid, ObjectGuid playerGuid, { leaderItr->second.members.emplace_back(playerGuid, playerItr->second.level); m_queuedPlayers.erase(playerItr); + erasedPlayer = true; } } else if (playerItr != m_queuedPlayers.end()) // async nature @@ -327,6 +428,17 @@ void LFGQueue::PendingJoinSuccess(ObjectGuid leaderGuid, ObjectGuid playerGuid, m_queuedPlayers.erase(leaderItr); GroupUpdate(leaderGuid, playerGuid, full); + + if (erasedPlayer) + { + sWorld.GetMessager().AddMessage([playerGuid](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + + if (player) + player->GetSession()->m_lfgInfo.queued = false; + }); + } } void LFGQueue::SendLFGUpdate(ObjectGuid leaderGuid, ObjectGuid playerGuid) const @@ -421,7 +533,7 @@ void LFGQueue::SendLFGListQueryResponse(ObjectGuid playerGuid, Team playerTeam, for (const auto& data : m_queuedPlayers) { auto const& info = data.second; - if (!info.team != playerTeam) + if (info.team != playerTeam) continue; if (!info.isLeader || info.full) @@ -594,26 +706,26 @@ void LFGQueue::GroupMakeMeetingStoneQueueJoinedFor(WorldPacket& message, uint16 { message.Initialize(SMSG_MEETINGSTONE_SETQUEUE); message << uint32(entry); - message << uint8(0x01); + message << uint8(MeetingstoneSetqueue::IN_QUEUE); } void LFGQueue::GroupMakeMeetingStoneQueueLeftFor(WorldPacket& message, uint16 entry) { message.Initialize(SMSG_MEETINGSTONE_SETQUEUE); message << uint32(entry); - message << uint8(0x00); + message << uint8(MeetingstoneSetqueue::LEFT_QUEUE); } void LFGQueue::GroupMakeMeetingStoneQueueMatchedFor(WorldPacket& message, uint32 entry, bool asLeader) { message.Initialize(SMSG_MEETINGSTONE_SETQUEUE); message << uint32(entry); - message << uint8(0x05); + message << uint8(MeetingstoneSetqueue::JOINED_GROUP); message << uint8(asLeader); } void LFGQueue::GroupMakeMeetingStoneMemberAdded(WorldPacket& data, ObjectGuid guid) { - data.Initialize(SMSG_MEETINGSTONE_SETQUEUE, 8); + data.Initialize(SMSG_MEETINGSTONE_MEMBER_ADDED, 8); data << guid; } diff --git a/src/game/LFG/LFGQueue.h b/src/game/LFG/LFGQueue.h index b780d8e43cc..b24efe0f106 100644 --- a/src/game/LFG/LFGQueue.h +++ b/src/game/LFG/LFGQueue.h @@ -88,8 +88,8 @@ struct LFGPlayerQueueInfo bool status = false; ObjectGuid leaderGuid; - bool autoFill; - bool autoJoin; + bool autoFill = false; + bool autoJoin = false; bool pendingTransfer = false; @@ -111,6 +111,8 @@ class LFGQueue void StartLookingForGroup(LFGPlayerQueueInfo info, ObjectGuid invokerPlayer); void StopLookingForGroup(ObjectGuid leaderGuid, ObjectGuid playerGuid); + void SetLfgSlot(ObjectGuid leaderGuid, uint32 slot, uint16 entry, uint16 type); + void SetLfmData(ObjectGuid leaderGuid, uint16 entry, uint16 type); void TryJoin(ObjectGuid playerGuid, bool initial); void TryFill(ObjectGuid leaderGuid, bool initial); diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index 9c5210e26bc..00cbb807a08 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -31,6 +31,7 @@ #include "Entities/Item.h" #include "WorldSocket.h" #include "Multithreading/Messager.h" +#include "LFG/LFGDefines.h" #include #include @@ -911,6 +912,8 @@ class WorldSession void SetPacketLogging(bool state); + LfgPlayerInfo m_lfgInfo; + private: // Additional private opcode handlers void HandleComplainMail(WorldPacket& recv_data); diff --git a/src/game/World/World.cpp b/src/game/World/World.cpp index 4cff78db5de..5119e9a1242 100644 --- a/src/game/World/World.cpp +++ b/src/game/World/World.cpp @@ -869,6 +869,8 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_UINT32_SUNSREACH_COUNTER, "Sunsreach.CounterMax", 10000); + setConfig(CONFIG_BOOL_LFG_ENABLED, "Lfg.Enabled", true); + sLog.outString(); } diff --git a/src/game/World/World.h b/src/game/World/World.h index c61e74f7e11..57fc46e5109 100644 --- a/src/game/World/World.h +++ b/src/game/World/World.h @@ -389,6 +389,7 @@ enum eConfigBoolValues CONFIG_BOOL_ALWAYS_SHOW_QUEST_GREETING, CONFIG_BOOL_DISABLE_INSTANCE_RELOCATE, CONFIG_BOOL_PRELOAD_MMAP_TILES, + CONFIG_BOOL_LFG_ENABLED, CONFIG_BOOL_VALUE_COUNT }; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 231c5ddd00b..afe94ce9b2d 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -1609,6 +1609,18 @@ Death.Bones.BattlegroundOrArena = 1 Death.Ghost.RunSpeed.World = 1.0 Death.Ghost.RunSpeed.Battleground = 1.0 +################################################################################################################### +# LFG CONFIG +# +# Lfg.Enabled +# Lfg is enabled +# Default: 1 (enable) +# 0 (disable) +# +################################################################################################################### + +Lfg.Enabled = 1 + ################################################################################################################### # BATTLEGROUND CONFIG #