Core/NetworkIO: implement 2nd connection
This commit is contained in:
1 parent
0299e10945
commit
8bec6af24a
28 files changed
+2049
-1000
No files matched your search
@@ -23,6 +23,7 @@
|
||||
#include "WorldSession.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "AddonMgr.h"
|
||||
#include "AuthenticationPackets.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "BattlenetServerManager.h"
|
||||
#include "Common.h"
|
||||
@@ -110,7 +111,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
|
||||
AntiDOS(this),
|
||||
m_GUIDLow(0),
|
||||
_player(nullptr),
|
||||
m_Socket(sock),
|
||||
_security(sec),
|
||||
_accountId(id),
|
||||
_accountName(std::move(name)),
|
||||
@@ -119,7 +119,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
|
||||
_warden(nullptr),
|
||||
_logoutTime(0),
|
||||
m_inQueue(false),
|
||||
m_playerLoading(false),
|
||||
m_playerLogout(false),
|
||||
m_playerRecentlyLogout(false),
|
||||
m_playerSave(false),
|
||||
@@ -150,15 +149,8 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
|
||||
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
|
||||
}
|
||||
|
||||
_compressionStream = new z_stream();
|
||||
_compressionStream->zalloc = (alloc_func)nullptr;
|
||||
_compressionStream->zfree = (free_func)nullptr;
|
||||
_compressionStream->opaque = (voidpf)nullptr;
|
||||
_compressionStream->avail_in = 0;
|
||||
_compressionStream->next_in = nullptr;
|
||||
int32 z_res = deflateInit(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION));
|
||||
if (z_res != Z_OK)
|
||||
TC_LOG_ERROR("network", "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
|
||||
m_Socket[CONNECTION_TYPE_REALM] = sock;
|
||||
_instanceConnectKey.Raw = UI64LIT(0);
|
||||
}
|
||||
|
||||
/// WorldSession destructor
|
||||
@@ -166,13 +158,16 @@ WorldSession::~WorldSession()
|
||||
{
|
||||
///- unload player if not unloaded
|
||||
if (_player)
|
||||
LogoutPlayer (true);
|
||||
LogoutPlayer(true);
|
||||
|
||||
/// - If have unclosed socket, close it
|
||||
if (m_Socket)
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
m_Socket->CloseSocket();
|
||||
m_Socket = nullptr;
|
||||
if (m_Socket[i])
|
||||
{
|
||||
m_Socket[i]->CloseSocket();
|
||||
m_Socket[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
delete _warden;
|
||||
@@ -184,12 +179,12 @@ WorldSession::~WorldSession()
|
||||
delete packet;
|
||||
|
||||
LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); // One-time query
|
||||
}
|
||||
|
||||
int32 z_res = deflateEnd(_compressionStream);
|
||||
if (z_res != Z_OK && z_res != Z_DATA_ERROR) // Z_DATA_ERROR signals that internal state was BUSY
|
||||
TC_LOG_ERROR("network", "Can't close packet compression stream (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res));
|
||||
|
||||
delete _compressionStream;
|
||||
bool WorldSession::PlayerDisconnected() const
|
||||
{
|
||||
return !(m_Socket[CONNECTION_TYPE_REALM] && m_Socket[CONNECTION_TYPE_REALM]->IsOpen() &&
|
||||
m_Socket[CONNECTION_TYPE_INSTANCE] && m_Socket[CONNECTION_TYPE_INSTANCE]->IsOpen());
|
||||
}
|
||||
|
||||
std::string const & WorldSession::GetPlayerName() const
|
||||
@@ -219,9 +214,6 @@ ObjectGuid::LowType WorldSession::GetGUIDLow() const
|
||||
/// Send a packet to the client
|
||||
void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
|
||||
{
|
||||
if (!m_Socket)
|
||||
return;
|
||||
|
||||
if (packet->GetOpcode() == NULL_OPCODE)
|
||||
{
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending of NULL_OPCODE to %s", GetPlayerInfo().c_str());
|
||||
@@ -233,12 +225,41 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
|
||||
return;
|
||||
}
|
||||
|
||||
ServerOpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
|
||||
|
||||
if (!handler)
|
||||
{
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending of opcode %u with non existing handler to %s", packet->GetOpcode(), GetPlayerInfo().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Default connection index defined in Opcodes.cpp table
|
||||
ConnectionType conIdx = handler->ConnectionIndex;
|
||||
|
||||
// Override connection index
|
||||
if (packet->GetConnection() != CONNECTION_TYPE_DEFAULT)
|
||||
{
|
||||
if (packet->GetConnection() != CONNECTION_TYPE_INSTANCE && IsInstanceOnlyOpcode(packet->GetOpcode()))
|
||||
{
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending of instance only opcode %u with connection type %u to %s", packet->GetOpcode(), packet->GetConnection(), GetPlayerInfo().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
conIdx = packet->GetConnection();
|
||||
}
|
||||
|
||||
if (!m_Socket[conIdx])
|
||||
{
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending of %s to non existent socket %u to %s", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())).c_str(), conIdx, GetPlayerInfo().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forced)
|
||||
{
|
||||
OpcodeHandler const* handler = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
|
||||
OpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
|
||||
if (!handler || handler->Status == STATUS_UNHANDLED)
|
||||
{
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str(), GetPlayerInfo().c_str());
|
||||
TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())).c_str(), GetPlayerInfo().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -280,7 +301,7 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
|
||||
sScriptMgr->OnPacketSend(this, *packet);
|
||||
|
||||
TC_LOG_TRACE("network.opcode", "S->C: %s %s", GetPlayerInfo().c_str(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str());
|
||||
m_Socket->SendPacket(*packet);
|
||||
m_Socket[conIdx]->SendPacket(*packet);
|
||||
}
|
||||
|
||||
/// Add an incoming packet to the queue
|
||||
@@ -316,7 +337,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
///- Before we process anything:
|
||||
/// If necessary, kick the player from the character select screen
|
||||
if (IsConnectionIdle() && !HasPermission(rbac::RBAC_PERM_IGNORE_IDLE_CONNECTION))
|
||||
m_Socket->CloseSocket();
|
||||
m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
|
||||
|
||||
///- Retrieve packets from the receive queue and call the appropriate handlers
|
||||
/// not process packets if socket already closed
|
||||
@@ -327,7 +348,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
uint32 processedPackets = 0;
|
||||
time_t currentTime = time(nullptr);
|
||||
|
||||
while (m_Socket && _recvQueue.next(packet, updater))
|
||||
while (m_Socket[CONNECTION_TYPE_REALM] && _recvQueue.next(packet, updater))
|
||||
{
|
||||
ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
|
||||
try
|
||||
@@ -440,7 +461,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
|
||||
_recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
|
||||
|
||||
if (m_Socket && m_Socket->IsOpen() && _warden)
|
||||
if (m_Socket[0] && m_Socket[0]->IsOpen() && _warden)
|
||||
_warden->Update();
|
||||
|
||||
if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
|
||||
@@ -463,23 +484,32 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
{
|
||||
time_t currTime = time(nullptr);
|
||||
///- If necessary, log the player out
|
||||
if (ShouldLogOut(currTime) && !m_playerLoading)
|
||||
if (ShouldLogOut(currTime) && m_playerLoading.IsEmpty())
|
||||
LogoutPlayer(true);
|
||||
|
||||
if (m_Socket && GetPlayer() && _warden)
|
||||
if (m_Socket[CONNECTION_TYPE_REALM] && GetPlayer() && _warden)
|
||||
_warden->Update();
|
||||
|
||||
///- Cleanup socket pointer if need
|
||||
if (m_Socket && !m_Socket->IsOpen())
|
||||
if ((m_Socket[0] && !m_Socket[0]->IsOpen()) || (m_Socket[1] && !m_Socket[1]->IsOpen()))
|
||||
{
|
||||
expireTime -= expireTime > diff ? diff : expireTime;
|
||||
if (expireTime < diff || forceExit || !GetPlayer())
|
||||
{
|
||||
m_Socket = nullptr;
|
||||
if (m_Socket[CONNECTION_TYPE_REALM])
|
||||
{
|
||||
m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
|
||||
m_Socket[CONNECTION_TYPE_REALM].reset();
|
||||
}
|
||||
if (m_Socket[CONNECTION_TYPE_INSTANCE])
|
||||
{
|
||||
m_Socket[CONNECTION_TYPE_INSTANCE]->CloseSocket();
|
||||
m_Socket[CONNECTION_TYPE_INSTANCE].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_Socket)
|
||||
if (!m_Socket[CONNECTION_TYPE_REALM])
|
||||
return false; //Will remove this session from the world session map
|
||||
}
|
||||
|
||||
@@ -589,7 +619,7 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
|
||||
// remove player from the group if he is:
|
||||
// a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
|
||||
if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
|
||||
if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket[CONNECTION_TYPE_REALM])
|
||||
_player->RemoveFromGroup();
|
||||
|
||||
//! Send update to group and reset stored max enchanting level
|
||||
@@ -635,6 +665,12 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
if (m_Socket[CONNECTION_TYPE_INSTANCE])
|
||||
{
|
||||
m_Socket[CONNECTION_TYPE_INSTANCE]->CloseSocket();
|
||||
m_Socket[CONNECTION_TYPE_INSTANCE].reset();
|
||||
}
|
||||
|
||||
m_playerLogout = false;
|
||||
m_playerSave = false;
|
||||
m_playerRecentlyLogout = true;
|
||||
@@ -644,10 +680,13 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
/// Kick a player out of the World
|
||||
void WorldSession::KickPlayer()
|
||||
{
|
||||
if (m_Socket)
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
m_Socket->CloseSocket();
|
||||
forceExit = true;
|
||||
if (m_Socket[i])
|
||||
{
|
||||
m_Socket[i]->CloseSocket();
|
||||
forceExit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,6 +765,25 @@ void WorldSession::Handle_Deprecated(WorldPacket& recvPacket)
|
||||
, GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())).c_str(), GetPlayerInfo().c_str());
|
||||
}
|
||||
|
||||
void WorldSession::SendConnectToInstance(WorldPackets::Auth::ConnectToSerial serial)
|
||||
{
|
||||
boost::system::error_code ignored_error;
|
||||
boost::asio::ip::tcp::endpoint instanceAddress = realm.GetAddressForClient(boost::asio::ip::make_address(GetRemoteAddress(), ignored_error));
|
||||
instanceAddress.port(sWorld->getIntConfig(CONFIG_PORT_INSTANCE));
|
||||
|
||||
_instanceConnectKey.Fields.AccountId = GetAccountId();
|
||||
_instanceConnectKey.Fields.ConnectionType = CONNECTION_TYPE_INSTANCE;
|
||||
_instanceConnectKey.Fields.Key = urand(0, 0x7FFFFFFF);
|
||||
|
||||
WorldPackets::Auth::ConnectTo connectTo;
|
||||
connectTo.Key = _instanceConnectKey.Raw;
|
||||
connectTo.Serial = serial;
|
||||
connectTo.Payload.Where = instanceAddress;
|
||||
connectTo.Con = CONNECTION_TYPE_INSTANCE;
|
||||
|
||||
SendPacket(connectTo.Write());
|
||||
}
|
||||
|
||||
void WorldSession::SendAuthWaitQue(uint32 position)
|
||||
{
|
||||
if (position == 0)
|
||||
|
||||
Reference in new issue
Block a user