diff --git a/src/client/ClientServices.cpp b/src/client/ClientServices.cpp index 93db598..39cf646 100644 --- a/src/client/ClientServices.cpp +++ b/src/client/ClientServices.cpp @@ -22,12 +22,12 @@ bool ClientServices::s_selectRealmInfoValid; void ClientServices::ConnectToSelectedServer() { if (!ClientServices::s_selectRealmInfoValid && !ClientServices::SetSelectedRealmInfo(0)) { - // TODO ClientServices::Connection()->Sub6B10B0(0, 39); + ClientServices::Connection()->SetStatus(0, 39); return; } if (ClientServices::Connection()->m_netState != NS_INITIALIZED) { - // TODO ClientServices::Connection()->Sub6B10B0(0, 39); + ClientServices::Connection()->SetStatus(0, 39); return; } diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index f986ea2..2ad969d 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -1,4 +1,5 @@ #include "glue/CGlueMgr.hpp" +#include "glue/CRealmList.hpp" #include "client/Client.hpp" #include "client/ClientServices.hpp" #include "gx/Coordinate.hpp" @@ -46,6 +47,7 @@ char CGlueMgr::m_accountName[1280]; float CGlueMgr::m_aspect; bool CGlueMgr::m_authenticated; char CGlueMgr::m_currentScreen[64]; +int32_t CGlueMgr::m_displayingQueueDialog; CGlueMgr::GLUE_IDLE_STATE CGlueMgr::m_idleState; int32_t CGlueMgr::m_initialized; int32_t CGlueMgr::m_lastLoginResult; @@ -195,6 +197,12 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) { // TODO + WOWCS_OPS op; + const char* msg; + int32_t result; + int32_t errorCode; + int32_t complete = ClientServices::Connection()->PollStatus(op, &msg, result, errorCode); + switch (CGlueMgr::m_idleState) { case IDLE_LOGIN_SERVER_LOGIN: { CGlueMgr::PollLoginServerLogin(); @@ -202,7 +210,7 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) { } case IDLE_ACCOUNT_LOGIN: { - // TODO PollAccountLogin + CGlueMgr::PollAccountLogin(errorCode, msg, complete, result, op); break; } @@ -304,6 +312,75 @@ void CGlueMgr::QuitGame() { ClientPostClose(0); } +void CGlueMgr::PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op) { + auto login = ClientServices::LoginConnection(); + + if (login->GetLoginServerType() == 1 && CGlueMgr::m_loginState == LOGIN_STATE_FAILED) { + CGlueMgr::DisplayLoginStatus(); + + ClientServices::Connection()->Cancel(2); + login->Logoff(); + + CGlueMgr::m_idleState = IDLE_NONE; + CGlueMgr::m_showedDisconnect = 0; + + return; + } + + if (errorCode == 27) { + // TODO AUTH_WAIT_QUEUE + } else { + if (CGlueMgr::m_displayingQueueDialog) { + FrameScript_SignalEvent(3, "%s", "CANCEL"); + CGlueMgr::m_displayingQueueDialog = 0; + } + + FrameScript_SignalEvent(4, "%s", msg); + } + + if (complete) { + if (result == 0) { + if (errorCode != 2) { + // TODO + } + + CGlueMgr::m_idleState = IDLE_NONE; + CGlueMgr::m_showedDisconnect = 0; + + if (errorCode == 2) { + // TODO CGlueMgr::m_disconnectPending = 1; + // TODO ClientServices::Connection()->Disconnect(); + } + + if (errorCode != 13) { + // TODO CCharacterSelection::ClearCharacterList(); + + if (ClientServices::GetInstance()->m_realmList.Count()) { + FrameScript_SignalEvent(5, nullptr); + CRealmList::UpdateList(); + } else { + // TODO + } + + return; + } + + if (!SStrCmpI(CGlueMgr::m_currentScreen, "charselect", STORM_MAX_STR)) { + CGlueMgr::SetScreen("login"); + return; + } + + return; + } + + if (op == COP_CONNECT) { + // TODO + + return; + } + } +} + void CGlueMgr::PollLoginServerLogin() { if (CGlueMgr::m_loginState != LOGIN_STATE_PIN_WAIT) { CGlueMgr::DisplayLoginStatus(); diff --git a/src/glue/CGlueMgr.hpp b/src/glue/CGlueMgr.hpp index 3617c70..36d2fba 100644 --- a/src/glue/CGlueMgr.hpp +++ b/src/glue/CGlueMgr.hpp @@ -36,6 +36,7 @@ class CGlueMgr { static float m_aspect; static bool m_authenticated; static char m_currentScreen[]; + static int32_t m_displayingQueueDialog; static GLUE_IDLE_STATE m_idleState; static int32_t m_initialized; static int32_t m_lastLoginResult; @@ -59,6 +60,7 @@ class CGlueMgr { static void Initialize(); static void LoginServerLogin(const char* accountName, const char* password); static void QuitGame(); + static void PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op); static void PollLoginServerLogin(); static void Resume(); static void SetCurrentAccount(const char* accountName); diff --git a/src/glue/CRealmList.cpp b/src/glue/CRealmList.cpp new file mode 100644 index 0000000..749cb05 --- /dev/null +++ b/src/glue/CRealmList.cpp @@ -0,0 +1,5 @@ +#include "glue/CRealmList.hpp" + +void CRealmList::UpdateList() { + // TODO +} diff --git a/src/glue/CRealmList.hpp b/src/glue/CRealmList.hpp new file mode 100644 index 0000000..d741070 --- /dev/null +++ b/src/glue/CRealmList.hpp @@ -0,0 +1,10 @@ +#ifndef GLUE_C_REALM_LIST_HPP +#define GLUE_C_REALM_LIST_HPP + +class CRealmList { + public: + // Static functions + static void UpdateList(); +}; + +#endif diff --git a/src/net/connection/ClientConnection.cpp b/src/net/connection/ClientConnection.cpp index c618e35..01a0de0 100644 --- a/src/net/connection/ClientConnection.cpp +++ b/src/net/connection/ClientConnection.cpp @@ -1,6 +1,114 @@ #include "net/connection/ClientConnection.hpp" #include "net/Login.hpp" #include "client/ClientServices.hpp" +#include "ui/FrameScript.hpp" + +const char* s_errorCodeTokens[] = { + "RESPONSE_SUCCESS", + "RESPONSE_FAILURE", + "RESPONSE_CANCELLED", + "RESPONSE_DISCONNECTED", + "RESPONSE_FAILED_TO_CONNECT", + "RESPONSE_CONNECTED", + "RESPONSE_VERSION_MISMATCH", + "CSTATUS_CONNECTING", + "CSTATUS_NEGOTIATING_SECURITY", + "CSTATUS_NEGOTIATION_COMPLETE", + "CSTATUS_NEGOTIATION_FAILED", + "CSTATUS_AUTHENTICATING", + "AUTH_OK", + "AUTH_FAILED", + "AUTH_REJECT", + "AUTH_BAD_SERVER_PROOF", + "AUTH_UNAVAILABLE", + "AUTH_SYSTEM_ERROR", + "AUTH_BILLING_ERROR", + "AUTH_BILLING_EXPIRED", + "AUTH_VERSION_MISMATCH", + "AUTH_UNKNOWN_ACCOUNT", + "AUTH_INCORRECT_PASSWORD", + "AUTH_SESSION_EXPIRED", + "AUTH_SERVER_SHUTTING_DOWN", + "AUTH_ALREADY_LOGGING_IN", + "AUTH_LOGIN_SERVER_NOT_FOUND", + "AUTH_WAIT_QUEUE", + "AUTH_BANNED", + "AUTH_ALREADY_ONLINE", + "AUTH_NO_TIME", + "AUTH_DB_BUSY", + "AUTH_SUSPENDED", + "AUTH_PARENTAL_CONTROL", + "AUTH_LOCKED_ENFORCED", + "REALM_LIST_IN_PROGRESS", + "REALM_LIST_SUCCESS", + "REALM_LIST_FAILED", + "REALM_LIST_INVALID", + "REALM_LIST_REALM_NOT_FOUND", + "ACCOUNT_CREATE_IN_PROGRESS", + "ACCOUNT_CREATE_SUCCESS", + "ACCOUNT_CREATE_FAILED", + "CHAR_LIST_RETRIEVING", + "CHAR_LIST_RETRIEVED", + "CHAR_LIST_FAILED", + "CHAR_CREATE_IN_PROGRESS", + "CHAR_CREATE_SUCCESS", + "CHAR_CREATE_ERROR", + "CHAR_CREATE_FAILED", + "CHAR_CREATE_NAME_IN_USE", + "CHAR_CREATE_DISABLED", + "CHAR_CREATE_PVP_TEAMS_VIOLATION", + "CHAR_CREATE_SERVER_LIMIT", + "CHAR_CREATE_ACCOUNT_LIMIT", + "CHAR_CREATE_SERVER_QUEUE", + "CHAR_CREATE_ONLY_EXISTING", + "CHAR_CREATE_EXPANSION", + "CHAR_CREATE_EXPANSION_CLASS", + "CHAR_CREATE_LEVEL_REQUIREMENT", + "CHAR_CREATE_UNIQUE_CLASS_LIMIT", + "CHAR_CREATE_CHARACTER_IN_GUILD", + "CHAR_CREATE_RESTRICTED_RACECLASS", + "CHAR_CREATE_CHARACTER_CHOOSE_RACE", + "CHAR_CREATE_CHARACTER_ARENA_LEADER", + "CHAR_CREATE_CHARACTER_DELETE_MAIL", + "CHAR_CREATE_CHARACTER_SWAP_FACTION", + "CHAR_CREATE_CHARACTER_RACE_ONLY", + "CHAR_CREATE_CHARACTER_GOLD_LIMIT", + "CHAR_CREATE_FORCE_LOGIN", + "CHAR_DELETE_IN_PROGRESS", + "CHAR_DELETE_SUCCESS", + "CHAR_DELETE_FAILED", + "CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER", + "CHAR_DELETE_FAILED_GUILD_LEADER", + "CHAR_DELETE_FAILED_ARENA_CAPTAIN", + "CHAR_LOGIN_IN_PROGRESS", + "CHAR_LOGIN_SUCCESS", + "CHAR_LOGIN_NO_WORLD", + "CHAR_LOGIN_DUPLICATE_CHARACTER", + "CHAR_LOGIN_NO_INSTANCES", + "CHAR_LOGIN_FAILED", + "CHAR_LOGIN_DISABLED", + "CHAR_LOGIN_NO_CHARACTER", + "CHAR_LOGIN_LOCKED_FOR_TRANSFER", + "CHAR_LOGIN_LOCKED_BY_BILLING", + "CHAR_LOGIN_LOCKED_BY_MOBILE_AH", + "CHAR_NAME_SUCCESS", + "CHAR_NAME_FAILURE", + "CHAR_NAME_NO_NAME", + "CHAR_NAME_TOO_SHORT", + "CHAR_NAME_TOO_LONG", + "CHAR_NAME_INVALID_CHARACTER", + "CHAR_NAME_MIXED_LANGUAGES", + "CHAR_NAME_PROFANE", + "CHAR_NAME_RESERVED", + "CHAR_NAME_INVALID_APOSTROPHE", + "CHAR_NAME_MULTIPLE_APOSTROPHES", + "CHAR_NAME_THREE_CONSECUTIVE", + "CHAR_NAME_INVALID_SPACE", + "CHAR_NAME_CONSECUTIVE_SPACES", + "CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS", + "CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END", + "CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME", +}; void ClientConnection::Cancel(int32_t errorCode) { this->Cleanup(); @@ -32,3 +140,43 @@ void ClientConnection::Connect() { ClientServices::LoginConnection()->GetRealmList(); } + +int32_t ClientConnection::PollStatus(WOWCS_OPS& op, const char** msg, int32_t& result, int32_t& errorCode) { + op = this->m_statusCop; + errorCode = this->m_errorCode; + result = this->m_statusResult; + + static char altText[256]; + + if (this->m_statusComplete) { + auto text = errorCode >= 0 && errorCode < 104 + ? FrameScript_GetText(s_errorCodeTokens[errorCode], -1, GENDER_NOT_APPLICABLE) + : nullptr; + + if (!text) { + SStrPrintf(altText, sizeof(altText), "(%i)", errorCode); + *msg = altText; + } else if (errorCode == 27) { + // TODO + *msg = "TODO"; + } else { + *msg = text; + } + + return this->m_statusComplete; + } + + *msg = ""; + + return this->m_statusComplete; +} + +void ClientConnection::SetStatus(int32_t result, int32_t errorCode) { + this->Cleanup(); + + this->m_statusResult = result; + this->m_errorCode = errorCode; + this->m_statusComplete = 1; + + // TODO LogConnectionStatus(this->m_statusCop, errorCode, 0); +} diff --git a/src/net/connection/ClientConnection.hpp b/src/net/connection/ClientConnection.hpp index 5735614..7df58e9 100644 --- a/src/net/connection/ClientConnection.hpp +++ b/src/net/connection/ClientConnection.hpp @@ -22,6 +22,8 @@ class ClientConnection : public RealmConnection { void Cancel(int32_t errorCode); void Cleanup(); void Connect(); + int32_t PollStatus(WOWCS_OPS& op, const char** msg, int32_t& result, int32_t& errorCode); + void SetStatus(int32_t result, int32_t errorCode); }; #endif