diff options
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Calendar/CalendarMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateData.h | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/CombatHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/GuildHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 2 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSplineInit.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 6 | ||||
-rw-r--r-- | src/server/game/Server/WorldPacket.h | 23 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 60 |
17 files changed, 137 insertions, 54 deletions
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index e47a23d467c..64116b8f8c1 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -642,7 +642,7 @@ void CalendarMgr::SendCalendarCommandResult(uint64 guid, CalendarError err, char } } -void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent) +void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent) { // Send packet to all guild members if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 3dadcbdf645..cd527a7373e 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -330,7 +330,7 @@ class CalendarMgr void SendCalendarClearPendingAction(uint64 guid); void SendCalendarCommandResult(uint64 guid, CalendarError err, char const* param = NULL); - void SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent); + void SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent); }; #define sCalendarMgr CalendarMgr::instance() diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 13d725dbbe2..51087e0f966 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -712,7 +712,7 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons if (iter == data_map.end()) { - std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData(player->GetMapId()))); + std::pair<UpdateDataMapType::iterator, bool> p = data_map.emplace(player, UpdateData(player->GetMapId())); ASSERT(p.second); iter = p.first; } diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h index 1deccfa237b..e0666a1a717 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.h +++ b/src/server/game/Entities/Object/Updates/UpdateData.h @@ -55,6 +55,11 @@ class UpdateData { public: UpdateData(uint16 map); + UpdateData(UpdateData&& right) : m_map(right.m_map), m_blockCount(right.m_blockCount), + m_outOfRangeGUIDs(std::move(right.m_outOfRangeGUIDs)), + m_data(std::move(right.m_data)) + { + } void AddOutOfRangeGUID(std::set<uint64>& guids); void AddOutOfRangeGUID(uint64 guid); @@ -70,6 +75,9 @@ class UpdateData uint32 m_blockCount; std::set<uint64> m_outOfRangeGUIDs; ByteBuffer m_data; + + UpdateData(UpdateData const& right) = delete; + UpdateData& operator=(UpdateData const& right) = delete; }; #endif diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2a3b903513e..f096170c46d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2118,7 +2118,11 @@ void Unit::SendMeleeAttackStop(Unit* victim) { WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); data.append(GetPackGUID()); - data.append(victim ? victim->GetPackGUID() : 0); + if (victim) + data.append(victim->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation SendMessageToSet(&data, true); TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP"); diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 47ffc2578bd..e4d749d9ab0 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -93,7 +93,11 @@ void WorldSession::SendAttackStop(Unit const* enemy) { WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size data.append(GetPlayer()->GetPackGUID()); - data.append(enemy ? enemy->GetPackGUID() : 0); // must be packed guid + if (enemy) + data.append(enemy->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); // unk, can be 1 also SendPacket(&data); } diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 97d5ea8310e..a6e63d196c2 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -746,7 +746,7 @@ void WorldSession::HandleAutoDeclineGuildInvites(WorldPacket& recvPacket) uint8 enable; recvPacket >> enable; - GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable); + GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable != 0); } void WorldSession::HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c69f7863ef6..75301da32ed 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2705,7 +2705,7 @@ uint32 Map::GetPlayersCountExceptGMs() const return count; } -void Map::SendToPlayers(WorldPacket const* data) const +void Map::SendToPlayers(WorldPacket* data) const { for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) itr->GetSource()->GetSession()->SendPacket(data); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index c676a5c5ce0..c194f4dccd7 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -423,7 +423,7 @@ class Map : public GridRefManager<NGridType> void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); } void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); } - void SendToPlayers(WorldPacket const* data) const; + void SendToPlayers(WorldPacket* data) const; typedef MapRefManager PlayerList; PlayerList const& GetPlayers() const { return m_mapRefManager; } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 78c6c98cb59..e1a15fa52b5 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -60,12 +60,12 @@ namespace Movement { MoveSpline& move_spline = *unit->movespline; - bool transport = unit->GetTransGUID(); + bool transport = unit->GetTransGUID() != 0; Location real_position; // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports - if (!move_spline.Finalized() && move_spline.onTransport == (unit->GetTransGUID() != 0)) + if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); else { @@ -138,7 +138,7 @@ namespace Movement if (move_spline.Finalized()) return; - bool transport = unit->GetTransGUID(); + bool transport = unit->GetTransGUID() != 0; Location loc; if (move_spline.onTransport == transport) loc = move_spline.ComputePosition(); @@ -178,7 +178,7 @@ namespace Movement { args.splineId = splineIdGen.NewId(); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - args.TransformForTransport = unit->GetTransGUID(); + args.TransformForTransport = unit->GetTransGUID() != 0; // mix existing state into new args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); args.flags.flying = unit->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index e437875d57a..6d0be13c35e 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -414,25 +414,37 @@ void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew) FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew); } -void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet) +void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) { ASSERT(socket); - FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, packet); + if (SCR_REG_LST(ServerScript).empty()) + return; + + WorldPacket copy(packet); + FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, copy); } -void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet) +void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) { ASSERT(socket); - FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, packet); + if (SCR_REG_LST(ServerScript).empty()) + return; + + WorldPacket copy(packet); + FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, copy); } -void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet) +void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) { ASSERT(socket); - FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, packet); + if (SCR_REG_LST(ServerScript).empty()) + return; + + WorldPacket copy(packet); + FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, copy); } void ScriptMgr::OnOpenStateChange(bool open) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index bc58519fde4..104410a1345 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -909,9 +909,9 @@ class ScriptMgr void OnNetworkStop(); void OnSocketOpen(std::shared_ptr<WorldSocket> socket); void OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew); - void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet); - void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet); - void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet); + void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); + void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); + void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); public: /* WorldScript */ diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h index e2498e64f0a..3e812621b48 100644 --- a/src/server/game/Server/WorldPacket.h +++ b/src/server/game/Server/WorldPacket.h @@ -33,15 +33,28 @@ class WorldPacket : public ByteBuffer { } - WorldPacket(Opcodes opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode) + explicit WorldPacket(Opcodes opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { } + + WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode) + { + } + + WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode) { } - // copy constructor - WorldPacket(WorldPacket const& packet) : ByteBuffer(packet), m_opcode(packet.m_opcode) + + WorldPacket& operator=(WorldPacket const& right) { + if (this != &right) + { + m_opcode = right.m_opcode; + ByteBuffer::operator =(right); + } + + return *this; } - void Initialize(Opcodes opcode, size_t newres = 200) + void Initialize(Opcodes opcode, size_t newres=200) { clear(); _storage.reserve(newres); @@ -58,5 +71,5 @@ class WorldPacket : public ByteBuffer void Compress(void* dst, uint32 *dst_size, const void* src, int src_size); z_stream_s* _compressionStream; }; -#endif +#endif diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 46411b35522..227555c1dfa 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -206,7 +206,7 @@ uint32 WorldSession::GetGuidLow() const } /// Send a packet to the client -void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/) +void WorldSession::SendPacket(WorldPacket* packet, bool forced /*= false*/) { if (!m_Socket) return; @@ -350,7 +350,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) } else if (_player->IsInWorld()) { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnPacketReceive(m_Socket, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -363,7 +363,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) else { // not expected _player or must checked in packet hanlder - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnPacketReceive(m_Socket, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -375,7 +375,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnPacketReceive(m_Socket, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -393,7 +393,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnPacketReceive(m_Socket, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); break; diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 96a66bf2421..bd159475c37 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -185,7 +185,7 @@ class CharacterCreateInfo protected: CharacterCreateInfo(std::string const& name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId, WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair), - OutfitId(outfitId), Data(data), CharCount(0) + OutfitId(outfitId), Data(std::move(data)), CharCount(0) { } /// User specified variables @@ -227,7 +227,7 @@ class WorldSession void SendAddonsInfo(); bool IsAddonRegistered(const std::string& prefix) const; - void SendPacket(WorldPacket const* packet, bool forced = false); + void SendPacket(WorldPacket* packet, bool forced = false); void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3); void SendNotification(uint32 string_id, ...); void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 48c12f84870..46a1bf8f16d 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -18,7 +18,6 @@ #include <memory> #include "WorldSocket.h" -#include "ServerPktHeader.h" #include "BigNumber.h" #include "Opcodes.h" #include "ScriptMgr.h" @@ -175,35 +174,24 @@ void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transf CloseSocket(); } -void WorldSocket::AsyncWrite(WorldPacket const& packet) +void WorldSocket::AsyncWrite(WorldPacket& packet) { if (sPacketLog->CanLogPacket()) sPacketLog->LogPacket(packet, SERVER_TO_CLIENT); - WorldPacket const* pkt = &packet; - WorldPacket buff; // Empty buffer used in case packet should be compressed if (_worldSession && packet.size() > 0x400) - { - buff.Compress(_worldSession->GetCompressionStream(), pkt); - pkt = &buff; - } - - TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str()); - - ServerPktHeader header(pkt->size() + 2, pkt->GetOpcode()); + packet.Compress(_worldSession->GetCompressionStream()); - std::vector<uint8> data(header.getHeaderLength() + pkt->size()); - std::memcpy(data.data(), header.header, header.getHeaderLength()); + TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(packet.GetOpcode()).c_str()); - if (!pkt->empty()) - std::memcpy(&data[header.getHeaderLength()], pkt->contents(), pkt->size()); + ServerPktHeader header(packet.size() + 2, packet.GetOpcode()); std::lock_guard<std::mutex> guard(_writeLock); bool needsWriteStart = _writeQueue.empty(); - _authCrypt.EncryptSend(data.data(), header.getHeaderLength()); + _authCrypt.EncryptSend(header.header, header.getHeaderLength()); - _writeQueue.push(std::move(data)); + _writeQueue.emplace(header, std::move(packet)); if (needsWriteStart) AsyncWrite(_writeQueue.front()); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index ca50b46efb0..4e1cbe743fd 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -19,14 +19,26 @@ #ifndef __WORLDSOCKET_H__ #define __WORLDSOCKET_H__ +// Forward declare buffer function here - Socket.h must know about it +struct WorldPacketBuffer; +namespace boost +{ + namespace asio + { + WorldPacketBuffer const& buffer(WorldPacketBuffer const& buf); + } +} + #include "Common.h" #include "WorldPacketCrypt.h" +#include "ServerPktHeader.h" #include "Socket.h" #include "Util.h" #include "WorldPacket.h" #include "WorldSession.h" #include <chrono> #include <boost/asio/ip/tcp.hpp> +#include <boost/asio/buffer.hpp> using boost::asio::ip::tcp; @@ -40,8 +52,50 @@ struct ClientPktHeader #pragma pack(pop) -class WorldSocket : public Socket<WorldSocket> +struct WorldPacketBuffer { + typedef boost::asio::const_buffer value_type; + + typedef boost::asio::const_buffer const* const_iterator; + + WorldPacketBuffer(ServerPktHeader header, WorldPacket&& packet) : _header(header), _packet(std::move(packet)) + { + _buffers[0] = boost::asio::const_buffer(_header.header, _header.getHeaderLength()); + if (!_packet.empty()) + _buffers[1] = boost::asio::const_buffer(_packet.contents(), _packet.size()); + } + + const_iterator begin() const + { + return _buffers; + } + + const_iterator end() const + { + return _buffers + (_packet.empty() ? 1 : 2); + } + +private: + boost::asio::const_buffer _buffers[2]; + ServerPktHeader _header; + WorldPacket _packet; +}; + +namespace boost +{ + namespace asio + { + inline WorldPacketBuffer const& buffer(WorldPacketBuffer const& buf) + { + return buf; + } + } +} + +class WorldSocket : public Socket<WorldSocket, WorldPacketBuffer> +{ + typedef Socket<WorldSocket, WorldPacketBuffer> Base; + public: WorldSocket(tcp::socket&& socket); @@ -50,8 +104,8 @@ public: void Start() override; - void AsyncWrite(WorldPacket const& packet); - using Socket<WorldSocket>::AsyncWrite; + using Base::AsyncWrite; + void AsyncWrite(WorldPacket& packet); protected: void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override; |