diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 541bdf4cb0..d9f5052a02 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -17,6 +17,7 @@ #include "LFGMgr.h" #include "Group.h" +#include "LFGPackets.h" #include "Log.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" @@ -136,88 +137,44 @@ void BuildQuestReward(WorldPacket& data, Quest const* quest, Quest const* bonusQ } } -void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) +void WorldSession::HandleLfgJoinOpcode(WorldPackets::LFG::LFGJoin& lfgJoin) { if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) - { - recvData.rfinish(); return; - } - uint32 roles; - - recvData >> roles; - for (int32 i = 0; i < 3; ++i) - recvData.read_skip(); - - uint32 commentLen = recvData.ReadBits(9); - uint32 numDungeons = recvData.ReadBits(24); - - if (!numDungeons) + if (!lfgJoin.Slots.size()) { TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s no dungeons selected", GetPlayerInfo().c_str()); - recvData.rfinish(); return; } - std::string comment = recvData.ReadString(commentLen); - lfg::LfgDungeonSet newDungeons; - for (uint32 i = 0; i < numDungeons; ++i) + for (uint32 slot : lfgJoin.Slots) { - uint32 dungeon; - recvData >> dungeon; - dungeon &= 0x00FFFFFF; // remove the type from the dungeon entry - if (dungeon) - newDungeons.insert(dungeon); + uint32 dungeonId = slot & 0x00FFFFFF; + if (sLFGDungeonStore.LookupEntry(dungeonId)) + newDungeons.insert(dungeonId); } - TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s", - GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str()); + TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u", GetPlayerInfo().c_str(), lfgJoin.Roles, uint8(newDungeons.size())); - sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment); + sLFGMgr->JoinLfg(GetPlayer(), uint8(lfgJoin.Roles), newDungeons, lfgJoin.Comment); } -void WorldSession::HandleLfgLeaveOpcode(WorldPacket& recvData) +void WorldSession::HandleLfgLeaveOpcode(WorldPackets::LFG::LFGLeave& lfgLeave) { - ObjectGuid leaveGuid; Group* group = GetPlayer()->GetGroup(); - ObjectGuid guid = GetPlayer()->GetGUID(); - ObjectGuid gguid = group ? group->GetGUID() : guid; - recvData.read_skip(); // Always 8 - recvData.read_skip(); // Join date - recvData.read_skip(); // Always 3 - recvData.read_skip(); // Queue Id - - leaveGuid[4] = recvData.ReadBit(); - leaveGuid[5] = recvData.ReadBit(); - leaveGuid[0] = recvData.ReadBit(); - leaveGuid[6] = recvData.ReadBit(); - leaveGuid[2] = recvData.ReadBit(); - leaveGuid[7] = recvData.ReadBit(); - leaveGuid[1] = recvData.ReadBit(); - leaveGuid[3] = recvData.ReadBit(); - - recvData.ReadByteSeq(leaveGuid[7]); - recvData.ReadByteSeq(leaveGuid[4]); - recvData.ReadByteSeq(leaveGuid[3]); - recvData.ReadByteSeq(leaveGuid[2]); - recvData.ReadByteSeq(leaveGuid[6]); - recvData.ReadByteSeq(leaveGuid[0]); - recvData.ReadByteSeq(leaveGuid[1]); - recvData.ReadByteSeq(leaveGuid[5]); - - TC_LOG_DEBUG("lfg", "CMSG_LFG_LEAVE %s in group: %u sent guid " UI64FMTD ".", - GetPlayerInfo().c_str(), group ? 1 : 0, uint64(leaveGuid)); + TC_LOG_DEBUG("lfg", "CMSG_LFG_LEAVE %s in group: %u sent guid %s.", + GetPlayerInfo().c_str(), group ? 1 : 0, lfgLeave.Ticket.RequesterGuid.ToString().c_str()); // Check cheating - only leader can leave the queue - if (!group || group->GetLeaderGUID() == guid) + if (!group || group->GetLeaderGUID() == lfgLeave.Ticket.RequesterGuid) { - sLFGMgr->SetCallToArmsRewardEnligible(guid, false); - sLFGMgr->LeaveLfg(gguid); + sLFGMgr->SetCallToArmsRewardEnligible(lfgLeave.Ticket.RequesterGuid, false); + sLFGMgr->LeaveLfg(lfgLeave.Ticket.RequesterGuid); } } diff --git a/src/server/game/Server/Packet.h b/src/server/game/Server/Packet.h index 9574706a08..6dd43568d7 100644 --- a/src/server/game/Server/Packet.h +++ b/src/server/game/Server/Packet.h @@ -19,6 +19,7 @@ #define PacketBaseWorld_h__ #include "WorldPacket.h" +#include "PacketUtilities.h" namespace WorldPackets { diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 62305166eb..c2ec81bd7e 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -18,4 +18,6 @@ #ifndef AllPackets_h__ #define AllPackets_h__ +#include "LFGPackets.h" + #endif // AllPackets_h__ diff --git a/src/server/game/Server/Packets/LFGPackets.cpp b/src/server/game/Server/Packets/LFGPackets.cpp new file mode 100644 index 0000000000..2c0dacff65 --- /dev/null +++ b/src/server/game/Server/Packets/LFGPackets.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "LFGPackets.h" + +void WorldPackets::LFG::LFGJoin::Read() +{ + _worldPacket >> Roles; + for (uint8 i = 0; i < 3; ++i) + _worldPacket.read_skip(); + + uint32 commentLength = _worldPacket.ReadBits(9); + Slots.resize(_worldPacket.ReadBits(24)); + Comment = _worldPacket.ReadString(commentLength); + + for (uint32& slot : Slots) + _worldPacket >> slot; +} + + +void WorldPackets::LFG::LFGLeave::Read() +{ + _worldPacket.read_skip(); + _worldPacket >> Ticket.Time; + uint32 type = 0; + _worldPacket >> type; + Ticket.Type = RideType(type); + _worldPacket >> Ticket.Id; + + ObjectGuid& requesterGuid = Ticket.RequesterGuid; + requesterGuid[4] = _worldPacket.ReadBit(); + requesterGuid[5] = _worldPacket.ReadBit(); + requesterGuid[0] = _worldPacket.ReadBit(); + requesterGuid[6] = _worldPacket.ReadBit(); + requesterGuid[2] = _worldPacket.ReadBit(); + requesterGuid[7] = _worldPacket.ReadBit(); + requesterGuid[1] = _worldPacket.ReadBit(); + requesterGuid[3] = _worldPacket.ReadBit(); + + _worldPacket.ReadByteSeq(requesterGuid[7]); + _worldPacket.ReadByteSeq(requesterGuid[4]); + _worldPacket.ReadByteSeq(requesterGuid[3]); + _worldPacket.ReadByteSeq(requesterGuid[2]); + _worldPacket.ReadByteSeq(requesterGuid[6]); + _worldPacket.ReadByteSeq(requesterGuid[0]); + _worldPacket.ReadByteSeq(requesterGuid[1]); + _worldPacket.ReadByteSeq(requesterGuid[5]); +} diff --git a/src/server/game/Server/Packets/LFGPackets.h b/src/server/game/Server/Packets/LFGPackets.h new file mode 100644 index 0000000000..7e6dd74e39 --- /dev/null +++ b/src/server/game/Server/Packets/LFGPackets.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef LFGPackets_h__ +#define LFGPackets_h__ + +#include "Packet.h" +#include "LFGPacketsCommon.h" +#include "Optional.h" + +namespace lfg +{ + enum LfgTeleportResult : uint8; +} + +namespace WorldPackets +{ + namespace LFG + { + class LFGJoin final : public ClientPacket + { + public: + LFGJoin(WorldPacket&& packet) : ClientPacket(CMSG_LFG_JOIN, std::move(packet)) { } + + void Read() override; + + uint32 Roles = 0; + std::string Comment; + Array Slots; + }; + + class LFGLeave final : public ClientPacket + { + public: + LFGLeave(WorldPacket&& packet) : ClientPacket(CMSG_LFG_LEAVE, std::move(packet)) { } + + void Read() override; + + RideTicket Ticket; + }; + } +} + +#endif // LFGPackets_h__ diff --git a/src/server/game/Server/Packets/LFGPacketsCommon.cpp b/src/server/game/Server/Packets/LFGPacketsCommon.cpp new file mode 100644 index 0000000000..c1109df320 --- /dev/null +++ b/src/server/game/Server/Packets/LFGPacketsCommon.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "LFGPacketsCommon.h" + +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::LFG::RideTicket& ticket) +{ + data >> ticket.RequesterGuid; + data >> ticket.Id; + ticket.Type = data.read(); + data >> ticket.Time; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::LFG::RideTicket const& ticket) +{ + data << ticket.RequesterGuid; + data << uint32(ticket.Id); + data << uint32(ticket.Type); + data << int32(ticket.Time); + + return data; +} diff --git a/src/server/game/Server/Packets/LFGPacketsCommon.h b/src/server/game/Server/Packets/LFGPacketsCommon.h new file mode 100644 index 0000000000..8810c56ac2 --- /dev/null +++ b/src/server/game/Server/Packets/LFGPacketsCommon.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef LFGPacketsCommon_h__ +#define LFGPacketsCommon_h__ + +#include "Packet.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace LFG + { + enum class RideType : uint32 + { + None = 0, + Battlegrounds = 1, + Lfg = 2 + }; + + struct RideTicket + { + int32 Time = 0; + RideType Type = RideType::None; + uint32 Id = 0; + + ObjectGuid RequesterGuid; + }; + } +} + +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::LFG::RideTicket& ticket); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::LFG::RideTicket const& ticket); + +#endif // LFGPacketsCommon_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4ed4cd7dfe..5d114e33a9 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -76,6 +76,11 @@ class RBACData; namespace WorldPackets { + namespace LFG + { + class LFGJoin; + class LFGLeave; + } } enum AccountDataType @@ -943,8 +948,8 @@ class TC_GAME_API WorldSession void HandleLfgGetLockInfoOpcode(WorldPacket& recvData); void SendLfgPlayerLockInfo(); void SendLfgPartyLockInfo(); - void HandleLfgJoinOpcode(WorldPacket& recvData); - void HandleLfgLeaveOpcode(WorldPacket& recvData); + void HandleLfgJoinOpcode(WorldPackets::LFG::LFGJoin& lfgJoin); + void HandleLfgLeaveOpcode(WorldPackets::LFG::LFGLeave& lfgleave); void HandleLfgSetRolesOpcode(WorldPacket& recvData); void HandleLfgProposalResultOpcode(WorldPacket& recvData); void HandleLfgSetBootVoteOpcode(WorldPacket& recvData); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 6d5ada0aef..c23221bf08 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -414,7 +414,7 @@ WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler() } // prevent invalid memory access/crash with custom opcodes - if (opcode >= NUM_OPCODE_HANDLERS) + if (uint16(opcode) >= NUM_OPCODE_HANDLERS) { CloseSocket(); return ReadDataHandlerResult::Error;