Merge branch 'master' of https://github.com/TrinityCore/TrinityCore into 4.3.4
Conflicts: README.md src/server/game/Entities/Object/Object.cpp src/server/game/Entities/Object/Updates/UpdateData.h src/server/game/Server/WorldPacket.h src/server/game/Server/WorldSession.cpp src/server/game/Server/WorldSession.h src/server/game/Server/WorldSocket.cpp src/server/game/Server/WorldSocket.h src/server/shared/Packets/ByteBuffer.h
This commit is contained in:
commit
2cba07d6a1
32 files changed
+264
-138
No files matched your search
+7
-9
@@ -6,18 +6,16 @@ before_install:
|
||||
- echo "yes" | sudo add-apt-repository ppa:kalakris/cmake
|
||||
- echo "yes" | sudo add-apt-repository ppa:boost-latest/ppa
|
||||
- echo "yes" | sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install build-essential libtool gcc-4.8 g++-4.8 make cmake openssl libssl-dev libmysqlclient15-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev libboost1.55-dev libboost-thread1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get -qq install build-essential libtool gcc-4.8 g++-4.8 make cmake openssl
|
||||
- sudo apt-get -qq install libssl-dev libmysqlclient15-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev
|
||||
- sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev
|
||||
|
||||
script:
|
||||
- mkdir bin
|
||||
- cd bin
|
||||
- cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=1 -DUSE_COREPCH=0 -DUSE_SCRIPTPCH=0 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
script: make -j 8
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- 4.3.4
|
||||
- make -j 8
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
@@ -1,7 +1,8 @@
|
||||
#  TrinityCore
|
||||
|
||||
[](https://travis-ci.org/TrinityCore/TrinityCore)
|
||||
[](https://scan.coverity.com/projects/435)
|
||||
[](https://scan.coverity.com/projects/435)
|
||||
`3.3.5`: [](https://travis-ci.org/TrinityCore/TrinityCore)
|
||||
`4.3.4`: [](https://travis-ci.org/TrinityCore/TrinityCore)
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
DELETE FROM `spell_area` WHERE `spell` IN(48763,48761, 45614);
|
||||
INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`, `quest_end_status`) VALUES
|
||||
(48763, 4180, 12274, 0, 0, 0, 0, 0, 74, 11),
|
||||
(48761, 4180, 12274, 0, 0, 0, 1, 0, 74, 11),
|
||||
(45614, 4125, 11633, 0, 0, 0, 2, 0, 74, 11),
|
||||
(45614, 4135, 11633, 0, 0, 0, 2, 0, 74, 11),
|
||||
(45614, 4136, 11633, 0, 0, 0, 2, 0, 74, 11),
|
||||
(45614, 4137, 11633, 0, 0, 0, 2, 0, 74, 11);
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "AuthSession.h"
|
||||
#include "Log.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "AuthCodes.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "SHA1.h"
|
||||
@@ -173,19 +172,16 @@ void AuthSession::ReadDataHandler(boost::system::error_code error, size_t transf
|
||||
CloseSocket();
|
||||
}
|
||||
|
||||
void AuthSession::AsyncWrite(ByteBuffer const& packet)
|
||||
void AuthSession::AsyncWrite(ByteBuffer& packet)
|
||||
{
|
||||
std::vector<uint8> data(packet.size());
|
||||
std::memcpy(data.data(), packet.contents(), packet.size());
|
||||
|
||||
std::lock_guard<std::mutex> guard(_writeLock);
|
||||
|
||||
bool needsWriteStart = _writeQueue.empty();
|
||||
|
||||
_writeQueue.push(std::move(data));
|
||||
_writeQueue.push(std::move(packet));
|
||||
|
||||
if (needsWriteStart)
|
||||
AsyncWrite(_writeQueue.front());
|
||||
Base::AsyncWrite(_writeQueue.front());
|
||||
}
|
||||
|
||||
bool AuthSession::HandleLogonChallenge()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define __AUTHSESSION_H__
|
||||
|
||||
#include "Common.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "Socket.h"
|
||||
#include "BigNumber.h"
|
||||
#include <memory>
|
||||
@@ -28,10 +29,10 @@
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
struct AuthHandler;
|
||||
class ByteBuffer;
|
||||
|
||||
class AuthSession : public Socket<AuthSession>
|
||||
class AuthSession : public Socket<AuthSession, ByteBuffer>
|
||||
{
|
||||
typedef Socket<AuthSession, ByteBuffer> Base;
|
||||
|
||||
public:
|
||||
static std::unordered_map<uint8, AuthHandler> InitHandlers();
|
||||
@@ -47,8 +48,8 @@ public:
|
||||
AsyncReadHeader();
|
||||
}
|
||||
|
||||
using Socket<AuthSession>::AsyncWrite;
|
||||
void AsyncWrite(ByteBuffer const& packet);
|
||||
using Base::AsyncWrite;
|
||||
void AsyncWrite(ByteBuffer& packet);
|
||||
|
||||
protected:
|
||||
void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override;
|
||||
|
||||
@@ -234,4 +234,15 @@ namespace Battlenet
|
||||
bool BitStream::Read<bool>(uint32 bitCount);
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
inline const_buffers_1 buffer(Battlenet::BitStream const& stream)
|
||||
{
|
||||
return buffer(stream.GetBuffer(), stream.GetSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __BATTLENETBITSTREAM_H__
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "BattlenetPackets.h"
|
||||
#include "BattlenetPacketCrypt.h"
|
||||
#include "Socket.h"
|
||||
#include "BigNumber.h"
|
||||
#include <memory>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -33,15 +33,28 @@ class WorldPacket : public ByteBuffer
|
||||
{
|
||||
}
|
||||
|
||||
WorldPacket(Opcodes opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode)
|
||||
{
|
||||
}
|
||||
// copy constructor
|
||||
WorldPacket(WorldPacket const& packet) : ByteBuffer(packet), m_opcode(packet.m_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)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize(Opcodes opcode, size_t newres = 200)
|
||||
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(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
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
packet.Compress(_worldSession->GetCompressionStream());
|
||||
|
||||
TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str());
|
||||
TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(packet.GetOpcode()).c_str());
|
||||
|
||||
ServerPktHeader header(pkt->size() + 2, pkt->GetOpcode());
|
||||
|
||||
std::vector<uint8> data(header.getHeaderLength() + pkt->size());
|
||||
std::memcpy(data.data(), header.header, header.getHeaderLength());
|
||||
|
||||
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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -112,26 +112,6 @@ public:
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void SendWeather(WeatherState weather, float grade) const
|
||||
{
|
||||
WorldPacket data(SMSG_WEATHER, 9);
|
||||
data << uint32(weather);
|
||||
data << float(grade);
|
||||
data << uint8(0);
|
||||
SendPacketToPlayers(&data);
|
||||
}
|
||||
|
||||
// Send packet to all players in Tomb of the Earthrager
|
||||
void SendPacketToPlayers(WorldPacket const* data) const
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->GetAreaId() == AREA_TOMB_OF_THE_EARTHRAGER)
|
||||
player->GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_summonDeaths = 0;
|
||||
@@ -153,7 +133,7 @@ public:
|
||||
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_SANDSTORM);
|
||||
SendWeather(WEATHER_STATE_LIGHT_SANDSTORM, 1.0f);
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_LIGHT_SANDSTORM, 1.0f);
|
||||
events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6000, 0, PHASE_DISPERSE);
|
||||
events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE);
|
||||
|
||||
@@ -185,7 +165,7 @@ public:
|
||||
++_summonDeaths;
|
||||
if (_summonDeaths == 11) // All summons died
|
||||
{
|
||||
SendWeather(WEATHER_STATE_FOG, 0.0f);
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_FOG, 0.0f);
|
||||
me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
|
||||
events.SetPhase(PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL);
|
||||
|
||||
@@ -100,7 +100,7 @@ enum GameObjects
|
||||
|
||||
enum Misc
|
||||
{
|
||||
AREA_TOMB_OF_THE_EARTHRAGER = 5610,
|
||||
AREA_TOMB_OF_THE_EARTHRAGER = 4945,
|
||||
ACHIEV_VAULT_OF_LIGHTS_EVENT = 24212, // Faster Than The Speed Of Light
|
||||
SPELL_VAULT_OF_LIGHTS_CREDIT = 94067, // Not in DBC
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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
|
||||
@@ -26,12 +25,13 @@
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
template<class T>
|
||||
template<class T, class PacketType>
|
||||
class Socket : public std::enable_shared_from_this<T>
|
||||
{
|
||||
public:
|
||||
@@ -44,31 +44,44 @@ public:
|
||||
|
||||
void AsyncReadHeader()
|
||||
{
|
||||
_socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), std::bind(&Socket<T>::ReadHeaderHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||
_socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), std::bind(&Socket<T, PacketType>::ReadHeaderHandlerInternal, this->shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
void AsyncReadData(std::size_t size, std::size_t bufferOffset)
|
||||
{
|
||||
_socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), std::bind(&Socket<T>::ReadDataHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||
_socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), std::bind(&Socket<T, PacketType>::ReadDataHandlerInternal, this->shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
void ReadData(std::size_t size, std::size_t bufferOffset)
|
||||
{
|
||||
_socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size));
|
||||
boost::system::error_code error;
|
||||
|
||||
_socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
TC_LOG_DEBUG("network", "Socket::ReadData: %s errored with: %i (%s)", GetRemoteIpAddress().to_string().c_str(), error.value(), error.message().c_str());
|
||||
|
||||
CloseSocket();
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWrite(std::vector<uint8> const& data)
|
||||
void AsyncWrite(PacketType const& data)
|
||||
{
|
||||
boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T>::WriteHandler, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||
boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T, PacketType>::WriteHandler, this->shared_from_this(), std::placeholders::_1,
|
||||
std::placeholders::_2));
|
||||
}
|
||||
|
||||
bool IsOpen() const { return _socket.is_open(); }
|
||||
void CloseSocket()
|
||||
{
|
||||
boost::system::error_code socketError;
|
||||
_socket.close(socketError);
|
||||
if (socketError)
|
||||
TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(), socketError.value(), socketError.message().c_str());
|
||||
boost::system::error_code error;
|
||||
_socket.close(error);
|
||||
if (error)
|
||||
TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(),
|
||||
error.value(), error.message().c_str());
|
||||
}
|
||||
|
||||
uint8* GetReadBuffer() { return _readBuffer; }
|
||||
@@ -78,7 +91,7 @@ protected:
|
||||
virtual void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) = 0;
|
||||
|
||||
std::mutex _writeLock;
|
||||
std::queue<std::vector<uint8> > _writeQueue;
|
||||
std::queue<PacketType> _writeQueue;
|
||||
|
||||
private:
|
||||
void ReadHeaderHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadHeaderHandler(error, transferedBytes); }
|
||||
@@ -90,6 +103,7 @@ private:
|
||||
{
|
||||
std::lock_guard<std::mutex> deleteGuard(_writeLock);
|
||||
|
||||
DeletePacket(_writeQueue.front());
|
||||
_writeQueue.pop();
|
||||
|
||||
if (!_writeQueue.empty())
|
||||
@@ -99,6 +113,12 @@ private:
|
||||
CloseSocket();
|
||||
}
|
||||
|
||||
template<typename Q = PacketType>
|
||||
typename std::enable_if<std::is_pointer<Q>::value>::type DeletePacket(PacketType& packet) { delete packet; }
|
||||
|
||||
template<typename Q = PacketType>
|
||||
typename std::enable_if<!std::is_pointer<Q>::value>::type DeletePacket(PacketType const& /*packet*/) { }
|
||||
|
||||
tcp::socket _socket;
|
||||
|
||||
uint8 _readBuffer[4096];
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <cstring>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
// Root of ByteBuffer exception hierarchy
|
||||
class ByteBufferException : public std::exception
|
||||
@@ -80,12 +81,30 @@ class ByteBuffer
|
||||
_storage.reserve(reserve);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
|
||||
_bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage)
|
||||
ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos),
|
||||
_bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(std::move(buf._storage))
|
||||
{
|
||||
}
|
||||
|
||||
ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos),
|
||||
_bitpos(right._bitpos), _curbitval(right._curbitval), _storage(right._storage)
|
||||
{
|
||||
}
|
||||
|
||||
ByteBuffer& operator=(ByteBuffer const& right)
|
||||
{
|
||||
if (this != &right)
|
||||
{
|
||||
_rpos = right._rpos;
|
||||
_wpos = right._wpos;
|
||||
_bitpos = right._bitpos;
|
||||
_curbitval = right._curbitval;
|
||||
_storage = right._storage;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~ByteBuffer() { }
|
||||
|
||||
void clear()
|
||||
@@ -510,18 +529,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(); }
|
||||
@@ -737,5 +756,15 @@ inline void ByteBuffer::read_skip<std::string>()
|
||||
read_skip<char*>();
|
||||
}
|
||||
|
||||
#endif
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
inline const_buffers_1 buffer(ByteBuffer const& packet)
|
||||
{
|
||||
return buffer(packet.contents(), packet.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -196,11 +196,10 @@ Compression = 1
|
||||
# Description: Maximum number of players in the world. Excluding Mods, GMs and Admins.
|
||||
# Important: If you want to block players and only allow Mods, GMs or Admins to join the
|
||||
# server, use the DB field "auth.realmlist.allowedSecurityLevel".
|
||||
# Default: 100 - (Enabled)
|
||||
# Default: 0 - (Disabled, No limit)
|
||||
# 1+ - (Enabled)
|
||||
# 0 - (Disabled, No limit)
|
||||
|
||||
PlayerLimit = 100
|
||||
PlayerLimit = 0
|
||||
|
||||
#
|
||||
# SaveRespawnTimeImmediately
|
||||
|
||||
@@ -171,19 +171,14 @@ namespace MMAP
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
uint32* mapId = nullptr;
|
||||
uint32 mapId;
|
||||
|
||||
_queue.WaitAndPop(mapId);
|
||||
|
||||
if (_cancelationToken)
|
||||
return;
|
||||
|
||||
if (!mapId) // shouldn't happen?
|
||||
continue;
|
||||
|
||||
buildMap(*mapId);
|
||||
|
||||
delete mapId;
|
||||
buildMap(mapId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +200,7 @@ namespace MMAP
|
||||
if (!shouldSkipMap(mapId))
|
||||
{
|
||||
if (threads > 0)
|
||||
_queue.Push(new uint32(mapId));
|
||||
_queue.Push(mapId);
|
||||
else
|
||||
buildMap(mapId);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace MMAP
|
||||
rcContext* m_rcContext;
|
||||
|
||||
std::vector<std::thread> _workerThreads;
|
||||
ProducerConsumerQueue<uint32*> _queue;
|
||||
ProducerConsumerQueue<uint32> _queue;
|
||||
std::atomic<bool> _cancelationToken;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user