diff --git a/src/net/Types.hpp b/src/net/Types.hpp index b7792cd..7ea35e4 100644 --- a/src/net/Types.hpp +++ b/src/net/Types.hpp @@ -1174,6 +1174,7 @@ enum NETSTATE { NS_STATE_3 = 3, NS_CONNECTING = 4, NS_CONNECTED = 5, + NS_DISCONNECTING = 6 }; enum WOW_CONN_STATE { diff --git a/src/net/connection/ClientConnection.cpp b/src/net/connection/ClientConnection.cpp index e02187a..6ac0b53 100644 --- a/src/net/connection/ClientConnection.cpp +++ b/src/net/connection/ClientConnection.cpp @@ -100,7 +100,9 @@ void ClientConnection::Connect() { } int32_t ClientConnection::Disconnect() { - // TODO + this->NetClient::Disconnect(); + this->m_connected = 0; + // TODO: WardenClient_Destroy(); return 0; } diff --git a/src/net/connection/NetClient.cpp b/src/net/connection/NetClient.cpp index e60e6ec..c33f704 100644 --- a/src/net/connection/NetClient.cpp +++ b/src/net/connection/NetClient.cpp @@ -98,6 +98,12 @@ void NETEVENTQUEUE::Poll() { this->m_critSect.Leave(); } +void NETEVENTQUEUE::Clear() { + this->m_critSect.Enter(); + this->m_eventQueue.Clear(); + this->m_critSect.Leave(); +} + void NetClient::AddRef() { SInterlockedIncrement(&this->m_refCount); } @@ -144,6 +150,34 @@ void NetClient::Connect(const char* addrStr) { this->ConnectInternal(host, port); } +void NetClient::Disconnect() { + if (this->m_redirectConnection) { + // TODO: this->m_redirectConnection->SetResponse(0, 0); + this->m_redirectConnection->Disconnect(); + this->m_redirectConnection->Release(); + } + + if (this->m_netState == NS_CONNECTED) { + this->m_netState = NS_DISCONNECTING; + this->m_serverConnection->Disconnect(); + } else { + // TODO: this->m_serverConnection->SetResponse(0, 0); + this->m_serverConnection->Disconnect(); + this->m_netEventQueue->Clear(); + this->m_serverConnection->Release(); + + auto connectionMem = SMemAlloc(sizeof(WowConnection), __FILE__, __LINE__, 0x0); + if (connectionMem) { + auto connection = new (connectionMem) WowConnection(this, nullptr); + this->m_serverConnection = connection; + } else { + this->m_serverConnection = nullptr; + } + + this->m_netState = NS_INITIALIZED; + } +} + int32_t NetClient::ConnectInternal(const char* host, uint16_t port) { if (this->m_netState != NS_INITIALIZED) { SErrDisplayAppFatal("Expected (m_netState == NS_INITIALIZED), got %d", this->m_netState); diff --git a/src/net/connection/NetClient.hpp b/src/net/connection/NetClient.hpp index 7564e33..d6b587c 100644 --- a/src/net/connection/NetClient.hpp +++ b/src/net/connection/NetClient.hpp @@ -43,6 +43,7 @@ class NETEVENTQUEUE { {}; void AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes); void Poll(); + void Clear(); }; class NetClient : public WowConnectionResponse { @@ -62,6 +63,7 @@ class NetClient : public WowConnectionResponse { void AddRef(); void AuthChallengeHandler(WowConnection* conn, CDataStore* msg); void Connect(const char* addrStr); + void Disconnect(); int32_t ConnectInternal(const char* host, uint16_t port); void DelRef(); void EnableEncryption(WowConnection* conn, uint8_t* seed, uint8_t seedLen); diff --git a/src/ui/ScriptFunctionsCharSelect.cpp b/src/ui/ScriptFunctionsCharSelect.cpp index 122189f..a97d67a 100644 --- a/src/ui/ScriptFunctionsCharSelect.cpp +++ b/src/ui/ScriptFunctionsCharSelect.cpp @@ -55,7 +55,7 @@ int32_t Script_GetCharacterInfo(lua_State* L) { } int32_t index = static_cast(lua_tonumber(L, 1)) - 1; - if (index < 0 || index > CCharacterSelection::GetNumCharacters()) { + if (index < 0 || index >= CCharacterSelection::GetNumCharacters()) { lua_pushnil(L); // name lua_pushnil(L); // race lua_pushnil(L); // class