feat(net): parse realm list

This commit is contained in:
fallenoak 2023-02-10 14:56:00 -06:00
parent fc7fa1dbdc
commit 22bfe894d2
No known key found for this signature in database
GPG Key ID: 7628F8E61AEA070D
10 changed files with 222 additions and 3 deletions

@ -1 +1 @@
Subproject commit 1113e846dad906864e7e4e9e5275334f6ca3df0e
Subproject commit 156ccfdb7da35ab786530cdd956e3881b50983f7

View File

@ -93,6 +93,14 @@ void ClientServices::SetAccountName(const char* accountName) {
SStrCopy(ClientServices::s_accountName, accountName, sizeof(ClientServices::s_accountName));
}
int32_t ClientServices::GetLoginServerType() {
if (!ClientServices::LoginConnection()) {
return 0;
}
return ClientServices::LoginConnection()->GetLoginServerType();
}
void ClientServices::LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, const char* stateStr, const char* resultStr, uint8_t flags) {
CGlueMgr::SetLoginStateAndResult(state, result, addrStr, stateStr, resultStr, flags);
@ -119,3 +127,7 @@ void ClientServices::LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, c
// TODO CVar::DeleteAccountCVars();
}
}
void ClientServices::RealmEnumCallback(uint32_t a2) {
// TODO
}

View File

@ -26,7 +26,9 @@ class ClientServices : public LoginResponse {
static void SetAccountName(const char* accountName);
// Virtual member functions
virtual int32_t GetLoginServerType();
virtual void LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, const char* stateStr, const char* resultStr, uint8_t flags);
virtual void RealmEnumCallback(uint32_t a2);
};
#endif

View File

@ -1225,4 +1225,24 @@ struct NETCONNADDR {
NETADDR selfAddr;
};
struct REALM_INFO {
uint32_t id;
uint8_t type;
uint8_t flags;
char name[256];
char address[32];
float population;
uint8_t numChars;
uint8_t category;
uint32_t uint130;
uint32_t uint134;
uint32_t sort;
uint32_t uint13C;
uint8_t locked;
uint8_t majorVersion;
uint8_t minorVersion;
uint8_t patchVersion;
uint16_t revision;
};
#endif

View File

@ -282,8 +282,86 @@ int32_t Grunt::ClientLink::CmdAuthReconnectProof(CDataStore& msg) {
}
int32_t Grunt::ClientLink::CmdRealmList(CDataStore& msg) {
// TODO
return 0;
if (msg.m_read > msg.m_size || msg.m_size - msg.m_read < 2) {
return 0;
}
uint16_t size;
msg.Get(size);
if (msg.m_read > msg.m_size || msg.m_size - msg.m_read < size) {
return 0;
}
uint32_t startData = msg.m_read;
uint32_t padding;
msg.Get(padding);
uint32_t startList = msg.m_read;
uint16_t count;
msg.Get(count);
for (uint32_t i = 0; i < count && msg.m_read < msg.m_size; i++) {
uint8_t realmType;
msg.Get(realmType);
uint8_t locked;
msg.Get(locked);
uint8_t realmFlags;
msg.Get(realmFlags);
char realmName[256];
msg.GetString(realmName, sizeof(realmName));
char realmAddress[256];
msg.GetString(realmAddress, sizeof(realmAddress));
float population;
msg.Get(population);
uint8_t numChars;
msg.Get(numChars);
uint8_t realmCategory;
msg.Get(realmCategory);
uint8_t sort;
msg.Get(sort);
// TODO SPECIFY_BUILD
if (realmFlags & 0x4) {
uint8_t major;
msg.Get(major);
uint8_t minor;
msg.Get(minor);
uint8_t patch;
msg.Get(patch);
uint16_t revision;
msg.Get(revision);
}
}
uint16_t padding2;
msg.Get(padding2);
if (msg.m_read <= msg.m_size && msg.m_read - startData == size) {
uint32_t endData = msg.m_read;
msg.m_read = startList;
this->m_clientResponse->RealmListResult(&msg);
msg.m_read = endData;
return 2;
}
return 1;
}
int32_t Grunt::ClientLink::CmdXferData(CDataStore& msg) {

View File

@ -4,6 +4,7 @@
#include "net/grunt/Grunt.hpp"
#include "net/Types.hpp"
class CDataStore;
class LoginResponse;
class Grunt::ClientResponse {
@ -16,6 +17,7 @@ class Grunt::ClientResponse {
virtual void SetMatrixInfo(bool enabled, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, bool a7, uint8_t a8, uint64_t a9, const uint8_t* a10, uint32_t a11) = 0;
virtual void SetTokenInfo(bool enabled, uint8_t required) = 0;
virtual void LogonResult(Result result, const uint8_t* sessionKey, uint32_t sessionKeyLen, uint16_t flags) = 0;
virtual void RealmListResult(CDataStore* msg) = 0;
virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state) = 0;
virtual int32_t GetServerId() = 0;
virtual void GetRealmList() = 0;

View File

@ -1,5 +1,7 @@
#include "net/login/Login.hpp"
#include "net/login/LoginResponse.hpp"
#include <cstring>
#include <common/DataStore.hpp>
#include <storm/Memory.hpp>
#include <storm/String.hpp>
@ -17,6 +19,14 @@ bool Login::OnlineIdle() {
return true;
}
void Login::RealmListResult(CDataStore* msg) {
if (!msg || !msg->IsFinal()) {
this->m_loginResponse->HandleRealmData(4, nullptr);
} else {
this->m_loginResponse->HandleRealmData(0, msg);
}
}
void Login::SetLogonCreds(const char* accountName, const char* password) {
SStrCopy(this->m_accountName, accountName, 1280);

View File

@ -3,6 +3,7 @@
#include "net/grunt/ClientResponse.hpp"
class CDataStore;
class LoginResponse;
class Login : public Grunt::ClientResponse {
@ -19,6 +20,7 @@ class Login : public Grunt::ClientResponse {
// Virtual member functions
virtual ~Login();
virtual bool OnlineIdle();
virtual void RealmListResult(CDataStore* msg);
virtual bool IsReconnect();
// Member functions

View File

@ -1,7 +1,92 @@
#include "net/login/LoginResponse.hpp"
#include "net/grunt/Grunt.hpp"
#include <common/DataStore.hpp>
#include <storm/String.hpp>
void LoginResponse::HandleRealmData(uint32_t a2, CDataStore* msg) {
this->m_realmList.Clear();
if (a2 || !msg) {
this->RealmEnumCallback(a2);
return;
}
uint16_t count;
msg->Get(count);
this->m_realmList.SetCount(count);
for (uint32_t i = 0; i < count; i++) {
auto& realm = this->m_realmList[i];
realm.id = i;
msg->Get(realm.type);
msg->Get(realm.locked);
msg->Get(realm.flags);
msg->GetString(realm.name, sizeof(realm.name));
msg->GetString(realm.address, sizeof(realm.address));
msg->Get(realm.population);
msg->Get(realm.numChars);
msg->Get(realm.category);
if (this->GetLoginServerType() == 1) {
msg->Get(realm.uint130);
msg->Get(realm.uint134);
msg->Get(realm.sort);
msg->Get(realm.uint13C);
} else {
uint8_t sort;
msg->Get(sort);
realm.sort = sort;
realm.uint130 = 0;
realm.uint134 = 0;
realm.uint13C = 0;
}
if (realm.flags & 0x4) {
msg->Get(realm.majorVersion);
msg->Get(realm.minorVersion);
msg->Get(realm.patchVersion);
msg->Get(realm.revision);
} else {
realm.majorVersion = 0;
realm.minorVersion = 0;
realm.patchVersion = 0;
realm.revision = 0;
}
if (msg->m_read > msg->m_size) {
break;
}
if (realm.population == 600.0f) {
realm.population = 0.0f;
realm.flags |= 0x20;
} else if (realm.population == 200.0f) {
realm.population = 0.001f;
realm.flags |= 0x40;
} else if (realm.population == 400.f) {
realm.population = 8.0f;
realm.flags |= 0x80;
}
// TODO name manipulation
}
msg->Get(reinterpret_cast<uint16_t&>(this->uint10));
// Overrun or underrun
if (msg->m_read > msg->m_size || !msg->IsRead()) {
this->m_realmList.Clear();
this->RealmEnumCallback(4);
}
// Success
this->RealmEnumCallback(a2);
}
void LoginResponse::UpdateLoginStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, uint16_t flags) {
this->m_loginState = state;
this->m_loginResult = result;

View File

@ -2,17 +2,25 @@
#define NET_LOGIN_LOGIN_RESPONSE_HPP
#include "net/Types.hpp"
#include <storm/Array.hpp>
class CDataStore;
class LoginResponse {
public:
// Member variables
TSFixedArray<REALM_INFO> m_realmList;
uint32_t uint10;
LOGIN_STATE m_loginState;
LOGIN_RESULT m_loginResult;
// Virtual member functions
virtual int32_t GetLoginServerType() = 0;
virtual void LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, const char* stateStr, const char* resultStr, uint8_t flags) = 0;
virtual void RealmEnumCallback(uint32_t a2) = 0;
// Member functions
void HandleRealmData(uint32_t a2, CDataStore* msg);
void UpdateLoginStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, uint16_t flags);
};