From ffc5094300a75483850c31dc9db3b114ebd641cb Mon Sep 17 00:00:00 2001 From: sogladev Date: Thu, 28 May 2026 04:31:56 +0200 Subject: [PATCH] fix(Core/LFG): Sort players by role in LFG proposals (#25954) --- src/server/game/DungeonFinding/LFGMgr.cpp | 28 +++++++++++++++++------ src/server/game/Handlers/LFGHandler.cpp | 28 +++++++++++++++++++---- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 5422da2ec8..a948c6bf52 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1692,18 +1692,32 @@ namespace lfg LfgGuidList players; GuidUnorderedSet playersToTeleport; - for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) - { - ObjectGuid guid = it->first; - if (guid == proposal.leader) - players.push_front(guid); - else - players.push_back(guid); + // Sort players by role, leader first, then tank, healer and dps + std::vector tanks, healers, dps; + if (proposal.leader && proposal.players.contains(proposal.leader)) + players.push_back(proposal.leader); + + for (auto const& [guid, player] : proposal.players) + { if (proposal.isNew || GetGroup(guid) != proposal.group) playersToTeleport.insert(guid); + + if (guid == proposal.leader) + continue; + + if (player.role & lfg::PLAYER_ROLE_TANK) + tanks.push_back(guid); + else if (player.role & lfg::PLAYER_ROLE_HEALER) + healers.push_back(guid); + else + dps.push_back(guid); } + players.insert(players.end(), tanks.begin(), tanks.end()); + players.insert(players.end(), healers.begin(), healers.end()); + players.insert(players.end(), dps.begin(), dps.end()); + // Set the dungeon difficulty LFGDungeonData const* dungeon = GetLFGDungeon(proposal.dungeonId); ASSERT(dungeon); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index befc84be1e..867a3c939c 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -569,12 +569,32 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size - for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) + // Sort by roles: tank, healer, dps + std::vector ordered; + ordered.reserve(proposal.players.size()); + + std::vector tanks, healers, dps; + + for (auto const& [pguid, player] : proposal.players) { - lfg::LfgProposalPlayer const& player = it->second; + if (player.role & lfg::PLAYER_ROLE_TANK) + tanks.push_back(pguid); + else if (player.role & lfg::PLAYER_ROLE_HEALER) + healers.push_back(pguid); + else + dps.push_back(pguid); + } + + ordered.insert(ordered.end(), tanks.begin(), tanks.end()); + ordered.insert(ordered.end(), healers.begin(), healers.end()); + ordered.insert(ordered.end(), dps.begin(), dps.end()); + + for (auto const& pguid : ordered) + { + lfg::LfgProposalPlayer const& player = proposal.players.find(pguid)->second; data << uint32(player.role); // Role - data << uint8(it->first == guid); // Self player - if (!player.group) // Player not it a group + data << uint8(pguid == guid); // Self player + if (!player.group) // Player not in a group { data << uint8(0); // Not in dungeon data << uint8(0); // Not same group