mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-17 05:02:29 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
34
src/net/connection/ClientConnection.cpp
Normal file
34
src/net/connection/ClientConnection.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include "net/connection/ClientConnection.hpp"
|
||||
#include "net/Login.hpp"
|
||||
#include "client/ClientServices.hpp"
|
||||
|
||||
void ClientConnection::Cancel(int32_t errorCode) {
|
||||
this->Cleanup();
|
||||
|
||||
this->m_statusResult = 0;
|
||||
this->m_errorCode = errorCode;
|
||||
this->m_statusComplete = 1;
|
||||
|
||||
// TODO
|
||||
// LogConnectionStatus(this->m_statusCop, errorCode, 0);
|
||||
}
|
||||
|
||||
void ClientConnection::Cleanup() {
|
||||
if (this->m_cleanup) {
|
||||
this->m_cleanup();
|
||||
this->m_cleanup = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::Connect() {
|
||||
// TODO
|
||||
|
||||
this->m_cleanup = nullptr;
|
||||
this->m_statusCop = COP_CONNECT;
|
||||
this->m_errorCode = 7;
|
||||
this->m_statusComplete = 0;
|
||||
|
||||
// TODO
|
||||
|
||||
ClientServices::LoginConnection()->GetRealmList();
|
||||
}
|
||||
27
src/net/connection/ClientConnection.hpp
Normal file
27
src/net/connection/ClientConnection.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef NET_CONNECTION_CLIENT_CONNECTION_HPP
|
||||
#define NET_CONNECTION_CLIENT_CONNECTION_HPP
|
||||
|
||||
#include "net/connection/RealmConnection.hpp"
|
||||
#include "net/Types.hpp"
|
||||
|
||||
class RealmResponse;
|
||||
|
||||
class ClientConnection : public RealmConnection {
|
||||
public:
|
||||
// Member variables
|
||||
int32_t m_statusComplete = 1;
|
||||
int32_t m_statusResult = 1;
|
||||
WOWCS_OPS m_statusCop = COP_NONE;
|
||||
int32_t m_errorCode = 0;
|
||||
void (*m_cleanup)() = nullptr;
|
||||
|
||||
// Member functions
|
||||
ClientConnection(RealmResponse* realmResponse)
|
||||
: RealmConnection(realmResponse)
|
||||
{};
|
||||
void Cancel(int32_t errorCode);
|
||||
void Cleanup();
|
||||
void Connect();
|
||||
};
|
||||
|
||||
#endif
|
||||
66
src/net/connection/NetClient.cpp
Normal file
66
src/net/connection/NetClient.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "net/connection/NetClient.hpp"
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
HPROPCONTEXT s_propContext;
|
||||
|
||||
int32_t NetClient::s_clientCount;
|
||||
|
||||
void InitializePropContext() {
|
||||
if (PropGetSelectedContext() != s_propContext) {
|
||||
PropSelectContext(s_propContext);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t NetClient::Initialize() {
|
||||
STORM_ASSERT(this->m_netState == NS_UNINITIALIZED);
|
||||
|
||||
if (NetClient::s_clientCount == 0) {
|
||||
s_propContext = PropGetSelectedContext();
|
||||
|
||||
if (!WowConnection::InitOsNet(nullptr, InitializePropContext, 1, false)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
NetClient::s_clientCount++;
|
||||
|
||||
auto queueMem = SMemAlloc(sizeof(NETEVENTQUEUE), __FILE__, __LINE__, 0x0);
|
||||
auto queue = new (queueMem) NETEVENTQUEUE(this);
|
||||
this->m_netEventQueue = queue;
|
||||
|
||||
memset(this->m_handlers, 0, sizeof(this->m_handlers));
|
||||
memset(this->m_handlerParams, 0, sizeof(this->m_handlerParams));
|
||||
|
||||
auto connectionMem = SMemAlloc(sizeof(WowConnection), __FILE__, __LINE__, 0x0);
|
||||
auto connection = new (connectionMem) WowConnection(this, nullptr);
|
||||
this->m_serverConnection = connection;
|
||||
|
||||
this->m_netState = NS_INITIALIZED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NetClient::SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param) {
|
||||
this->m_handlers[msgId] = handler;
|
||||
this->m_handlerParams[msgId] = param;
|
||||
}
|
||||
|
||||
void NetClient::WCCantConnect(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void NetClient::WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void NetClient::WCDataReady(WowConnection* conn, uint32_t timeStamp, uint8_t* data, int32_t len) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void NetClient::WCDisconnected(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) {
|
||||
// TODO
|
||||
}
|
||||
56
src/net/connection/NetClient.hpp
Normal file
56
src/net/connection/NetClient.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef NET_CONNECTION_NET_CLIENT_HPP
|
||||
#define NET_CONNECTION_NET_CLIENT_HPP
|
||||
|
||||
#include "net/connection/WowConnectionResponse.hpp"
|
||||
#include "net/Types.hpp"
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
class NetClient;
|
||||
class WowConnection;
|
||||
|
||||
typedef int32_t (*MESSAGE_HANDLER)(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
|
||||
|
||||
class NETEVENTQUEUENODE : public TSLinkedNode<NETEVENTQUEUENODE> {
|
||||
public:
|
||||
};
|
||||
|
||||
class NETEVENTQUEUE {
|
||||
public:
|
||||
// Member variables
|
||||
NetClient* m_client;
|
||||
SCritSect m_critSect;
|
||||
STORM_LIST(NETEVENTQUEUENODE) m_eventQueue;
|
||||
|
||||
// Member functions
|
||||
NETEVENTQUEUE(NetClient* client)
|
||||
: m_client(client)
|
||||
{};
|
||||
};
|
||||
|
||||
class NetClient : public WowConnectionResponse {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_clientCount;
|
||||
|
||||
// Member variables
|
||||
NETSTATE m_netState = NS_UNINITIALIZED;
|
||||
MESSAGE_HANDLER m_handlers[NUM_MSG_TYPES];
|
||||
void* m_handlerParams[NUM_MSG_TYPES];
|
||||
NETEVENTQUEUE* m_netEventQueue = nullptr;
|
||||
WowConnection* m_serverConnection = nullptr;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr);
|
||||
virtual void WCCantConnect(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr);
|
||||
virtual void WCDisconnected(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr);
|
||||
virtual void WCDataReady(WowConnection* conn, uint32_t timeStamp, uint8_t* data, int32_t len);
|
||||
|
||||
// Member functions
|
||||
int32_t Initialize();
|
||||
void SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param);
|
||||
};
|
||||
|
||||
#endif
|
||||
29
src/net/connection/RealmConnection.cpp
Normal file
29
src/net/connection/RealmConnection.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "net/connection/RealmConnection.hpp"
|
||||
#include "net/Types.hpp"
|
||||
|
||||
int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
RealmConnection::RealmConnection(RealmResponse* realmResponse) {
|
||||
this->m_realmResponse = realmResponse;
|
||||
|
||||
// TODO
|
||||
|
||||
this->Initialize();
|
||||
|
||||
this->SetMessageHandler(SMSG_AUTH_CHALLENGE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_AUTH_RESPONSE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_ADDON_INFO, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_ENUM_CHARACTERS_RESULT, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CREATE_CHAR, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CHARACTER_LOGIN_FAILED, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_LOGOUT_COMPLETE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_LOGOUT_CANCEL_ACK, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_LOGOUT_RESPONSE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_DELETE_CHAR, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CACHE_VERSION, &RealmConnection::MessageHandler, this);
|
||||
|
||||
// TODO
|
||||
}
|
||||
22
src/net/connection/RealmConnection.hpp
Normal file
22
src/net/connection/RealmConnection.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef NET_CONNECTION_REALM_CONNECTION_HPP
|
||||
#define NET_CONNECTION_REALM_CONNECTION_HPP
|
||||
|
||||
#include "net/connection/NetClient.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
class RealmResponse;
|
||||
|
||||
class RealmConnection : public NetClient {
|
||||
public:
|
||||
// Static functions
|
||||
int32_t static MessageHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
|
||||
|
||||
// Member variables
|
||||
RealmResponse* m_realmResponse;
|
||||
|
||||
// Member functions
|
||||
RealmConnection(RealmResponse* realmResponse);
|
||||
};
|
||||
|
||||
#endif
|
||||
8
src/net/connection/RealmResponse.hpp
Normal file
8
src/net/connection/RealmResponse.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef NET_CONNECTION_REALM_RESPONSE_HPP
|
||||
#define NET_CONNECTION_REALM_RESPONSE_HPP
|
||||
|
||||
class RealmResponse {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
591
src/net/connection/WowConnection.cpp
Normal file
591
src/net/connection/WowConnection.cpp
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
#include "net/connection/WowConnection.hpp"
|
||||
#include "net/connection/WowConnectionNet.hpp"
|
||||
#include "net/connection/WowConnectionResponse.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
uint64_t WowConnection::s_countTotalBytes;
|
||||
int32_t WowConnection::s_destroyed;
|
||||
WowConnectionNet* WowConnection::s_network;
|
||||
ATOMIC32 WowConnection::s_numWowConnections;
|
||||
bool (*WowConnection::s_verifyAddr)(const NETADDR*);
|
||||
|
||||
int32_t WowConnection::CreateSocket() {
|
||||
int32_t sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// TODO
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int32_t WowConnection::InitOsNet(bool (*fcn)(const NETADDR*), void (*threadinit)(), int32_t numThreads, bool useEngine) {
|
||||
if (!WowConnection::s_network) {
|
||||
// TODO s_usedSocketBits logic
|
||||
// TODO WDataStore::StaticInitialize();
|
||||
|
||||
WowConnection::s_verifyAddr = fcn;
|
||||
WowConnection::s_destroyed = 0;
|
||||
|
||||
numThreads = std::min(numThreads, 32);
|
||||
|
||||
auto networkMem = SMemAlloc(sizeof(WowConnectionNet), __FILE__, __LINE__, 0x0);
|
||||
auto network = new (networkMem) WowConnectionNet(numThreads, threadinit);
|
||||
|
||||
WowConnection::s_network = network;
|
||||
WowConnection::s_network->PlatformInit(useEngine);
|
||||
WowConnection::s_network->Start();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WowConnection::WowConnection(WowConnectionResponse* response, void (*func)(void)) {
|
||||
// TODO
|
||||
|
||||
this->Init(response, func);
|
||||
|
||||
this->m_sock = -1;
|
||||
}
|
||||
|
||||
WowConnection::WowConnection(int32_t sock, sockaddr_in* addr, WowConnectionResponse* response) {
|
||||
// TODO
|
||||
|
||||
this->Init(response, nullptr);
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_sock = sock;
|
||||
this->m_connState = WOWC_CONNECTED;
|
||||
}
|
||||
|
||||
void WowConnection::AcquireResponseRef() {
|
||||
this->m_responseLock.Enter();
|
||||
|
||||
STORM_ASSERT(this->m_responseRef == 0 || this->GetState() == WOWC_LISTENING);
|
||||
|
||||
this->m_responseRef++;
|
||||
this->m_responseRefThread = SGetCurrentThreadId();
|
||||
|
||||
this->m_responseLock.Leave();
|
||||
}
|
||||
|
||||
void WowConnection::AddRef() {
|
||||
SInterlockedIncrement(&this->m_refCount);
|
||||
}
|
||||
|
||||
void WowConnection::CheckAccept() {
|
||||
for (int32_t i = 0; i < 10000; i++) {
|
||||
NETADDR addr;
|
||||
socklen_t addrLen = sizeof(addr);
|
||||
|
||||
int32_t sock = accept(this->m_sock, reinterpret_cast<sockaddr*>(&addr), &addrLen);
|
||||
if (sock < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (WowConnection::s_verifyAddr) {
|
||||
NETADDR verifyAddr;
|
||||
socklen_t verifyAddrLen = sizeof(verifyAddr);
|
||||
|
||||
getpeername(sock, reinterpret_cast<sockaddr*>(&verifyAddr), &verifyAddrLen);
|
||||
if (!WowConnection::s_verifyAddr(&verifyAddr)) {
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// RegisterSocket(sock);
|
||||
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
|
||||
auto connMem = SMemAlloc(sizeof(WowConnection), __FILE__, __LINE__, 0x0);
|
||||
auto conn = new (connMem) WowConnection(sock, reinterpret_cast<sockaddr_in*>(&addr), this->m_response);
|
||||
conn->AddRef();
|
||||
|
||||
this->AddRef();
|
||||
this->AcquireResponseRef();
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
if (this->m_response) {
|
||||
this->m_response->WCConnected(this, conn, OsGetAsyncTimeMs(), &conn->m_peer);
|
||||
}
|
||||
|
||||
WowConnection::s_network->Add(conn);
|
||||
WowConnection::s_network->PlatformChangeState(conn, conn->GetState());
|
||||
|
||||
conn->Release();
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->ReleaseResponseRef();
|
||||
|
||||
this->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnection::CheckConnect() {
|
||||
int32_t err;
|
||||
socklen_t errLen = sizeof(err);
|
||||
if (getsockopt(this->m_sock, SOL_SOCKET, SO_ERROR, &err, &errLen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
WowConnection::s_network->Remove(this);
|
||||
|
||||
WowConnection::CloseSocket(this->m_sock);
|
||||
this->m_sock = -1;
|
||||
|
||||
this->SetState(WOWC_DISCONNECTED);
|
||||
this->AddRef();
|
||||
this->AcquireResponseRef();
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
if (this->m_response) {
|
||||
this->m_response->WCCantConnect(this, OsGetAsyncTimeMsPrecise(), &this->m_peer);
|
||||
}
|
||||
} else {
|
||||
this->SetState(WOWC_CONNECTED);
|
||||
this->AddRef();
|
||||
this->AcquireResponseRef();
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
socklen_t peerLen = sizeof(this->m_peer.peerAddr);
|
||||
getpeername(this->m_sock, reinterpret_cast<sockaddr*>(&this->m_peer.peerAddr), &peerLen);
|
||||
|
||||
socklen_t selfLen = sizeof(this->m_peer.selfAddr);
|
||||
getsockname(this->m_sock, reinterpret_cast<sockaddr*>(&this->m_peer.selfAddr), &selfLen);
|
||||
|
||||
if (this->m_response) {
|
||||
this->m_response->WCConnected(this, nullptr, OsGetAsyncTimeMsPrecise(), &this->m_peer);
|
||||
}
|
||||
}
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->ReleaseResponseRef();
|
||||
this->Release();
|
||||
}
|
||||
|
||||
void WowConnection::CloseSocket(int32_t sock) {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
closesocket(sock);
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
if (sock >= 0) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
bool WowConnection::Connect(char const* address, int32_t retryMs) {
|
||||
char host[256];
|
||||
auto port = SStrChr(address, ':');
|
||||
|
||||
if (port) {
|
||||
this->m_connectPort = SStrToInt(port + 1);
|
||||
|
||||
size_t portIndex = port - address + 1;
|
||||
portIndex = std::min(portIndex, sizeof(host));
|
||||
SStrCopy(host, address, portIndex);
|
||||
} else {
|
||||
this->m_connectPort = 0;
|
||||
|
||||
SStrCopy(host, address, sizeof(host));
|
||||
}
|
||||
|
||||
this->Connect(host, this->m_connectPort, retryMs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WowConnection::Connect(char const* address, uint16_t port, int32_t retryMs) {
|
||||
auto connectAddress = inet_addr(address);
|
||||
|
||||
if (connectAddress == -1 || connectAddress == 0) {
|
||||
auto entry = gethostbyname(address);
|
||||
if (entry) {
|
||||
auto addrs = reinterpret_cast<uint8_t**>(entry->h_addr_list);
|
||||
auto addr0 = addrs[0];
|
||||
this->m_connectAddress = addr0[0]
|
||||
| addr0[1] << 8
|
||||
| addr0[2] << 16
|
||||
| addr0[3] << 24;
|
||||
} else {
|
||||
this->m_connectAddress = 0;
|
||||
}
|
||||
} else {
|
||||
this->m_connectAddress = connectAddress;
|
||||
}
|
||||
|
||||
this->m_connectPort = port;
|
||||
|
||||
this->StartConnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WowConnection::Disconnect() {
|
||||
this->m_lock.Enter();
|
||||
|
||||
if (this->m_sock >= 0 && this->GetState() == WOWC_CONNECTED) {
|
||||
this->m_connState = WOWC_DISCONNECTING;
|
||||
|
||||
if (WowConnection::s_network) {
|
||||
WowConnection::s_network->PlatformChangeState(this, WOWC_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
this->m_lock.Leave();
|
||||
}
|
||||
|
||||
void WowConnection::DoDisconnect() {
|
||||
this->m_lock.Enter();
|
||||
|
||||
if (this->m_sock >= 0) {
|
||||
WowConnection::s_network->Remove(this);
|
||||
this->CloseSocket(this->m_sock);
|
||||
}
|
||||
|
||||
this->SetState(WOWC_DISCONNECTED);
|
||||
|
||||
this->AddRef();
|
||||
this->AcquireResponseRef();
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
if (this->m_response && this->m_sock >= 0) {
|
||||
// TODO
|
||||
// this->m_response->Vfunc4(this, OsGetAsyncTimeMsPrecise());
|
||||
}
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->m_sock = -1;
|
||||
this->ReleaseResponseRef();
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
this->Release();
|
||||
}
|
||||
|
||||
void WowConnection::DoExceptions() {
|
||||
this->AddRef();
|
||||
this->m_lock.Enter();
|
||||
|
||||
if (this->GetState() == WOWC_CONNECTING) {
|
||||
this->CheckConnect();
|
||||
}
|
||||
|
||||
this->m_lock.Leave();
|
||||
this->Release();
|
||||
}
|
||||
|
||||
void WowConnection::DoMessageReads() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnection::DoReads() {
|
||||
this->AddRef();
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
if (this->m_connState == WOWC_LISTENING) {
|
||||
this->CheckAccept();
|
||||
} else if (this->m_connState == WOWC_CONNECTED) {
|
||||
if (this->m_type == WOWC_TYPE_STREAM) {
|
||||
this->DoStreamReads();
|
||||
} else {
|
||||
this->DoMessageReads();
|
||||
}
|
||||
}
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
this->Release();
|
||||
}
|
||||
|
||||
void WowConnection::DoStreamReads() {
|
||||
uint32_t startTime = OsGetAsyncTimeMsPrecise();
|
||||
uint8_t buf[4096];
|
||||
uint32_t bytesRead;
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
bytesRead = recv(this->m_sock, buf, sizeof(buf), 0);
|
||||
|
||||
if (bytesRead >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
if (WSAGetLastError() != WSAEINTR) {
|
||||
break;
|
||||
}
|
||||
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
if (errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bytesRead == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
this->AcquireResponseRef();
|
||||
this->m_lock.Leave();
|
||||
|
||||
if (this->m_response) {
|
||||
this->m_response->WCDataReady(this, OsGetAsyncTimeMs(), buf, bytesRead);
|
||||
}
|
||||
|
||||
this->m_lock.Enter();
|
||||
this->ReleaseResponseRef();
|
||||
|
||||
if (this->GetState() == WOWC_DISCONNECTING || (OsGetAsyncTimeMsPrecise() - startTime) >= 5) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldDisconnect = false;
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
shouldDisconnect = bytesRead >= 0 || WSAGetLastError() != WSAEAGAIN;
|
||||
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
shouldDisconnect = bytesRead >= 0 || errno != EAGAIN;
|
||||
#endif
|
||||
|
||||
if (shouldDisconnect) {
|
||||
this->AcquireResponseRef();
|
||||
|
||||
WowConnection::s_network->Remove(this);
|
||||
this->CloseSocket(this->m_sock);
|
||||
this->SetState(WOWC_DISCONNECTED);
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
if (this->m_response && this->m_sock >= 0) {
|
||||
this->m_response->WCDisconnected(this, OsGetAsyncTimeMs(), &this->m_peer);
|
||||
}
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->m_sock = -1;
|
||||
|
||||
this->ReleaseResponseRef();
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnection::DoWrites() {
|
||||
this->AddRef();
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
if (this->m_connState == WOWC_CONNECTING) {
|
||||
this->CheckConnect();
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
this->Release();
|
||||
}
|
||||
|
||||
WOW_CONN_STATE WowConnection::GetState() {
|
||||
return this->m_connState;
|
||||
}
|
||||
|
||||
void WowConnection::Init(WowConnectionResponse* response, void (*func)(void)) {
|
||||
SInterlockedIncrement(&WowConnection::s_numWowConnections);
|
||||
|
||||
this->m_refCount = 1;
|
||||
this->m_responseRef = 0;
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_connState = WOWC_UNINITIALIZED;
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_response = response;
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_connectAddress = 0;
|
||||
this->m_connectPort = 0;
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_serviceFlags = 0x0;
|
||||
this->m_serviceCount = 0;
|
||||
|
||||
// TODO
|
||||
|
||||
this->SetState(WOWC_INITIALIZED);
|
||||
this->m_type = WOWC_TYPE_MESSAGES;
|
||||
}
|
||||
|
||||
void WowConnection::Release() {
|
||||
if (SInterlockedDecrement(&this->m_refCount) <= 0) {
|
||||
if (WowConnection::s_network) {
|
||||
WowConnection::s_network->Delete(this);
|
||||
} else {
|
||||
// TODO SMemFree
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnection::ReleaseResponseRef() {
|
||||
this->m_responseLock.Enter();
|
||||
|
||||
STORM_ASSERT(this->m_responseRef > 0);
|
||||
|
||||
this->m_responseRef--;
|
||||
|
||||
// TODO
|
||||
// dwordD4 = (void *)this->dwordD4;
|
||||
// if (dwordD4) {
|
||||
// this->m_response = dwordD4;
|
||||
// this->dwordD4 = 0;
|
||||
// }
|
||||
|
||||
this->m_responseLock.Leave();
|
||||
}
|
||||
|
||||
WC_SEND_RESULT WowConnection::SendRaw(uint8_t* data, int32_t len, bool a4) {
|
||||
WowConnection::s_countTotalBytes += len;
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
// TODO
|
||||
|
||||
if (len > 0 && this->m_connState == WOWC_CONNECTED) {
|
||||
STORM_ASSERT(this->m_sock >= 0);
|
||||
|
||||
#if defined (WHOA_SYSTEM_WIN)
|
||||
// TODO
|
||||
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
if (this->m_sendList.Head()) {
|
||||
// TODO
|
||||
} else {
|
||||
auto written = write(this->m_sock, data, len);
|
||||
|
||||
if (written <= 0) {
|
||||
// TODO
|
||||
} else if (written == len) {
|
||||
this->m_lock.Leave();
|
||||
return WC_SEND_SENT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
this->m_lock.Leave();
|
||||
|
||||
return WC_SEND_ERROR;
|
||||
}
|
||||
|
||||
void WowConnection::SetState(WOW_CONN_STATE state) {
|
||||
WOW_CONN_STATE oldState = this->m_connState;
|
||||
this->m_connState = state;
|
||||
|
||||
if (WowConnection::s_network) {
|
||||
WowConnection::s_network->PlatformChangeState(this, oldState);
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnection::SetType(WOWC_TYPE type) {
|
||||
this->m_lock.Enter();
|
||||
this->m_type = type;
|
||||
this->m_lock.Leave();
|
||||
}
|
||||
|
||||
void WowConnection::StartConnect() {
|
||||
if (this->m_sock >= 0) {
|
||||
if (this->m_netlink.IsLinked()) {
|
||||
WowConnection::s_network->Remove(this);
|
||||
}
|
||||
|
||||
this->CloseSocket(this->m_sock);
|
||||
this->m_sock = -1;
|
||||
}
|
||||
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->m_sock = WowConnection::CreateSocket();
|
||||
|
||||
if (this->m_sock < 0) {
|
||||
this->SetState(WOWC_ERROR);
|
||||
this->m_lock.Leave();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
fcntl(this->m_sock, F_SETFL, O_NONBLOCK);
|
||||
|
||||
uint32_t opt = 1;
|
||||
setsockopt(this->m_sock, SOL_SOCKET, 4130, &opt, sizeof(opt));
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(this->m_connectPort);
|
||||
addr.sin_addr.s_addr = this->m_connectAddress;
|
||||
|
||||
if (!this->m_netlink.IsLinked()) {
|
||||
WowConnection::s_network->Add(this);
|
||||
}
|
||||
|
||||
this->SetState(WOWC_CONNECTING);
|
||||
|
||||
if (connect(this->m_sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) >= 0) {
|
||||
this->m_lock.Leave();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS) {
|
||||
this->m_lock.Leave();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WowConnection::s_network->Remove(this);
|
||||
this->CloseSocket(this->m_sock);
|
||||
this->m_sock = -1;
|
||||
|
||||
this->SetState(WOWC_ERROR);
|
||||
|
||||
this->m_lock.Leave();
|
||||
#endif
|
||||
}
|
||||
87
src/net/connection/WowConnection.hpp
Normal file
87
src/net/connection/WowConnection.hpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef NET_CONNECTION_WOW_CONNECTION_HPP
|
||||
#define NET_CONNECTION_WOW_CONNECTION_HPP
|
||||
|
||||
#include "net/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Atomic.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
class WowConnectionNet;
|
||||
class WowConnectionResponse;
|
||||
|
||||
class WowConnection {
|
||||
public:
|
||||
// Types
|
||||
struct SENDNODE : public TSLinkedNode<SENDNODE> {
|
||||
uint8_t* data;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
uint32_t datasize;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static uint64_t s_countTotalBytes;
|
||||
static int32_t s_destroyed;
|
||||
static WowConnectionNet* s_network;
|
||||
static ATOMIC32 s_numWowConnections;
|
||||
static bool (*s_verifyAddr)(const NETADDR*);
|
||||
|
||||
// Static functions
|
||||
static int32_t CreateSocket();
|
||||
static int32_t InitOsNet(bool (*fcn)(const NETADDR*), void (*threadinit)(), int32_t numThreads, bool useEngine);
|
||||
|
||||
// Member variables
|
||||
ATOMIC32 m_refCount;
|
||||
int32_t m_sock;
|
||||
WOW_CONN_STATE m_connState;
|
||||
WowConnectionResponse* m_response;
|
||||
uint32_t m_connectAddress;
|
||||
uint16_t m_connectPort;
|
||||
NETCONNADDR m_peer;
|
||||
SCritSect m_responseLock;
|
||||
int32_t m_responseRef;
|
||||
uintptr_t m_responseRefThread;
|
||||
STORM_LIST(SENDNODE) m_sendList;
|
||||
uint32_t m_serviceFlags;
|
||||
TSLink<WowConnection> m_netlink;
|
||||
SCritSect m_lock;
|
||||
ATOMIC32 m_serviceCount;
|
||||
WOWC_TYPE m_type;
|
||||
|
||||
// Member functions
|
||||
WowConnection(WowConnectionResponse* response, void (*func)(void));
|
||||
WowConnection(int32_t sock, sockaddr_in* addr, WowConnectionResponse* response);
|
||||
void AcquireResponseRef();
|
||||
void AddRef();
|
||||
void CheckAccept();
|
||||
void CheckConnect();
|
||||
void CloseSocket(int32_t sock);
|
||||
bool Connect(char const* address, int32_t retryMs);
|
||||
bool Connect(char const* address, uint16_t port, int32_t retryMs);
|
||||
void Disconnect();
|
||||
void DoDisconnect();
|
||||
void DoExceptions();
|
||||
void DoMessageReads();
|
||||
void DoReads();
|
||||
void DoStreamReads();
|
||||
void DoWrites();
|
||||
WOW_CONN_STATE GetState();
|
||||
void Init(WowConnectionResponse* response, void (*func)(void));
|
||||
void Release();
|
||||
void ReleaseResponseRef();
|
||||
WC_SEND_RESULT SendRaw(uint8_t* data, int32_t len, bool a4);
|
||||
void SetState(WOW_CONN_STATE state);
|
||||
void SetType(WOWC_TYPE type);
|
||||
void StartConnect();
|
||||
};
|
||||
|
||||
#endif
|
||||
166
src/net/connection/WowConnectionNet.cpp
Normal file
166
src/net/connection/WowConnectionNet.cpp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
#include "net/connection/WowConnectionNet.hpp"
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include <storm/Atomic.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
uint32_t MainProc(void* param) {
|
||||
auto network = static_cast<WowConnectionNet*>(param);
|
||||
network->Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t WorkerProc(void* param) {
|
||||
auto worker = static_cast<WowConnectionNet::Worker*>(param);
|
||||
worker->owner->RunWorker(worker->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WowConnectionNet::Add(WowConnection* connection) {
|
||||
this->m_connectionsLock.Enter();
|
||||
|
||||
if (!this->m_connections.IsLinked(connection)) {
|
||||
this->m_connections.LinkToTail(connection);
|
||||
this->PlatformAdd(connection);
|
||||
}
|
||||
|
||||
this->m_connectionsLock.Leave();
|
||||
}
|
||||
|
||||
void WowConnectionNet::Delete(WowConnection* connection) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::Remove(WowConnection* connection) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::Run() {
|
||||
this->PlatformRun();
|
||||
this->m_stopEvent.Set();
|
||||
}
|
||||
|
||||
void WowConnectionNet::RunWorker(int32_t id) {
|
||||
if (this->m_threadinit) {
|
||||
this->m_threadinit();
|
||||
}
|
||||
|
||||
this->m_workerSem.Signal(1);
|
||||
|
||||
auto& worker = this->m_workers[id];
|
||||
|
||||
while (true) {
|
||||
do {
|
||||
// TODO worker.time40 = OsGetAsyncTimeMsPrecise();
|
||||
} while (worker.event.Wait(1000));
|
||||
|
||||
if (worker.quit) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto serviceConn = worker.serviceConn;
|
||||
auto serviceFlags = serviceConn->m_serviceFlags;
|
||||
serviceConn->m_serviceFlags = 0;
|
||||
|
||||
this->Service(worker.serviceConn, serviceFlags);
|
||||
|
||||
worker.lock.Enter();
|
||||
|
||||
SInterlockedDecrement(&serviceConn->m_serviceCount);
|
||||
serviceConn->Release();
|
||||
worker.serviceConn = nullptr;
|
||||
|
||||
worker.lock.Leave();
|
||||
|
||||
this->m_workerSem.Signal(1);
|
||||
this->PlatformWorkerReady();
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnectionNet::Service(WowConnection* connection, uint32_t serviceFlags) {
|
||||
while (serviceFlags) {
|
||||
if (serviceFlags & 0x1) {
|
||||
connection->DoWrites();
|
||||
}
|
||||
|
||||
if (serviceFlags & 0x2) {
|
||||
connection->DoReads();
|
||||
}
|
||||
|
||||
if (serviceFlags & 0x4) {
|
||||
connection->DoExceptions();
|
||||
}
|
||||
|
||||
if (serviceFlags & 0x8) {
|
||||
connection->DoDisconnect();
|
||||
}
|
||||
|
||||
this->m_connectionsLock.Enter();
|
||||
|
||||
serviceFlags = connection->m_serviceFlags;
|
||||
connection->m_serviceFlags = 0;
|
||||
|
||||
this->m_connectionsLock.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnectionNet::SignalWorker(WowConnection* connection, uint32_t flags) {
|
||||
if (!this->m_workerSem.Wait(500)) {
|
||||
connection->AddRef();
|
||||
connection->m_serviceFlags = flags;
|
||||
SInterlockedIncrement(&connection->m_serviceCount);
|
||||
|
||||
int32_t i = 0;
|
||||
while (1) {
|
||||
this->m_workers[i].lock.Enter();
|
||||
|
||||
if (!this->m_workers[i].serviceConn) {
|
||||
break;
|
||||
}
|
||||
|
||||
STORM_ASSERT(this->m_workers[i].serviceConn != connection);
|
||||
|
||||
this->m_workers[i].lock.Leave();
|
||||
|
||||
i++;
|
||||
|
||||
STORM_ASSERT(i < this->m_numWorkers);
|
||||
}
|
||||
|
||||
this->m_workers[i].serviceConn = connection;
|
||||
this->m_workers[i].lock.Leave();
|
||||
this->m_workers[i].event.Set();
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnectionNet::Start() {
|
||||
for (int32_t i = 0; i < this->m_numWorkers; i++) {
|
||||
auto worker = &this->m_workers[i];
|
||||
|
||||
worker->id = i;
|
||||
worker->serviceConn = nullptr;
|
||||
worker->quit = 0;
|
||||
worker->owner = this;
|
||||
// TODO worker.time40 = OsGetAsyncTimeMsPrecise();
|
||||
|
||||
char name[32];
|
||||
SStrPrintf(name, sizeof(name), "NetThread %d", i);
|
||||
|
||||
SThread::Create(&WorkerProc, worker, worker->thread, name, 0);
|
||||
}
|
||||
|
||||
char name[32];
|
||||
SStrPrintf(name, sizeof(name), "Network");
|
||||
|
||||
// TODO BYTE1(this->dword8EC) = 0;
|
||||
|
||||
SThread::Create(&MainProc, this, this->m_thread, name, 0);
|
||||
|
||||
// TODO
|
||||
// while (!BYTE1(this->dword8EC)) {
|
||||
// OsSleep(100);
|
||||
// }
|
||||
}
|
||||
55
src/net/connection/WowConnectionNet.hpp
Normal file
55
src/net/connection/WowConnectionNet.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef NET_CONNECTION_WOW_CONNECTION_NET_HPP
|
||||
#define NET_CONNECTION_WOW_CONNECTION_NET_HPP
|
||||
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class WowConnectionNet {
|
||||
public:
|
||||
// Types
|
||||
struct Worker {
|
||||
WowConnectionNet* owner;
|
||||
SThread thread;
|
||||
int32_t id;
|
||||
WowConnection* serviceConn;
|
||||
SEvent event = SEvent(0, 0);
|
||||
int8_t quit;
|
||||
SCritSect lock;
|
||||
};
|
||||
|
||||
// Member variables
|
||||
SThread m_thread;
|
||||
SEvent m_stopEvent = SEvent(1, 0);
|
||||
uint8_t m_stop;
|
||||
int32_t m_numWorkers;
|
||||
Worker m_workers[32];
|
||||
SCritSect m_connectionsLock;
|
||||
STORM_EXPLICIT_LIST(WowConnection, m_netlink) m_connections;
|
||||
SSemaphore m_workerSem;
|
||||
void (*m_threadinit)();
|
||||
|
||||
// Member functions
|
||||
WowConnectionNet(uint32_t numThreads, void (*threadinit)())
|
||||
: m_workerSem(0, numThreads)
|
||||
, m_numWorkers(numThreads)
|
||||
, m_threadinit(threadinit)
|
||||
, m_stop(0)
|
||||
{};
|
||||
void Add(WowConnection* connection);
|
||||
void Delete(WowConnection* connection);
|
||||
void PlatformAdd(WowConnection* connection);
|
||||
void PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state);
|
||||
void PlatformInit(bool useEngine);
|
||||
void PlatformRun();
|
||||
void PlatformWorkerReady();
|
||||
void Remove(WowConnection* connection);
|
||||
void Run();
|
||||
void RunWorker(int32_t id);
|
||||
void Service(WowConnection* connection, uint32_t serviceFlags);
|
||||
void SignalWorker(WowConnection* connection, uint32_t flags);
|
||||
void Start();
|
||||
};
|
||||
|
||||
#endif
|
||||
175
src/net/connection/WowConnectionNetMac.cpp
Normal file
175
src/net/connection/WowConnectionNetMac.cpp
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
|
||||
#include "net/connection/WowConnectionNet.hpp"
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <storm/Array.hpp>
|
||||
|
||||
int32_t s_workerPipe[2];
|
||||
|
||||
void WowConnectionNet::PlatformAdd(WowConnection* connection) {
|
||||
uint32_t on = 1;
|
||||
setsockopt(connection->m_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
|
||||
char buf = '\1';
|
||||
write(s_workerPipe[1], &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state) {
|
||||
char buf = '\1';
|
||||
write(s_workerPipe[1], &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformInit(bool useEngine) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformRun() {
|
||||
pipe(s_workerPipe);
|
||||
|
||||
if (fcntl(s_workerPipe[0], F_SETFL, O_NONBLOCK) < 0) {
|
||||
perror("fcntl(worker pipe)");
|
||||
}
|
||||
|
||||
TSGrowableArray<WowConnection*> connections;
|
||||
char buf[25];
|
||||
|
||||
while (!this->m_stop) {
|
||||
timeval timeout = { 30, 0 };
|
||||
|
||||
fd_set readFds = {};
|
||||
fd_set writeFds = {};
|
||||
fd_set errorFds = {};
|
||||
|
||||
readFds.fds_bits[s_workerPipe[0] >> 5] |= 1 << (s_workerPipe[0] & 0x1F);
|
||||
|
||||
auto fdCount = s_workerPipe[0];
|
||||
|
||||
int32_t v39 = 0;
|
||||
int32_t v41 = 0;
|
||||
|
||||
this->m_connectionsLock.Enter();
|
||||
|
||||
for (auto connection = this->m_connections.Head(); connection; connection = this->m_connections.Link(connection)->Next()) {
|
||||
if (connection->m_serviceCount) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (connection->m_connState) {
|
||||
case WOWC_CONNECTING: {
|
||||
errorFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F);
|
||||
writeFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F);
|
||||
|
||||
connections.Add(1, &connection);
|
||||
connection->AddRef();
|
||||
fdCount = std::max(fdCount, connection->m_sock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WOWC_LISTENING: {
|
||||
readFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F);
|
||||
|
||||
connections.Add(1, &connection);
|
||||
connection->AddRef();
|
||||
fdCount = std::max(fdCount, connection->m_sock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WOWC_CONNECTED: {
|
||||
readFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F);
|
||||
errorFds.fds_bits[connection->m_sock >> 5] |= 1 << (connection->m_sock & 0x1F);
|
||||
|
||||
// TODO
|
||||
|
||||
connections.Add(1, &connection);
|
||||
connection->AddRef();
|
||||
fdCount = std::max(fdCount, connection->m_sock);
|
||||
}
|
||||
|
||||
case WOWC_DISCONNECTING: {
|
||||
// TODO
|
||||
|
||||
v41++;
|
||||
connections.Add(1, &connection);
|
||||
connection->AddRef();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->m_connectionsLock.Leave();
|
||||
|
||||
if (v41 > 0) {
|
||||
timeout = { 0, 0 };
|
||||
}
|
||||
|
||||
if (connections.Count() > 0) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
select(fdCount + 1, &readFds, &writeFds, &errorFds, &timeout);
|
||||
|
||||
auto v1 = s_workerPipe[0];
|
||||
if (((1 << (s_workerPipe[0] & 0x1F)) & readFds.fds_bits[s_workerPipe[0] >> 5]) != 0) {
|
||||
while (read(v1, buf, 1u) > 0) {
|
||||
v1 = s_workerPipe[0];
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < connections.Count(); i++) {
|
||||
auto connection = connections[i];
|
||||
uint32_t signalFlags = 0x0;
|
||||
|
||||
if (!(connection->m_sock & 0x80000000)) {
|
||||
if (FD_ISSET(connection->m_sock, &writeFds)) {
|
||||
signalFlags |= 0x1;
|
||||
}
|
||||
|
||||
if (FD_ISSET(connection->m_sock, &readFds)) {
|
||||
signalFlags |= 0x2;
|
||||
}
|
||||
|
||||
if (FD_ISSET(connection->m_sock, &errorFds)) {
|
||||
signalFlags |= 0x4;
|
||||
}
|
||||
}
|
||||
|
||||
if (connection->m_connState == WOWC_DISCONNECTING) {
|
||||
signalFlags |= 0x8;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// auto v15 = connection->dword10C;
|
||||
// if (!(v15 & 1) && v15) {
|
||||
// signalFlags |= 0x2;
|
||||
// }
|
||||
|
||||
if (signalFlags) {
|
||||
this->SignalWorker(connection, signalFlags);
|
||||
}
|
||||
|
||||
connection->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformWorkerReady() {
|
||||
char buf = '\1';
|
||||
write(s_workerPipe[1], &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
#endif
|
||||
25
src/net/connection/WowConnectionNetWin.cpp
Normal file
25
src/net/connection/WowConnectionNetWin.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#if defined(WHOA_SYSTEM_WIN)
|
||||
|
||||
#include "net/connection/WowConnectionNet.hpp"
|
||||
|
||||
void WowConnectionNet::PlatformAdd(WowConnection* connection) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformChangeState(WowConnection* connection, WOW_CONN_STATE state) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformInit(bool useEngine) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformRun() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WowConnectionNet::PlatformWorkerReady() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#endif
|
||||
17
src/net/connection/WowConnectionResponse.hpp
Normal file
17
src/net/connection/WowConnectionResponse.hpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef NET_CONNECTION_WOW_CONNECTION_RESPONSE_HPP
|
||||
#define NET_CONNECTION_WOW_CONNECTION_RESPONSE_HPP
|
||||
|
||||
#include "net/Types.hpp"
|
||||
|
||||
class WowConnection;
|
||||
|
||||
class WowConnectionResponse {
|
||||
public:
|
||||
// Virtual member functions
|
||||
virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr) = 0;
|
||||
virtual void WCCantConnect(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) = 0;
|
||||
virtual void WCDisconnected(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) {};
|
||||
virtual void WCDataReady(WowConnection* conn, uint32_t timeStamp, uint8_t* data, int32_t len) {};
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue