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() {
// 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() {
@ -367,6 +373,7 @@ void ClientServices::LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, c
void ClientServices::RealmEnumCallback(uint32_t a2) {
auto connection = ClientServices::Connection();
STORM_ASSERT(connection);
if (a2 == 1) {
connection->Complete(0, 23);
@ -378,7 +385,13 @@ void ClientServices::RealmEnumCallback(uint32_t a2) {
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) {
// 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);
switch (CGlueMgr::m_idleState) {
case IDLE_LOGIN_SERVER_LOGIN: {
CGlueMgr::PollLoginServerLogin();
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();
case IDLE_LOGIN_SERVER_LOGIN: {
CGlueMgr::PollLoginServerLogin();
break;
}
break;
}
case IDLE_13: {
CGlueMgr::PollUserSurvey();
break;
}
case IDLE_ACCOUNT_LOGIN: {
CGlueMgr::PollAccountLogin(errorCode, msg, complete, result, op);
break;
}
// TODO other idle states
case IDLE_CHARACTER_LIST: {
CGlueMgr::PollCharacterList(errorCode, msg, complete, result, op);
break;
}
default:
break;
case IDLE_REALM_LIST: {
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;
@ -688,6 +693,33 @@ void CGlueMgr::PollCharacterList(int32_t errorCode, const char* msg, int32_t com
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) {
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 PollLoginServerLogin();
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 PollUserSurvey();
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) {
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<AuthenticationChallenge*>(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<uint8_t*>(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<uint8_t*>(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();

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -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();

View File

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

View File

@ -88,6 +88,10 @@ int32_t GruntLogin::GetServerId() {
return 0;
}
void GruntLogin::Reconnect() {
// TODO
}
void GruntLogin::GetVersionProof(const uint8_t* versionChallenge) {
if (this->IsReconnect()) {
// 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 LOGIN_STATE NextSecurityState(LOGIN_STATE state);
virtual int32_t GetServerId();
virtual void Reconnect();
virtual void GetRealmList();
virtual void Logon(const char* a2, const char* a3);
virtual void ProveVersion(const uint8_t* versionChecksum);

View File

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

View File

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

View File

@ -11,7 +11,8 @@
#include <storm/String.hpp>
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) {