Compare commits

...

2 Commits

11 changed files with 216 additions and 9 deletions

View File

@ -142,6 +142,12 @@ const char* ClientServices::GetErrorToken(uint32_t token) {
} }
} }
bool ClientServices::ValidDisconnect(const void* client) {
STORM_ASSERT(client);
STORM_ASSERT(ClientServices::s_currentConnection);
return client == ClientServices::s_currentConnection;
}
void ClientServices::ConnectToSelectedServer() { void ClientServices::ConnectToSelectedServer() {
if (!ClientServices::s_selectRealmInfoValid && !ClientServices::SetSelectedRealmInfo(0)) { if (!ClientServices::s_selectRealmInfoValid && !ClientServices::SetSelectedRealmInfo(0)) {
ClientServices::Connection()->Complete(0, 39); ClientServices::Connection()->Complete(0, 39);

View File

@ -33,6 +33,7 @@ class ClientServices : public LoginResponse {
// Static functions // Static functions
static const char* GetErrorToken(uint32_t token); static const char* GetErrorToken(uint32_t token);
static bool ValidDisconnect(const void* client);
static void ConnectToSelectedServer(); static void ConnectToSelectedServer();
static ClientConnection* Connection(); static ClientConnection* Connection();
static ClientServices* GetInstance(); static ClientServices* GetInstance();

View File

@ -171,6 +171,19 @@ void ConsoleWriteA(const char* str, COLOR_T color, ...) {
} }
} }
void ConsolePrintf(char const* str, ...) {
char buffer[4096] = { 0 };
if (str != nullptr && str[0] != '\0') {
va_list list;
va_start(list, str);
vsnprintf(buffer, sizeof(buffer), str, list);
va_end(list);
ConsoleWrite(buffer, DEFAULT_COLOR);
}
}
void MoveLinePtr(int32_t direction, int32_t modifier) { void MoveLinePtr(int32_t direction, int32_t modifier) {
CONSOLELINE* lineptr = s_currlineptr; CONSOLELINE* lineptr = s_currlineptr;

View File

@ -11,6 +11,7 @@
void ConsoleWrite(const char* str, COLOR_T color); void ConsoleWrite(const char* str, COLOR_T color);
void ConsoleWriteA(const char* str, COLOR_T color, ...); void ConsoleWriteA(const char* str, COLOR_T color, ...);
void ConsolePrintf(char const* str, ...);
void PasteInInputLine(char* characters); void PasteInInputLine(char* characters);

View File

@ -1,6 +1,7 @@
#include "glue/CGlueMgr.hpp" #include "glue/CGlueMgr.hpp"
#include "glue/CRealmList.hpp" #include "glue/CRealmList.hpp"
#include "glue/CCharacterSelection.hpp" #include "glue/CCharacterSelection.hpp"
#include "console/Console.hpp"
#include "client/Client.hpp" #include "client/Client.hpp"
#include "client/ClientServices.hpp" #include "client/ClientServices.hpp"
#include "gx/Coordinate.hpp" #include "gx/Coordinate.hpp"
@ -67,6 +68,7 @@ int32_t CGlueMgr::m_reload;
int32_t CGlueMgr::m_scandllOkayToLogIn = 1; // TODO int32_t CGlueMgr::m_scandllOkayToLogIn = 1; // TODO
float CGlueMgr::m_screenHeight; float CGlueMgr::m_screenHeight;
float CGlueMgr::m_screenWidth; float CGlueMgr::m_screenWidth;
int32_t CGlueMgr::m_clientKickReason;
int32_t CGlueMgr::m_showedDisconnect; int32_t CGlueMgr::m_showedDisconnect;
CSimpleTop* CGlueMgr::m_simpleTop; CSimpleTop* CGlueMgr::m_simpleTop;
int32_t CGlueMgr::m_suspended; int32_t CGlueMgr::m_suspended;
@ -229,6 +231,63 @@ void CGlueMgr::GetCharacterList() {
} }
} }
int32_t CGlueMgr::NetDisconnectHandler(const void* eventData, void*) {
bool v11 = CGlueMgr::m_idleState != IDLE_ACCOUNT_LOGIN;
CGlueMgr::m_idleState = IDLE_NONE;
CGlueMgr::m_showedDisconnect = 0;
if (CGlueMgr::m_disconnectPending) {
ConsolePrintf("CGlueMgr::NetDisconnectHandler: Disconnect pending");
CGlueMgr::m_disconnectPending = 0;
if (CGlueMgr::m_reconnect) {
CGlueMgr::m_reconnect = 0;
CGlueMgr::m_idleState = IDLE_ACCOUNT_LOGIN;
CGlueMgr::m_showedDisconnect = 0;
auto text = FrameScript_GetText("GAME_SERVER_LOGIN", -1, GENDER_NOT_APPLICABLE);
FrameScript_SignalEvent(3u, "%s%s", "CANCEL", text);
ClientServices::Connection()->Connect();
return 1;
}
return 1;
}
if (!ClientServices::ValidDisconnect(eventData)) {
ConsolePrintf("CGlueMgr::NetDisconnectHandler: Invalid disconnect");
return 1;
}
// TODO: ClientDestroyGame(0, 1, 0);
// TODO: EventSetMouseMode(0, 0);
if (CGlueMgr::m_suspended) {
CGlueMgr::Resume();
}
if (v11) {
ConsolePrintf("CGlueMgr::NetDisconnectHandler: Displaying script");
LABEL_14:
FrameScript_SignalEvent(2u, "%d", CGlueMgr::m_clientKickReason);
goto LABEL_15;
}
ConsolePrintf("CGlueMgr::NetDisconnectHandler: NOT displaying script");
WOWCS_OPS op;
const char* msg;
int32_t result;
int32_t errorCode;
int32_t complete = ClientServices::Connection()->PollStatus(op, &msg, result, errorCode);
if (!complete || result) {
ClientServices::SelectRealm("");
goto LABEL_14;
}
FrameScript_SignalEvent(3u, "%s%s", "OKAY", msg);
LABEL_15:
ClientServices::LoginConnection()->Logoff();
return 1;
}
// TODO a1: const EVENT_DATA_IDLE* // TODO a1: const EVENT_DATA_IDLE*
int32_t CGlueMgr::Idle(const void* a1, void* a2) { int32_t CGlueMgr::Idle(const void* a1, void* a2) {
// TODO: // TODO:

View File

@ -59,6 +59,7 @@ class CGlueMgr {
static int32_t m_scandllOkayToLogIn; static int32_t m_scandllOkayToLogIn;
static float m_screenHeight; static float m_screenHeight;
static float m_screenWidth; static float m_screenWidth;
static int32_t m_clientKickReason;
static int32_t m_showedDisconnect; static int32_t m_showedDisconnect;
static CSimpleTop* m_simpleTop; static CSimpleTop* m_simpleTop;
static int32_t m_suspended; static int32_t m_suspended;
@ -78,6 +79,7 @@ class CGlueMgr {
static int32_t HandleDisplaySizeChanged(const CSizeEvent& event); static int32_t HandleDisplaySizeChanged(const CSizeEvent& event);
static void GetRealmList(bool showProgress); static void GetRealmList(bool showProgress);
static void GetCharacterList(); static void GetCharacterList();
static int32_t NetDisconnectHandler(const void* eventData, void*);
static int32_t Idle(const void* a1, void* a2); static int32_t Idle(const void* a1, void* a2);
static void Initialize(); static void Initialize();
static void InitCursor(); static void InitCursor();

View File

@ -32,6 +32,7 @@ target_include_directories(net
target_link_libraries(net target_link_libraries(net
PRIVATE PRIVATE
client client
console
event event
PUBLIC PUBLIC
bc bc

View File

@ -1,5 +1,7 @@
#include "net/connection/NetClient.hpp" #include "net/connection/NetClient.hpp"
#include "net/connection/WowConnection.hpp" #include "net/connection/WowConnection.hpp"
#include "glue/CGlueMgr.hpp"
#include "console/Line.hpp"
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <new> #include <new>
@ -232,17 +234,17 @@ int32_t NetClient::HandleCantConnect() {
} }
int32_t NetClient::HandleConnect() { int32_t NetClient::HandleConnect() {
// TODO push obj mgr this->PushObjMgr();
this->m_netState = NS_CONNECTED; this->m_netState = NS_CONNECTED;
// TODO pop obj mgr this->PopObjMgr();
return 1; return 1;
} }
int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) { int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) {
// TODO push obj mgr this->PushObjMgr();
CDataStore msg; CDataStore msg;
msg.m_data = static_cast<uint8_t*>(data); msg.m_data = static_cast<uint8_t*>(data);
@ -252,13 +254,21 @@ int32_t NetClient::HandleData(uint32_t timeReceived, void* data, int32_t size) {
this->ProcessMessage(timeReceived, &msg, 0); this->ProcessMessage(timeReceived, &msg, 0);
// TODO pop obj mgr this->PopObjMgr();
return 1; return 1;
} }
int32_t NetClient::HandleDisconnect() { int32_t NetClient::HandleDisconnect() {
// TODO this->PushObjMgr();
STORM_ASSERT(this->m_netState == NS_CONNECTED || this->m_netState == NS_DISCONNECTING);
this->m_netState = NS_INITIALIZED;
ConsolePrintf("NetClient::HandleDisconnect()");
CGlueMgr::NetDisconnectHandler(this, nullptr);
this->PopObjMgr();
return 1; return 1;
} }
@ -358,6 +368,59 @@ void NetClient::SetLoginData(LoginData* loginData) {
memcpy(&this->m_loginData, loginData, sizeof(this->m_loginData)); memcpy(&this->m_loginData, loginData, sizeof(this->m_loginData));
} }
void NetClient::DisplayNetworkStats() {
this->m_pingLock.Enter();
OsGetAsyncTimeMs();
float bandwidthIn;
float bandwidthOut;
uint32_t latency;
this->GetNetStats(bandwidthIn, bandwidthOut, latency);
this->m_pingLock.Leave();
}
void NetClient::GetNetStats(float& bandwidthIn, float& bandwidthOut, uint32_t& latency) {
this->m_pingLock.Enter();
double v5 = (double)(OsGetAsyncTimeMs() - this->m_connectedTimestamp) * 0.001;
bandwidthIn = (double)this->m_bytesReceived * 0.0009765625 / v5;
bandwidthOut = (double)this->m_bytesSent * 0.0009765625 / v5;
uint32_t latencyStart = this->m_latencyStart;
uint32_t latencyEnd = this->m_latencyEnd;
uint32_t v6 = 0;
uint32_t v9 = 0;
while (latencyStart != latencyEnd) {
if (latencyStart >= 16) {
latencyStart = 0;
if (!latencyEnd)
break;
}
v9 += this->m_latency[latencyStart];
++v6;
++latencyStart;
} ;
if (!v6) {
latency = 0;
} else {
latency = v9 / v6;
}
this->m_pingLock.Leave();
}
void NetClient::PushObjMgr() {
// TODO
}
void NetClient::PopObjMgr() {
// TODO
}
void NetClient::SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param) { void NetClient::SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param) {
this->m_handlers[msgId] = handler; this->m_handlers[msgId] = handler;
this->m_handlerParams[msgId] = param; this->m_handlerParams[msgId] = param;
@ -387,7 +450,10 @@ void NetClient::WCConnected(WowConnection* conn, WowConnection* inbound, uint32_
} }
void NetClient::WCDisconnected(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) { void NetClient::WCDisconnected(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) {
// TODO this->DisplayNetworkStats();
if (this->m_netEventQueue) {
this->m_netEventQueue->AddEvent(EVENT_ID_NET_DISCONNECT, conn, this, nullptr, 0);
}
} }
void NetClient::WCMessageReady(WowConnection* conn, uint32_t timeStamp, CDataStore* msg) { void NetClient::WCMessageReady(WowConnection* conn, uint32_t timeStamp, CDataStore* msg) {

View File

@ -79,6 +79,10 @@ class NetClient : public WowConnectionResponse {
void SetDelete(); void SetDelete();
void SetLoginData(LoginData* loginData); void SetLoginData(LoginData* loginData);
void SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param); void SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param);
void DisplayNetworkStats();
void GetNetStats(float& bandwidthIn, float& bandwidthOut, uint32_t& latency);
void PushObjMgr();
void PopObjMgr();
private: private:
// Static variables // Static variables

View File

@ -341,8 +341,7 @@ void WowConnection::DoDisconnect() {
this->m_lock.Leave(); this->m_lock.Leave();
if (this->m_response && this->m_sock >= 0) { if (this->m_response && this->m_sock >= 0) {
// TODO this->m_response->WCDisconnected(this, OsGetAsyncTimeMsPrecise(), &this->m_peer);
// this->m_response->Vfunc4(this, OsGetAsyncTimeMsPrecise());
} }
this->m_lock.Enter(); this->m_lock.Enter();

View File

@ -72,7 +72,62 @@ void LoginResponse::HandleRealmData(uint32_t a2, CDataStore* msg) {
realm.flags |= 0x80; realm.flags |= 0x80;
} }
// TODO name manipulation if (realm.name[0] == '\0') {
continue;
}
int32_t j = 0;
while (realm.name[j]) {
switch (realm.name[j]) {
case '"':
case '*':
case '/':
case ':':
case '<':
case '>':
case '?':
case '\\':
case '|': {
realm.name[j] = ' ';
break;
}
default: {
break;
}
}
++j;
}
while (j > 0) {
bool stop = false;
switch (realm.name[j - 1]) {
case ' ':
case '"':
case '*':
case '.':
case '/':
case ':':
case '<':
case '>':
case '?':
case '\\':
case '|': {
--j;
break;
}
default: {
stop = true;
break;
}
}
if (stop) {
break;
}
}
realm.name[j] = '\0';
} }
msg->Get(reinterpret_cast<uint16_t&>(this->uint10)); msg->Get(reinterpret_cast<uint16_t&>(this->uint10));