Compare commits

...

3 Commits

14 changed files with 214 additions and 59 deletions

View File

@ -190,7 +190,13 @@ void ClientServices::SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler
} }
void ClientServices::GetRealmList() { void ClientServices::GetRealmList() {
// TODO STORM_ASSERT(ClientServices::s_currentConnection);
ClientServices::s_currentConnection->Initiate(COP_GET_REALMS, 35, nullptr);
if (ClientServices::s_loginObj->IsLoggedOn()) {
ClientServices::s_loginObj->GetRealmList();
} else {
ClientServices::s_loginObj->Reconnect();
}
} }
void ClientServices::GetCharacterList() { void ClientServices::GetCharacterList() {
@ -367,6 +373,7 @@ void ClientServices::LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, c
void ClientServices::RealmEnumCallback(uint32_t a2) { void ClientServices::RealmEnumCallback(uint32_t a2) {
auto connection = ClientServices::Connection(); auto connection = ClientServices::Connection();
STORM_ASSERT(connection);
if (a2 == 1) { if (a2 == 1) {
connection->Complete(0, 23); connection->Complete(0, 23);
@ -378,7 +385,13 @@ void ClientServices::RealmEnumCallback(uint32_t a2) {
return; return;
} }
// TODO statusCop checks // TODO: Proper implementation
if (connection->m_statusCop != COP_CONNECT) {
if (connection->m_statusCop == COP_GET_REALMS) {
connection->Complete(1, 36);
}
return;
}
if (ClientServices::LoginConnection()->GetLoginServerType() == 1) { if (ClientServices::LoginConnection()->GetLoginServerType() == 1) {
// TODO Battlenet logic // TODO Battlenet logic

View File

@ -346,49 +346,54 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) {
int32_t complete = ClientServices::Connection()->PollStatus(op, &msg, result, errorCode); int32_t complete = ClientServices::Connection()->PollStatus(op, &msg, result, errorCode);
switch (CGlueMgr::m_idleState) { switch (CGlueMgr::m_idleState) {
case IDLE_LOGIN_SERVER_LOGIN: { case IDLE_LOGIN_SERVER_LOGIN: {
CGlueMgr::PollLoginServerLogin(); CGlueMgr::PollLoginServerLogin();
break; break;
}
case IDLE_ACCOUNT_LOGIN: {
CGlueMgr::PollAccountLogin(errorCode, msg, complete, result, op);
break;
}
case IDLE_CHARACTER_LIST: {
CGlueMgr::PollCharacterList(errorCode, msg, complete, result, op);
break;
}
case IDLE_DELETE_CHARACTER: {
CGlueMgr::PollDeleteCharacter(errorCode, msg, complete, result, op);
break;
}
case IDLE_ENTER_WORLD: {
CGlueMgr::PollEnterWorld();
break;
}
case IDLE_12: {
if (CGlueMgr::m_patchDownload) {
CGlueMgr::PatchDownloadIdle();
} else if (CGlueMgr::m_surveyDownload) {
CGlueMgr::SurveyDownloadIdle();
} }
break;
}
case IDLE_13: { case IDLE_ACCOUNT_LOGIN: {
CGlueMgr::PollUserSurvey(); CGlueMgr::PollAccountLogin(errorCode, msg, complete, result, op);
break; break;
} }
// TODO other idle states case IDLE_CHARACTER_LIST: {
CGlueMgr::PollCharacterList(errorCode, msg, complete, result, op);
break;
}
default: case IDLE_REALM_LIST: {
break; CGlueMgr::PollRealmList(errorCode, msg, complete, result, op);
break;
}
case IDLE_DELETE_CHARACTER: {
CGlueMgr::PollDeleteCharacter(errorCode, msg, complete, result, op);
break;
}
case IDLE_ENTER_WORLD: {
CGlueMgr::PollEnterWorld();
break;
}
case IDLE_12: {
if (CGlueMgr::m_patchDownload) {
CGlueMgr::PatchDownloadIdle();
} else if (CGlueMgr::m_surveyDownload) {
CGlueMgr::SurveyDownloadIdle();
}
break;
}
case IDLE_13: {
CGlueMgr::PollUserSurvey();
break;
}
// TODO other idle states
default:
break;
} }
return 1; return 1;
@ -688,6 +693,33 @@ void CGlueMgr::PollCharacterList(int32_t errorCode, const char* msg, int32_t com
CGlueMgr::m_accountMsgAvailable = 0; CGlueMgr::m_accountMsgAvailable = 0;
} }
void CGlueMgr::PollRealmList(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op) {
FrameScript_SignalEvent(4u, "%s", msg);
if (CGlueMgr::HandleBattlenetDisconnect()) {
CGlueMgr::m_idleState = IDLE_NONE;
CGlueMgr::m_showedDisconnect = 0;
}
if (!complete) {
return;
}
if (result) {
CGlueMgr::m_idleState = IDLE_NONE;
CGlueMgr::m_showedDisconnect = 0;
FrameScript_SignalEvent(5u, nullptr);
CRealmList::UpdateList();
if (!CGlueMgr::m_accountMsgAvailable)
return;
FrameScript_SignalEvent(34u, nullptr);
CGlueMgr::m_accountMsgAvailable = 0;
} else {
FrameScript_SignalEvent(3u, "%s%s", "OKAY", msg);
CGlueMgr::m_idleState = IDLE_NONE;
CGlueMgr::m_showedDisconnect = 0;
}
}
void CGlueMgr::PollDeleteCharacter(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op) { void CGlueMgr::PollDeleteCharacter(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op) {
FrameScript_SignalEvent(4, "%s", msg); FrameScript_SignalEvent(4, "%s", msg);

View File

@ -89,6 +89,7 @@ class CGlueMgr {
static void PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op); static void PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
static void PollLoginServerLogin(); static void PollLoginServerLogin();
static void PollCharacterList(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op); static void PollCharacterList(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
static void PollRealmList(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
static void PollDeleteCharacter(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op); static void PollDeleteCharacter(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
static void PollUserSurvey(); static void PollUserSurvey();
static void CancelLogin(); static void CancelLogin();

View File

@ -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) { void NETEVENTQUEUE::AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes) {
this->m_critSect.Enter(); this->m_critSect.Enter();
@ -107,12 +112,27 @@ void NETEVENTQUEUE::Clear() {
this->m_critSect.Leave(); 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() { void NetClient::AddRef() {
SInterlockedIncrement(&this->m_refCount); SInterlockedIncrement(&this->m_refCount);
} }
void NetClient::AuthChallengeHandler(WowConnection* conn, CDataStore* msg) { void NetClient::AuthChallengeHandler(WowConnection* conn, CDataStore* msg) {
auto challenge = static_cast<AuthenticationChallenge*>(SMemAlloc(sizeof(AuthenticationChallenge), __FILE__, __LINE__, 0x0)); auto challenge = NEW(AuthenticationChallenge);
uint32_t v14; uint32_t v14;
msg->Get(v14); msg->Get(v14);
@ -129,7 +149,7 @@ void NetClient::AuthChallengeHandler(WowConnection* conn, CDataStore* msg) {
conn->Disconnect(); conn->Disconnect();
} }
delete challenge; DEL(challenge);
} }
void NetClient::Connect(const char* addrStr) { void NetClient::Connect(const char* addrStr) {
@ -155,7 +175,7 @@ void NetClient::Connect(const char* addrStr) {
void NetClient::Disconnect() { void NetClient::Disconnect() {
if (this->m_redirectConnection) { if (this->m_redirectConnection) {
// TODO: this->m_redirectConnection->SetResponse(0, 0); this->m_redirectConnection->SetResponse(nullptr, false);
this->m_redirectConnection->Disconnect(); this->m_redirectConnection->Disconnect();
this->m_redirectConnection->Release(); this->m_redirectConnection->Release();
} }
@ -164,7 +184,7 @@ void NetClient::Disconnect() {
this->m_netState = NS_DISCONNECTING; this->m_netState = NS_DISCONNECTING;
this->m_serverConnection->Disconnect(); this->m_serverConnection->Disconnect();
} else { } else {
// TODO: this->m_serverConnection->SetResponse(0, 0); this->m_serverConnection->SetResponse(nullptr, false);
this->m_serverConnection->Disconnect(); this->m_serverConnection->Disconnect();
this->m_netEventQueue->Clear(); this->m_netEventQueue->Clear();
this->m_serverConnection->Release(); 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_netState = NS_CONNECTING;
this->m_serverConnection->Connect(host, port, -1); 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; return 1;
} }
@ -254,10 +279,21 @@ void NetClient::Ping() {
} }
int32_t NetClient::HandleCantConnect() { int32_t NetClient::HandleCantConnect() {
// TODO this->PushObjMgr();
STORM_ASSERT(m_netState == NS_CONNECTING);
this->m_netState = NS_INITIALIZED;
this->PopObjMgr();
return 1; return 1;
} }
int32_t NetClient::ValidateMessageId(uint32_t msgId) {
// This method does nothing
return 0;
}
int32_t NetClient::HandleConnect() { int32_t NetClient::HandleConnect() {
this->PushObjMgr(); this->PushObjMgr();
@ -271,13 +307,17 @@ int32_t NetClient::HandleConnect() {
int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) { int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) {
this->PushObjMgr(); this->PushObjMgr();
CDataStore msg; NetClient::s_stats.bytesReceived += size + 2;
msg.m_data = static_cast<uint8_t*>(data);
msg.m_size = size;
msg.m_alloc = -1;
msg.m_read = 0;
this->ProcessMessage(timeReceived, &msg, 0); if (this->m_netState == NS_CONNECTED) {
CDataStore msg;
msg.m_data = static_cast<uint8_t*>(data);
msg.m_size = size;
msg.m_alloc = -1;
msg.m_read = 0;
this->ProcessMessage(timeReceived, &msg, 0);
}
this->PopObjMgr(); this->PopObjMgr();
@ -337,6 +377,37 @@ int32_t NetClient::Initialize() {
return 1; 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() { void NetClient::PollEventQueue() {
this->m_netEventQueue->Poll(); 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) { void NetClient::ProcessMessage(uint32_t timeReceived, CDataStore* msg, int32_t a4) {
// TODO s_stats.messagesReceived++ ++NetClient::s_stats.messagesReceived;
uint16_t msgId; uint16_t msgId;
msg->Get(msgId); msg->Get(msgId);
// TODO virtual function call on NetClient this->ValidateMessageId(msgId);
if (msgId >= NUM_MSG_TYPES || !this->m_handlers[msgId]) { if (msgId >= NUM_MSG_TYPES || !this->m_handlers[msgId]) {
msg->Reset(); msg->Reset();

View File

@ -41,6 +41,7 @@ class NETEVENTQUEUE {
NETEVENTQUEUE(NetClient* client) NETEVENTQUEUE(NetClient* client)
: m_client(client) : m_client(client)
{}; {};
~NETEVENTQUEUE();
void AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes); void AddEvent(EVENTID eventId, void* conn, NetClient* client, const void* data, uint32_t bytes);
void Poll(); void Poll();
void Clear(); void Clear();
@ -48,6 +49,8 @@ class NETEVENTQUEUE {
class NetClient : public WowConnectionResponse { class NetClient : public WowConnectionResponse {
public: public:
static void LogStats();
// Virtual member functions // Virtual member functions
virtual void WCMessageReady(WowConnection* conn, uint32_t timeStamp, CDataStore* msg); virtual void WCMessageReady(WowConnection* conn, uint32_t timeStamp, CDataStore* msg);
virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr); 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 HandleConnect();
virtual int32_t HandleDisconnect(); virtual int32_t HandleDisconnect();
virtual int32_t HandleCantConnect(); virtual int32_t HandleCantConnect();
virtual int32_t ValidateMessageId(uint32_t msgId);
// Member functions // Member functions
void AddRef(); void AddRef();
@ -73,6 +77,7 @@ class NetClient : public WowConnectionResponse {
void Ping(); void Ping();
void HandleIdle(); void HandleIdle();
int32_t Initialize(); int32_t Initialize();
void Destroy();
void PollEventQueue(); void PollEventQueue();
void PongHandler(WowConnection* conn, CDataStore* msg); void PongHandler(WowConnection* conn, CDataStore* msg);
void ProcessMessage(uint32_t timeReceived, CDataStore* msg, int32_t a4); void ProcessMessage(uint32_t timeReceived, CDataStore* msg, int32_t a4);

View File

@ -669,6 +669,27 @@ void WowConnection::Init(WowConnectionResponse* response, void (*func)(void)) {
this->m_type = WOWC_TYPE_MESSAGES; 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) { WowConnection::SENDNODE* WowConnection::NewSendNode(void* data, int32_t size, bool raw) {
// TODO counters // TODO counters
@ -693,8 +714,7 @@ void WowConnection::Release() {
if (WowConnection::s_network) { if (WowConnection::s_network) {
WowConnection::s_network->Delete(this); WowConnection::s_network->Delete(this);
} else { } else {
// TODO SMemFree DEL(this);
delete this;
} }
} }
} }

View File

@ -99,6 +99,7 @@ class WowConnection {
void FreeSendNode(SENDNODE* sn); void FreeSendNode(SENDNODE* sn);
WOW_CONN_STATE GetState(); WOW_CONN_STATE GetState();
void Init(WowConnectionResponse* response, void (*func)(void)); void Init(WowConnectionResponse* response, void (*func)(void));
void SetResponse(WowConnectionResponse* response, bool a3);
SENDNODE* NewSendNode(void* data, int32_t size, bool raw); SENDNODE* NewSendNode(void* data, int32_t size, bool raw);
void Release(); void Release();
void ReleaseResponseRef(); void ReleaseResponseRef();

View File

@ -34,7 +34,7 @@ void WowConnectionNet::Delete(WowConnection* connection) {
this->m_connectionsLock.Enter(); this->m_connectionsLock.Enter();
if (connection->m_refCount == 0) { if (connection->m_refCount == 0) {
delete connection; DEL(connection);
} }
this->m_connectionsLock.Leave(); this->m_connectionsLock.Leave();

View File

@ -20,6 +20,7 @@ class Grunt::ClientResponse {
virtual void RealmListResult(CDataStore* msg) = 0; virtual void RealmListResult(CDataStore* msg) = 0;
virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state) = 0; virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state) = 0;
virtual int32_t GetServerId() = 0; virtual int32_t GetServerId() = 0;
virtual void Reconnect() = 0;
virtual void GetRealmList() = 0; virtual void GetRealmList() = 0;
virtual void Logon(const char* a2, const char* a3) = 0; virtual void Logon(const char* a2, const char* a3) = 0;
virtual void ProveVersion(const uint8_t* versionChecksum) = 0; virtual void ProveVersion(const uint8_t* versionChecksum) = 0;

View File

@ -88,6 +88,10 @@ int32_t GruntLogin::GetServerId() {
return 0; return 0;
} }
void GruntLogin::Reconnect() {
// TODO
}
void GruntLogin::GetVersionProof(const uint8_t* versionChallenge) { void GruntLogin::GetVersionProof(const uint8_t* versionChallenge) {
if (this->IsReconnect()) { if (this->IsReconnect()) {
// TODO // TODO

View File

@ -22,6 +22,7 @@ class GruntLogin : public Login {
virtual void LogonResult(Grunt::Result result, const uint8_t* sessionKey, uint32_t sessionKeyLen, uint16_t flags); virtual void LogonResult(Grunt::Result result, const uint8_t* sessionKey, uint32_t sessionKeyLen, uint16_t flags);
virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state); virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state);
virtual int32_t GetServerId(); virtual int32_t GetServerId();
virtual void Reconnect();
virtual void GetRealmList(); virtual void GetRealmList();
virtual void Logon(const char* a2, const char* a3); virtual void Logon(const char* a2, const char* a3);
virtual void ProveVersion(const uint8_t* versionChecksum); virtual void ProveVersion(const uint8_t* versionChecksum);

View File

@ -13,6 +13,10 @@ bool Login::IsReconnect() {
return this->m_reconnect; return this->m_reconnect;
} }
bool Login::IsLoggedOn() {
return this->m_loggedOn;
}
bool Login::OnlineIdle() { bool Login::OnlineIdle() {
// TODO // TODO

View File

@ -22,6 +22,7 @@ class Login : public Grunt::ClientResponse {
virtual bool OnlineIdle(); virtual bool OnlineIdle();
virtual void RealmListResult(CDataStore* msg); virtual void RealmListResult(CDataStore* msg);
virtual bool IsReconnect(); virtual bool IsReconnect();
virtual bool IsLoggedOn();
// Member functions // Member functions
void SetLogonCreds(const char* accountName, const char* password); void SetLogonCreds(const char* accountName, const char* password);

View File

@ -11,7 +11,8 @@
#include <storm/String.hpp> #include <storm/String.hpp>
int32_t Script_RequestRealmList(lua_State* L) { int32_t Script_RequestRealmList(lua_State* L) {
WHOA_UNIMPLEMENTED(0); CGlueMgr::GetRealmList(StringToBOOL(L, 1, 0));
return 0;
} }
int32_t Script_RealmListUpdateRate(lua_State* L) { int32_t Script_RealmListUpdateRate(lua_State* L) {