From afc6c3666bf4b4235b8541aed49c7edc043a0765 Mon Sep 17 00:00:00 2001 From: VDm Date: Sat, 12 Apr 2025 14:33:18 +0400 Subject: [PATCH] feat(net): add NetClient::Destroy method --- src/net/connection/NetClient.cpp | 99 +++++++++++++++++++++---- src/net/connection/NetClient.hpp | 5 ++ src/net/connection/WowConnection.cpp | 24 +++++- src/net/connection/WowConnection.hpp | 1 + src/net/connection/WowConnectionNet.cpp | 2 +- 5 files changed, 114 insertions(+), 17 deletions(-) diff --git a/src/net/connection/NetClient.cpp b/src/net/connection/NetClient.cpp index 0adcca4..22ee134 100644 --- a/src/net/connection/NetClient.cpp +++ b/src/net/connection/NetClient.cpp @@ -22,6 +22,11 @@ void InitializePropContext() { } } + +NETEVENTQUEUE::~NETEVENTQUEUE() { + this->Clear(); +} + void NETEVENTQUEUE::AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes) { this->m_critSect.Enter(); @@ -107,12 +112,27 @@ void NETEVENTQUEUE::Clear() { this->m_critSect.Leave(); } + +void NetClient::LogStats() { + char message[128]; + + uint32_t time = OsGetAsyncTimeMs(); + SStrPrintf( + message, + sizeof(message), + "Client net stats: %Lu bytes sent, %Lu bytes received, %Lu msec elapsed", + NetClient::s_stats.bytesSent, + NetClient::s_stats.bytesReceived, + time - s_stats.logTimestamp); + ConsoleWrite(message, DEFAULT_COLOR); +} + void NetClient::AddRef() { SInterlockedIncrement(&this->m_refCount); } void NetClient::AuthChallengeHandler(WowConnection* conn, CDataStore* msg) { - auto challenge = static_cast(SMemAlloc(sizeof(AuthenticationChallenge), __FILE__, __LINE__, 0x0)); + auto challenge = NEW(AuthenticationChallenge); uint32_t v14; msg->Get(v14); @@ -129,7 +149,7 @@ void NetClient::AuthChallengeHandler(WowConnection* conn, CDataStore* msg) { conn->Disconnect(); } - delete challenge; + DEL(challenge); } void NetClient::Connect(const char* addrStr) { @@ -155,7 +175,7 @@ void NetClient::Connect(const char* addrStr) { void NetClient::Disconnect() { if (this->m_redirectConnection) { - // TODO: this->m_redirectConnection->SetResponse(0, 0); + this->m_redirectConnection->SetResponse(nullptr, false); this->m_redirectConnection->Disconnect(); this->m_redirectConnection->Release(); } @@ -164,7 +184,7 @@ void NetClient::Disconnect() { this->m_netState = NS_DISCONNECTING; this->m_serverConnection->Disconnect(); } else { - // TODO: this->m_serverConnection->SetResponse(0, 0); + this->m_serverConnection->SetResponse(nullptr, false); this->m_serverConnection->Disconnect(); this->m_netEventQueue->Clear(); this->m_serverConnection->Release(); @@ -189,7 +209,12 @@ int32_t NetClient::ConnectInternal(const char* host, uint16_t port) { this->m_netState = NS_CONNECTING; this->m_serverConnection->Connect(host, port, -1); - // TODO + if (this->m_redirectConnection) { + this->m_redirectConnection->SetResponse(nullptr, false); + this->m_redirectConnection->Disconnect(); + this->m_redirectConnection->Release(); + this->m_redirectConnection = nullptr; + } return 1; } @@ -254,10 +279,21 @@ void NetClient::Ping() { } int32_t NetClient::HandleCantConnect() { - // TODO + this->PushObjMgr(); + + STORM_ASSERT(m_netState == NS_CONNECTING); + this->m_netState = NS_INITIALIZED; + + this->PopObjMgr(); + return 1; } +int32_t NetClient::ValidateMessageId(uint32_t msgId) { + // This method does nothing + return 0; +} + int32_t NetClient::HandleConnect() { this->PushObjMgr(); @@ -271,13 +307,17 @@ int32_t NetClient::HandleConnect() { int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) { this->PushObjMgr(); - CDataStore msg; - msg.m_data = static_cast(data); - msg.m_size = size; - msg.m_alloc = -1; - msg.m_read = 0; + NetClient::s_stats.bytesReceived += size + 2; - this->ProcessMessage(timeReceived, &msg, 0); + if (this->m_netState == NS_CONNECTED) { + CDataStore msg; + msg.m_data = static_cast(data); + msg.m_size = size; + msg.m_alloc = -1; + msg.m_read = 0; + + this->ProcessMessage(timeReceived, &msg, 0); + } this->PopObjMgr(); @@ -337,6 +377,37 @@ int32_t NetClient::Initialize() { return 1; } +void NetClient::Destroy() { + if (this->m_netState == NS_UNINITIALIZED) { + return; + } + + this->Disconnect(); + + this->m_serverConnection->SetResponse(nullptr, false); + this->m_serverConnection->Release(); + this->m_serverConnection = nullptr; + + memset(this->m_handlers, 0, sizeof(this->m_handlers)); + memset(this->m_handlerParams, 0, sizeof(this->m_handlerParams)); + + if (this->m_netEventQueue) { + DEL(this->m_netEventQueue); + } + this->m_netEventQueue = nullptr; + + if (--NetClient::s_clientCount == 0) { + OsSleep(1); + // TODO: WowConnection::DestroyOsNet(); + } + + this->m_netState = NS_UNINITIALIZED; + + if (NetClient::s_clientCount == 0) { + NetClient::LogStats(); + } +} + void NetClient::PollEventQueue() { this->m_netEventQueue->Poll(); } @@ -371,12 +442,12 @@ void NetClient::PongHandler(WowConnection* conn, CDataStore* msg) { } void NetClient::ProcessMessage(uint32_t timeReceived, CDataStore* msg, int32_t a4) { - // TODO s_stats.messagesReceived++ + ++NetClient::s_stats.messagesReceived; uint16_t msgId; msg->Get(msgId); - // TODO virtual function call on NetClient + this->ValidateMessageId(msgId); if (msgId >= NUM_MSG_TYPES || !this->m_handlers[msgId]) { msg->Reset(); diff --git a/src/net/connection/NetClient.hpp b/src/net/connection/NetClient.hpp index 5bbdb48..7785d59 100644 --- a/src/net/connection/NetClient.hpp +++ b/src/net/connection/NetClient.hpp @@ -41,6 +41,7 @@ class NETEVENTQUEUE { NETEVENTQUEUE(NetClient* client) : m_client(client) {}; + ~NETEVENTQUEUE(); void AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes); void Poll(); void Clear(); @@ -48,6 +49,8 @@ class NETEVENTQUEUE { class NetClient : public WowConnectionResponse { public: + static void LogStats(); + // Virtual member functions virtual void WCMessageReady(WowConnection* conn, uint32_t timeStamp, CDataStore* msg); virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr); @@ -58,6 +61,7 @@ class NetClient : public WowConnectionResponse { virtual int32_t HandleConnect(); virtual int32_t HandleDisconnect(); virtual int32_t HandleCantConnect(); + virtual int32_t ValidateMessageId(uint32_t msgId); // Member functions void AddRef(); @@ -73,6 +77,7 @@ class NetClient : public WowConnectionResponse { void Ping(); void HandleIdle(); int32_t Initialize(); + void Destroy(); void PollEventQueue(); void PongHandler(WowConnection* conn, CDataStore* msg); void ProcessMessage(uint32_t timeReceived, CDataStore* msg, int32_t a4); diff --git a/src/net/connection/WowConnection.cpp b/src/net/connection/WowConnection.cpp index 78cf4fb..d2f12dc 100644 --- a/src/net/connection/WowConnection.cpp +++ b/src/net/connection/WowConnection.cpp @@ -669,6 +669,27 @@ void WowConnection::Init(WowConnectionResponse* response, void (*func)(void)) { this->m_type = WOWC_TYPE_MESSAGES; } +void WowConnection::SetResponse(WowConnectionResponse* response, bool a3) { + while (1) { + this->m_responseLock.Enter(); + if (!this->m_responseRef || this->m_responseRefThread == SGetCurrentThreadId()) + break; + + if (a3) { + // this->off_53 = response; + this->m_responseLock.Leave(); + return; + } + + this->m_responseLock.Leave(); + OsSleep(50u); + } + + this->m_response = response; + // this->off_53 = nullptr; + this->m_responseLock.Leave(); +} + WowConnection::SENDNODE* WowConnection::NewSendNode(void* data, int32_t size, bool raw) { // TODO counters @@ -693,8 +714,7 @@ void WowConnection::Release() { if (WowConnection::s_network) { WowConnection::s_network->Delete(this); } else { - // TODO SMemFree - delete this; + DEL(this); } } } diff --git a/src/net/connection/WowConnection.hpp b/src/net/connection/WowConnection.hpp index 0433dfb..132535a 100644 --- a/src/net/connection/WowConnection.hpp +++ b/src/net/connection/WowConnection.hpp @@ -99,6 +99,7 @@ class WowConnection { void FreeSendNode(SENDNODE* sn); WOW_CONN_STATE GetState(); void Init(WowConnectionResponse* response, void (*func)(void)); + void SetResponse(WowConnectionResponse* response, bool a3); SENDNODE* NewSendNode(void* data, int32_t size, bool raw); void Release(); void ReleaseResponseRef(); diff --git a/src/net/connection/WowConnectionNet.cpp b/src/net/connection/WowConnectionNet.cpp index 2971ad1..04bab31 100644 --- a/src/net/connection/WowConnectionNet.cpp +++ b/src/net/connection/WowConnectionNet.cpp @@ -34,7 +34,7 @@ void WowConnectionNet::Delete(WowConnection* connection) { this->m_connectionsLock.Enter(); if (connection->m_refCount == 0) { - delete connection; + DEL(connection); } this->m_connectionsLock.Leave();