forked from metin2/server
Rewrote network stack, started working on porting to 64-bit
This commit is contained in:
@@ -9,16 +9,12 @@
|
||||
#include "buffer_manager.h"
|
||||
#include "guild_manager.h"
|
||||
#include "db.h"
|
||||
|
||||
#include "party.h"
|
||||
|
||||
extern LPFDWATCH main_fdw;
|
||||
|
||||
LPCLIENT_DESC db_clientdesc = NULL;
|
||||
LPCLIENT_DESC g_pkAuthMasterDesc = NULL;
|
||||
LPCLIENT_DESC g_NetmarbleDBDesc = NULL;
|
||||
LPCLIENT_DESC g_TeenDesc = NULL;
|
||||
LPCLIENT_DESC g_PasspodDesc = NULL;
|
||||
|
||||
static const char* GetKnownClientDescName(LPCLIENT_DESC desc) {
|
||||
if (desc == db_clientdesc) {
|
||||
@@ -29,12 +25,32 @@ static const char* GetKnownClientDescName(LPCLIENT_DESC desc) {
|
||||
return "g_NetmarbleDBDesc";
|
||||
} else if (desc == g_TeenDesc) {
|
||||
return "g_TeenDesc";
|
||||
} else if (desc == g_PasspodDesc) {
|
||||
return "g_PasspodDesc";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void ClientDescEventHandler(bufferevent *bev, short events, void *ptr) {
|
||||
auto * clientDesc = static_cast<LPCLIENT_DESC>(ptr);
|
||||
|
||||
if (events & BEV_EVENT_CONNECTED) {
|
||||
sys_log(0, "SYSTEM: connected to server (ptr %p)", clientDesc);
|
||||
clientDesc->OnConnectSuccessful();
|
||||
|
||||
// Now that we're connected, we can set the read/write/event handlers (and therefore stop using this handler)
|
||||
auto * desc = static_cast<LPDESC>(clientDesc);
|
||||
bufferevent_setcb(bev, DescReadHandler, DescWriteHandler, DescEventHandler, desc);
|
||||
} else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
|
||||
if (events & BEV_EVENT_ERROR) {
|
||||
int err = bufferevent_socket_get_dns_error(bev);
|
||||
if (err)
|
||||
sys_err("SYSTEM: Client connection DNS error: %s", evutil_gai_strerror(err));
|
||||
}
|
||||
|
||||
sys_log(0, "SYSTEM: closing client connection (ptr %p)", clientDesc);
|
||||
clientDesc->SetPhase(PHASE_CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
CLIENT_DESC::CLIENT_DESC()
|
||||
{
|
||||
m_iPhaseWhenSucceed = 0;
|
||||
@@ -49,9 +65,8 @@ CLIENT_DESC::~CLIENT_DESC()
|
||||
|
||||
void CLIENT_DESC::Destroy()
|
||||
{
|
||||
if (m_sock == INVALID_SOCKET) {
|
||||
if (m_bufevent == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
P2P_MANAGER::instance().UnregisterConnector(this);
|
||||
|
||||
@@ -63,12 +78,10 @@ void CLIENT_DESC::Destroy()
|
||||
DBManager::instance().StopAllBilling();
|
||||
}
|
||||
|
||||
fdwatch_del_fd(m_lpFdw, m_sock);
|
||||
sys_log(0, "SYSTEM: closing client socket.");
|
||||
|
||||
sys_log(0, "SYSTEM: closing client socket. DESC #%d", m_sock);
|
||||
|
||||
socket_close(m_sock);
|
||||
m_sock = INVALID_SOCKET;
|
||||
bufferevent_free(m_bufevent);
|
||||
m_bufevent = nullptr;
|
||||
|
||||
// Chain up to base class Destroy()
|
||||
DESC::Destroy();
|
||||
@@ -89,38 +102,41 @@ bool CLIENT_DESC::Connect(int iPhaseWhenSucceed)
|
||||
|
||||
m_LastTryToConnectTime = get_global_time();
|
||||
|
||||
if (m_sock != INVALID_SOCKET)
|
||||
if (m_bufevent != nullptr)
|
||||
return false;
|
||||
|
||||
sys_log(0, "SYSTEM: Trying to connect to %s:%d", m_stHost.c_str(), m_wPort);
|
||||
|
||||
m_sock = socket_connect(m_stHost.c_str(), m_wPort);
|
||||
if (m_evbase == nullptr) {
|
||||
sys_err("SYSTEM: event base not set!");
|
||||
return false;
|
||||
}
|
||||
if (m_dnsBase == nullptr) {
|
||||
sys_err("SYSTEM: DNS event base not set!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_sock != INVALID_SOCKET)
|
||||
{
|
||||
sys_log(0, "SYSTEM: connected to server (fd %d, ptr %p)", m_sock, this);
|
||||
fdwatch_add_fd(m_lpFdw, m_sock, this, FDW_READ, false);
|
||||
fdwatch_add_fd(m_lpFdw, m_sock, this, FDW_WRITE, false);
|
||||
SetPhase(m_iPhaseWhenSucceed);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPhase(PHASE_CLIENT_CONNECTING);
|
||||
return false;
|
||||
}
|
||||
m_bufevent = bufferevent_socket_new(m_evbase, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
bufferevent_setcb(m_bufevent, NULL, NULL, ClientDescEventHandler, this);
|
||||
bufferevent_enable(m_bufevent, EV_READ|EV_WRITE);
|
||||
bufferevent_socket_connect_hostname(m_bufevent, m_dnsBase, AF_UNSPEC, m_stHost.c_str(), m_wPort);
|
||||
|
||||
SetPhase(PHASE_CLIENT_CONNECTING);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLIENT_DESC::Setup(LPFDWATCH _fdw, const char * _host, WORD _port)
|
||||
void CLIENT_DESC::OnConnectSuccessful() {
|
||||
sys_log(0, "SYSTEM: connected to server (ptr %p)", this);
|
||||
SetPhase(m_iPhaseWhenSucceed);
|
||||
}
|
||||
|
||||
void CLIENT_DESC::Setup(event_base* base, evdns_base * dns_base, const char * _host, WORD _port)
|
||||
{
|
||||
// 1MB input/output buffer
|
||||
m_lpFdw = _fdw;
|
||||
m_evbase = base;
|
||||
m_dnsBase = dns_base;
|
||||
m_stHost = _host;
|
||||
m_wPort = _port;
|
||||
|
||||
InitializeBuffers();
|
||||
|
||||
m_sock = INVALID_SOCKET;
|
||||
m_bufevent = nullptr;
|
||||
}
|
||||
|
||||
void CLIENT_DESC::SetPhase(int iPhase)
|
||||
@@ -196,9 +212,6 @@ void CLIENT_DESC::SetPhase(int iPhase)
|
||||
strncpy(pck.szSocialID, r.social_id, sizeof(pck.szSocialID));
|
||||
strncpy(pck.szHost, d->GetHostName(), sizeof(pck.szHost));
|
||||
pck.dwLoginKey = d->GetLoginKey();
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
memcpy(pck.adwClientKey, d->GetDecryptionKey(), 16);
|
||||
#endif
|
||||
|
||||
buf.write(&pck, sizeof(TPacketLoginOnSetup));
|
||||
}
|
||||
@@ -224,13 +237,6 @@ void CLIENT_DESC::SetPhase(int iPhase)
|
||||
|
||||
case PHASE_P2P:
|
||||
sys_log(1, "PHASE_P2P");
|
||||
|
||||
if (m_lpInputBuffer)
|
||||
buffer_reset(m_lpInputBuffer);
|
||||
|
||||
if (m_lpOutputBuffer)
|
||||
buffer_reset(m_lpOutputBuffer);
|
||||
|
||||
m_pInputProcessor = &m_inputP2P;
|
||||
break;
|
||||
|
||||
@@ -250,33 +256,34 @@ void CLIENT_DESC::SetPhase(int iPhase)
|
||||
|
||||
void CLIENT_DESC::DBPacketHeader(BYTE bHeader, DWORD dwHandle, DWORD dwSize)
|
||||
{
|
||||
buffer_write(m_lpOutputBuffer, encode_byte(bHeader), sizeof(BYTE));
|
||||
buffer_write(m_lpOutputBuffer, encode_4bytes(dwHandle), sizeof(DWORD));
|
||||
buffer_write(m_lpOutputBuffer, encode_4bytes(dwSize), sizeof(DWORD));
|
||||
DESC::RawPacket(encode_byte(bHeader), sizeof(BYTE));
|
||||
DESC::RawPacket(encode_4bytes(dwHandle), sizeof(DWORD));
|
||||
DESC::RawPacket(encode_4bytes(dwSize), sizeof(DWORD));
|
||||
}
|
||||
|
||||
void CLIENT_DESC::DBPacket(BYTE bHeader, DWORD dwHandle, const void * c_pvData, DWORD dwSize)
|
||||
{
|
||||
if (m_sock == INVALID_SOCKET) {
|
||||
if (m_bufevent == nullptr) {
|
||||
sys_log(0, "CLIENT_DESC [%s] trying DBPacket() while not connected",
|
||||
GetKnownClientDescName(this));
|
||||
return;
|
||||
}
|
||||
sys_log(1, "DB_PACKET: header %d handle %d size %d buffer_size %d", bHeader, dwHandle, dwSize, buffer_size(m_lpOutputBuffer));
|
||||
sys_log(1, "DB_PACKET: header %d handle %d size %d", bHeader, dwHandle, dwSize);
|
||||
DBPacketHeader(bHeader, dwHandle, dwSize);
|
||||
|
||||
if (c_pvData)
|
||||
buffer_write(m_lpOutputBuffer, c_pvData, dwSize);
|
||||
DESC::RawPacket(c_pvData, dwSize);
|
||||
}
|
||||
|
||||
void CLIENT_DESC::Packet(const void * c_pvData, int iSize)
|
||||
{
|
||||
if (m_sock == INVALID_SOCKET) {
|
||||
if (m_bufevent == nullptr) {
|
||||
sys_log(0, "CLIENT_DESC [%s] trying Packet() while not connected",
|
||||
GetKnownClientDescName(this));
|
||||
return;
|
||||
}
|
||||
buffer_write(m_lpOutputBuffer, c_pvData, iSize);
|
||||
|
||||
DESC::RawPacket(c_pvData, iSize);
|
||||
}
|
||||
|
||||
bool CLIENT_DESC::IsRetryWhenClosed()
|
||||
@@ -316,7 +323,7 @@ void CLIENT_DESC::UpdateChannelStatus(DWORD t, bool fForce)
|
||||
void CLIENT_DESC::Reset()
|
||||
{
|
||||
// Backup connection target info
|
||||
LPFDWATCH fdw = m_lpFdw;
|
||||
event_base * evbase = m_evbase;
|
||||
std::string host = m_stHost;
|
||||
WORD port = m_wPort;
|
||||
|
||||
@@ -324,16 +331,7 @@ void CLIENT_DESC::Reset()
|
||||
Initialize();
|
||||
|
||||
// Restore connection target info
|
||||
m_lpFdw = fdw;
|
||||
m_evbase = evbase;
|
||||
m_stHost = host;
|
||||
m_wPort = port;
|
||||
|
||||
InitializeBuffers();
|
||||
}
|
||||
|
||||
void CLIENT_DESC::InitializeBuffers()
|
||||
{
|
||||
m_lpOutputBuffer = buffer_new(1024 * 1024);
|
||||
m_lpInputBuffer = buffer_new(1024 * 1024);
|
||||
m_iMinInputBufferLen = 1024 * 1024;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user