diff options
-rw-r--r-- | src/server/authserver/Server/AuthSession.h | 2 | ||||
-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/Maps/Map.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 2 | ||||
-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/WorldSession.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 58 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 30 | ||||
-rw-r--r-- | src/server/shared/Packets/WorldPacket.h | 22 | ||||
-rw-r--r-- | src/server/shared/Threading/ProducerConsumerQueue.h | 14 |
18 files changed, 162 insertions, 53 deletions
diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h index 822f3c334fc..14129d76fd8 100644 --- a/src/server/authserver/Server/AuthSession.h +++ b/src/server/authserver/Server/AuthSession.h @@ -20,9 +20,9 @@ #define __AUTHSESSION_H__ #include "Common.h" +#include "ByteBuffer.h" #include "Socket.h" #include "BigNumber.h" -#include "ByteBuffer.h" #include <memory> #include <boost/asio/ip/tcp.hpp> diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 03d65fb134d..92f19c0adeb 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -636,7 +636,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 e238119defb..9bdb7c0a187 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -329,7 +329,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 23af4a70d3e..dfc0c438662 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -548,7 +548,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())); + std::pair<UpdateDataMapType::iterator, bool> p = data_map.emplace(player, UpdateData()); 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 16bdec46aba..1ec86192fab 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.h +++ b/src/server/game/Entities/Object/Updates/UpdateData.h @@ -53,6 +53,11 @@ class UpdateData { public: UpdateData(); + UpdateData(UpdateData&& right) : 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); @@ -69,6 +74,9 @@ class UpdateData ByteBuffer m_data; void Compress(void* dst, uint32 *dst_size, void* src, int src_size); + + 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 9472fba6572..f5b72b845a5 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2223,7 +2223,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/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index fbc33418e47..b0164b77f1c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2682,7 +2682,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 b431ca4ba17..70198cb20a3 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/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 1b91ed1690c..0d1983ab463 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 325a0743d79..0b5813a7f58 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -910,9 +910,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/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index eb83a5f55be..279e69a4267 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -186,7 +186,7 @@ uint32 WorldSession::GetGuidLow() const } /// Send a packet to the client -void WorldSession::SendPacket(WorldPacket const* packet) +void WorldSession::SendPacket(WorldPacket* packet) { if (!m_Socket) return; @@ -288,7 +288,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) { TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerInfo().c_str()); - sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnUnknownPacketReceive(m_Socket, *packet); } else { @@ -318,7 +318,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); } @@ -331,7 +331,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) else { // not expected _player or must checked in packet handler - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + sScriptMgr->OnPacketReceive(m_Socket, *packet); (this->*opHandle.handler)(*packet); LogUnprocessedTail(packet); } @@ -343,7 +343,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); } @@ -361,7 +361,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 7ad43907355..d5b2146ae79 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -178,7 +178,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 @@ -222,7 +222,7 @@ class WorldSession void ReadMovementInfo(WorldPacket& data, MovementInfo* mi); void WriteMovementInfo(WorldPacket* data, MovementInfo* mi); - void SendPacket(WorldPacket const* packet); + void SendPacket(WorldPacket* packet); 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 f078b2acc15..ea0bfc234bf 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" @@ -140,7 +139,7 @@ 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); @@ -149,18 +148,12 @@ void WorldSocket::AsyncWrite(WorldPacket const& packet) ServerPktHeader header(packet.size() + 2, packet.GetOpcode()); - std::vector<uint8> data(header.getHeaderLength() + packet.size()); - std::memcpy(data.data(), header.header, header.getHeaderLength()); - - if (!packet.empty()) - std::memcpy(&data[header.getHeaderLength()], packet.contents(), packet.size()); - 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 f355308ff7a..1fa08c2b5f1 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 "AuthCrypt.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,9 +52,49 @@ struct ClientPktHeader #pragma pack(pop) -class WorldSocket : public Socket<WorldSocket, std::vector<uint8> > +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, std::vector<uint8> > Base; + typedef Socket<WorldSocket, WorldPacketBuffer> Base; public: WorldSocket(tcp::socket&& socket); @@ -53,7 +105,7 @@ public: void Start() override; using Base::AsyncWrite; - void AsyncWrite(WorldPacket const& packet); + void AsyncWrite(WorldPacket& packet); protected: void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override; diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 311143b384c..9744904f0dc 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -81,12 +81,28 @@ class ByteBuffer _storage.reserve(reserve); } - // copy constructor - ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos), - _storage(buf._storage) + ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos), + _storage(std::move(buf._storage)) { } + ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos), + _storage(right._storage) + { + } + + ByteBuffer& operator=(ByteBuffer const& right) + { + if (this != &right) + { + _rpos = right._rpos; + _wpos = right._wpos; + _storage = right._storage; + } + + return *this; + } + virtual ~ByteBuffer() { } void clear() @@ -383,18 +399,18 @@ class ByteBuffer return *this; } - uint8 * contents() + uint8* contents() { if (_storage.empty()) throw ByteBufferException(); - return &_storage[0]; + return _storage.data(); } - const uint8 *contents() const + uint8 const* contents() const { if (_storage.empty()) throw ByteBufferException(); - return &_storage[0]; + return _storage.data(); } size_t size() const { return _storage.size(); } diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/shared/Packets/WorldPacket.h index 6703c5ed2ea..8851b9f3e45 100644 --- a/src/server/shared/Packets/WorldPacket.h +++ b/src/server/shared/Packets/WorldPacket.h @@ -29,12 +29,28 @@ class WorldPacket : public ByteBuffer WorldPacket() : ByteBuffer(0), m_opcode(0) { } + explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { } - // copy constructor - WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode) + + WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode) + { + } + + WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode) { } + WorldPacket& operator=(WorldPacket const& right) + { + if (this != &right) + { + m_opcode = right.m_opcode; + ByteBuffer::operator =(right); + } + + return *this; + } + void Initialize(uint16 opcode, size_t newres=200) { clear(); @@ -48,5 +64,5 @@ class WorldPacket : public ByteBuffer protected: uint16 m_opcode; }; -#endif +#endif diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h index 45a1cbc692a..1fee1d0685f 100644 --- a/src/server/shared/Threading/ProducerConsumerQueue.h +++ b/src/server/shared/Threading/ProducerConsumerQueue.h @@ -22,12 +22,11 @@ #include <mutex> #include <queue> #include <atomic> +#include <type_traits> template <typename T> class ProducerConsumerQueue { - static_assert(std::is_pointer<T>::value, "T for ProducerConsumerQueue must be a pointer"); - private: std::mutex _queueLock; std::queue<T> _queue; @@ -94,7 +93,7 @@ public: { T& value = _queue.front(); - delete value; + DeleteQueuedObject(value); _queue.pop(); } @@ -105,8 +104,13 @@ public: _condition.notify_all(); } -}; -#endif +private: + template<typename E = T> + typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; } + template<typename E = T> + typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { } +}; +#endif |