diff --git a/lib/common b/lib/common index 1c4d306..30c34ca 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 1c4d306a7fea3cb1ea0a3226da78fcf01324e498 +Subproject commit 30c34ca015c860fb156b79ca26938b7251db2ce0 diff --git a/src/net/grunt/ClientLink.cpp b/src/net/grunt/ClientLink.cpp index 6c2d94d..2a58ce1 100644 --- a/src/net/grunt/ClientLink.cpp +++ b/src/net/grunt/ClientLink.cpp @@ -1,11 +1,21 @@ #include "net/grunt/ClientLink.hpp" #include "net/connection/WowConnection.hpp" #include "net/grunt/ClientResponse.hpp" +#include "net/grunt/Command.hpp" #include -#include #include #include +Grunt::Command Grunt::s_clientCommands[] = { + { Grunt::ClientLink::CMD_AUTH_LOGON_CHALLENGE, "ClientLink::CMD_AUTH_LOGON_CHALLENGE", &Grunt::ClientLink::CmdAuthLogonChallenge, 0 }, + { Grunt::ClientLink::CMD_AUTH_LOGON_PROOF, "ClientLink::CMD_AUTH_LOGON_PROOF", &Grunt::ClientLink::CmdAuthLogonProof, 0 }, + { Grunt::ClientLink::CMD_AUTH_RECONNECT_CHALLENGE, "ClientLink::CMD_AUTH_RECONNECT_CHALLENGE", &Grunt::ClientLink::CmdAuthReconnectChallenge, 0 }, + { Grunt::ClientLink::CMD_AUTH_RECONNECT_PROOF, "ClientLink::CMD_AUTH_RECONNECT_PROOF", &Grunt::ClientLink::CmdAuthReconnectProof, 0 }, + { Grunt::ClientLink::CMD_REALM_LIST, "ClientLink::CMD_REALM_LIST", &Grunt::ClientLink::CmdRealmList, 0 }, + { Grunt::ClientLink::CMD_XFER_INITIATE, "ClientLink::CMD_XFER_INITIATE", &Grunt::ClientLink::CmdXferInitiate, 0 }, + { Grunt::ClientLink::CMD_XFER_DATA, "ClientLink::CMD_XFER_DATA", &Grunt::ClientLink::CmdXferData, 0 }, +}; + Grunt::ClientLink::ClientLink(Grunt::ClientResponse& clientResponse) { // TODO @@ -34,6 +44,41 @@ void Grunt::ClientLink::Call() { this->m_critSect.Leave(); } +int32_t Grunt::ClientLink::CmdAuthLogonChallenge(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdAuthLogonProof(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdAuthReconnectChallenge(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdAuthReconnectProof(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdRealmList(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdXferData(CDataStore& msg) { + // TODO + return 0; +} + +int32_t Grunt::ClientLink::CmdXferInitiate(CDataStore& msg) { + // TODO + return 0; +} + void Grunt::ClientLink::Connect(const char* a2) { if (this->m_state) { return; @@ -163,3 +208,23 @@ void Grunt::ClientLink::WCConnected(WowConnection* conn, WowConnection* inbound, this->Disconnect(); } } + +void Grunt::ClientLink::WCDataReady(WowConnection* conn, uint32_t timeStamp, uint8_t* data, int32_t len) { + this->m_datastore1B0.PutArray(data, len); + this->m_datastore1B0.Finalize(); + + uint32_t pos = 0; + if (Grunt::Command::Process(this->m_datastore1B0, Grunt::s_clientCommands, 7u, *this, pos)) { + auto remainingBytes = this->m_datastore1B0.m_size - pos; + this->m_datastore1B0.m_read = pos; + void* remainingData; + this->m_datastore1B0.GetDataInSitu(remainingData, remainingBytes); + this->m_datastore1B0.m_read = -1; + this->m_datastore1B0.Reset(); + this->m_datastore1B0.PutData(remainingData, remainingBytes); + } else { + this->m_datastore1B0.m_read = -1; + this->m_datastore1B0.Reset(); + this->Disconnect(); + } +} diff --git a/src/net/grunt/ClientLink.hpp b/src/net/grunt/ClientLink.hpp index c405e0d..2717c53 100644 --- a/src/net/grunt/ClientLink.hpp +++ b/src/net/grunt/ClientLink.hpp @@ -7,14 +7,24 @@ #include "net/grunt/Timer.hpp" #include "net/srp/SRP6_Client.hpp" #include "net/Types.hpp" +#include #include -class CDataStore; class WowConnection; class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::Timer::Event { public: // Types + enum COMMAND { + CMD_AUTH_LOGON_CHALLENGE = 0, + CMD_AUTH_LOGON_PROOF = 1, + CMD_AUTH_RECONNECT_CHALLENGE = 2, + CMD_AUTH_RECONNECT_PROOF = 3, + CMD_REALM_LIST = 16, + CMD_XFER_INITIATE = 48, + CMD_XFER_DATA = 49, + }; + struct Logon { const char* accountName; const char* password; @@ -34,6 +44,7 @@ class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::T int32_t m_state; SRP6_Client m_srpClient; SCritSect m_critSect; + CDataStore m_datastore1B0; WowConnection* m_connection = nullptr; ClientResponse* m_clientResponse; char m_accountName[1280]; @@ -41,10 +52,18 @@ class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::T // Virtual member functions virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr); virtual void WCCantConnect(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr); + virtual void WCDataReady(WowConnection* conn, uint32_t timeStamp, uint8_t* data, int32_t len); virtual void Call(); // Member functions ClientLink(Grunt::ClientResponse& clientResponse); + int32_t CmdAuthLogonChallenge(CDataStore& msg); + int32_t CmdAuthLogonProof(CDataStore& msg); + int32_t CmdAuthReconnectChallenge(CDataStore& msg); + int32_t CmdAuthReconnectProof(CDataStore& msg); + int32_t CmdRealmList(CDataStore& msg); + int32_t CmdXferData(CDataStore& msg); + int32_t CmdXferInitiate(CDataStore& msg); void Connect(const char* a2); void Disconnect(); void LogonNewSession(const Logon& logon); diff --git a/src/net/grunt/Command.hpp b/src/net/grunt/Command.hpp new file mode 100644 index 0000000..e07ad0d --- /dev/null +++ b/src/net/grunt/Command.hpp @@ -0,0 +1,45 @@ +#ifndef NET_GRUNT_COMMAND_HPP +#define NET_GRUNT_COMMAND_HPP + +#include "net/Grunt.hpp" + +template +class Grunt::Command { + public: + // Static members + static int32_t Process(CDataStore& msg, Command* commands, uint32_t commandCount, T& a4, uint32_t& pos); + + // Member variables + int32_t cmd; + const char* name; + int32_t (T::*callback)(CDataStore& msg); + uint32_t unk; +}; + +template +int32_t Grunt::Command::Process(CDataStore& msg, Command* commands, uint32_t commandCount, T& a4, uint32_t& pos) { + uint8_t cmd; + msg.Get(cmd); + + for (uint32_t i = 0; i < commandCount; i++) { + auto& command = commands[i]; + + if (command.cmd == cmd) { + auto callback = command.callback; + auto result = (a4.*callback)(msg); + + if (result == 0) { + return 1; + } else { + // TODO + return 0; + } + } + } + + // TODO + + return 0; +} + +#endif diff --git a/src/net/grunt/Grunt.hpp b/src/net/grunt/Grunt.hpp index f78b013..8c0dc77 100644 --- a/src/net/grunt/Grunt.hpp +++ b/src/net/grunt/Grunt.hpp @@ -4,8 +4,12 @@ namespace Grunt { class ClientLink; class ClientResponse; + template + class Command; class Pending; class Timer; + + extern Command s_clientCommands[]; } #endif