mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-15 20:32:28 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
165
src/net/grunt/ClientLink.cpp
Normal file
165
src/net/grunt/ClientLink.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#include "net/grunt/ClientLink.hpp"
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include "net/grunt/ClientResponse.hpp"
|
||||
#include <new>
|
||||
#include <common/DataStore.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
Grunt::ClientLink::ClientLink(Grunt::ClientResponse& clientResponse) {
|
||||
// TODO
|
||||
|
||||
this->m_clientResponse = &clientResponse;
|
||||
|
||||
this->SetState(0);
|
||||
|
||||
if (this->m_timer.m_thread.Valid()) {
|
||||
this->m_interval = 100;
|
||||
this->m_timer.Insert(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::Call() {
|
||||
// TODO
|
||||
// this->CheckExpired(false);
|
||||
|
||||
this->m_critSect.Enter();
|
||||
|
||||
if (this->m_state == 2) {
|
||||
this->m_clientResponse->GetLogonMethod();
|
||||
} else if (this->m_state == 6 && !this->m_clientResponse->OnlineIdle()) {
|
||||
this->Disconnect();
|
||||
}
|
||||
|
||||
this->m_critSect.Leave();
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::Connect(const char* a2) {
|
||||
if (this->m_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->SetState(1);
|
||||
|
||||
auto connectionMem = SMemAlloc(sizeof(WowConnection), __FILE__, __LINE__, 0x0);
|
||||
auto connection = new (connectionMem) WowConnection(this, nullptr);
|
||||
|
||||
this->m_connection = connection;
|
||||
this->m_connection->SetType(WOWC_TYPE_STREAM);
|
||||
|
||||
auto port = SStrChr(a2, ':');
|
||||
if (port) {
|
||||
this->m_connection->Connect(a2, 5000);
|
||||
} else {
|
||||
this->m_connection->Connect(a2, 3724, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::Disconnect() {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
if (this->m_connection) {
|
||||
this->m_connection->Disconnect();
|
||||
}
|
||||
|
||||
this->m_critSect.Leave();
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::LogonNewSession(const Grunt::ClientLink::Logon& logon) {
|
||||
this->SetState(3);
|
||||
|
||||
SStrCopy(this->m_accountName, logon.accountName, sizeof(this->m_accountName));
|
||||
SStrUpper(this->m_accountName);
|
||||
|
||||
char* password = static_cast<char*>(alloca(SStrLen(logon.password) + 1));
|
||||
SStrCopy(password, logon.password, STORM_MAX_STR);
|
||||
SStrUpper(password);
|
||||
|
||||
static char accountNameUnDecorated[1280];
|
||||
SStrCopy(accountNameUnDecorated, this->m_accountName, STORM_MAX_STR);
|
||||
auto decoration = const_cast<char*>(SStrChr(accountNameUnDecorated, '#'));
|
||||
if (decoration) {
|
||||
*decoration = '\0';
|
||||
}
|
||||
|
||||
// TODO SRP6_Client::BeginAuthentication
|
||||
|
||||
CDataStoreCache<1024> clientChallenge;
|
||||
|
||||
uint8_t opcode = 0;
|
||||
clientChallenge.Put(opcode);
|
||||
|
||||
uint8_t protocol = 8;
|
||||
clientChallenge.Put(protocol);
|
||||
|
||||
this->PackLogon(clientChallenge, logon);
|
||||
clientChallenge.Finalize();
|
||||
|
||||
this->Send(clientChallenge);
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::PackLogon(CDataStore& msg, const Logon& logon) {
|
||||
uint32_t startPos = msg.m_size;
|
||||
uint16_t tmpSize = 0;
|
||||
msg.Put(tmpSize);
|
||||
|
||||
msg.Put(logon.programID);
|
||||
msg.Put(logon.version[0]);
|
||||
msg.Put(logon.version[1]);
|
||||
msg.Put(logon.version[2]);
|
||||
msg.Put(logon.build);
|
||||
msg.Put(logon.processorID);
|
||||
msg.Put(logon.osID);
|
||||
msg.Put(logon.locale);
|
||||
msg.Put(logon.tz);
|
||||
|
||||
msg.Put(this->m_clientIP);
|
||||
|
||||
uint32_t accountNameLen = SStrLen(this->m_accountName);
|
||||
msg.Put(accountNameLen);
|
||||
msg.PutData(this->m_accountName, accountNameLen);
|
||||
|
||||
msg.Set(startPos, msg.m_size - startPos - 2);
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::Send(CDataStore& msg) {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
if (this->m_connection) {
|
||||
void* data;
|
||||
msg.GetDataInSitu(data, msg.m_size);
|
||||
|
||||
this->m_connection->SendRaw(static_cast<uint8_t*>(data), msg.m_size, false);
|
||||
}
|
||||
|
||||
this->m_critSect.Leave();
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::SetState(int32_t state) {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
this->m_state = state;
|
||||
|
||||
this->m_critSect.Leave();
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::WCCantConnect(WowConnection* conn, uint32_t timeStamp, NETCONNADDR* addr) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Grunt::ClientLink::WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr) {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
this->SetState(2);
|
||||
|
||||
int32_t connected = this->m_clientResponse->Connected(addr->peerAddr);
|
||||
|
||||
// TODO
|
||||
// this->m_clientIP = OsNetAddrGetAddress(&addr->selfAddr, 0);
|
||||
|
||||
this->m_critSect.Leave();
|
||||
|
||||
if (!connected) {
|
||||
this->Disconnect();
|
||||
}
|
||||
}
|
||||
54
src/net/grunt/ClientLink.hpp
Normal file
54
src/net/grunt/ClientLink.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef NET_GRUNT_CLIENT_LINK_HPP
|
||||
#define NET_GRUNT_CLIENT_LINK_HPP
|
||||
|
||||
#include "net/grunt/Grunt.hpp"
|
||||
#include "net/connection/WowConnectionResponse.hpp"
|
||||
#include "net/grunt/Pending.hpp"
|
||||
#include "net/grunt/Timer.hpp"
|
||||
#include "net/Types.hpp"
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class CDataStore;
|
||||
class WowConnection;
|
||||
|
||||
class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::Timer::Event {
|
||||
public:
|
||||
// Types
|
||||
struct Logon {
|
||||
const char* accountName;
|
||||
const char* password;
|
||||
uint32_t programID;
|
||||
uint32_t processorID;
|
||||
uint32_t osID;
|
||||
uint8_t version[4];
|
||||
uint16_t build;
|
||||
uint16_t uint1A;
|
||||
uint32_t locale;
|
||||
uint32_t tz;
|
||||
};
|
||||
|
||||
// Member variables
|
||||
Grunt::Timer m_timer;
|
||||
uint32_t m_clientIP = 0;
|
||||
int32_t m_state;
|
||||
SCritSect m_critSect;
|
||||
WowConnection* m_connection = nullptr;
|
||||
ClientResponse* m_clientResponse;
|
||||
char m_accountName[1280];
|
||||
|
||||
// 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 Call();
|
||||
|
||||
// Member functions
|
||||
ClientLink(Grunt::ClientResponse& clientResponse);
|
||||
void Connect(const char* a2);
|
||||
void Disconnect();
|
||||
void LogonNewSession(const Logon& logon);
|
||||
void PackLogon(CDataStore& msg, const Logon& logon);
|
||||
void Send(CDataStore& msg);
|
||||
void SetState(int32_t state);
|
||||
};
|
||||
|
||||
#endif
|
||||
20
src/net/grunt/ClientResponse.hpp
Normal file
20
src/net/grunt/ClientResponse.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef NET_GRUNT_CLIENT_RESPONSE_HPP
|
||||
#define NET_GRUNT_CLIENT_RESPONSE_HPP
|
||||
|
||||
#include "net/grunt/Grunt.hpp"
|
||||
#include "net/Types.hpp"
|
||||
|
||||
class LoginResponse;
|
||||
|
||||
class Grunt::ClientResponse {
|
||||
public:
|
||||
virtual bool Connected(const NETADDR& addr) = 0;
|
||||
virtual bool OnlineIdle() = 0;
|
||||
virtual void GetLogonMethod() = 0;
|
||||
virtual void GetRealmList() = 0;
|
||||
virtual void Logon(const char* a2, const char* a3) = 0;
|
||||
virtual void Logoff() = 0;
|
||||
virtual void Init(LoginResponse* loginResponse) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
11
src/net/grunt/Grunt.hpp
Normal file
11
src/net/grunt/Grunt.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef NET_GRUNT_GRUNT_HPP
|
||||
#define NET_GRUNT_GRUNT_HPP
|
||||
|
||||
namespace Grunt {
|
||||
class ClientLink;
|
||||
class ClientResponse;
|
||||
class Pending;
|
||||
class Timer;
|
||||
}
|
||||
|
||||
#endif
|
||||
10
src/net/grunt/Pending.hpp
Normal file
10
src/net/grunt/Pending.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef NET_GRUNT_PENDING_HPP
|
||||
#define NET_GRUNT_PENDING_HPP
|
||||
|
||||
#include "net/Grunt.hpp"
|
||||
|
||||
class Grunt::Pending {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
70
src/net/grunt/Timer.cpp
Normal file
70
src/net/grunt/Timer.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include "net/grunt/Timer.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
uint32_t Grunt::Timer::ThreadProc(void* param) {
|
||||
auto timer = static_cast<Timer*>(param);
|
||||
|
||||
while (true) {
|
||||
auto timeout = timer->Pump();
|
||||
|
||||
if (timer->m_event.Wait(timeout) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Grunt::Timer::Timer() {
|
||||
SThread::Create(Grunt::Timer::ThreadProc, this, this->m_thread, "GruntTimerEvt", 0);
|
||||
}
|
||||
|
||||
void Grunt::Timer::Insert(Grunt::Timer::Event& newEvent) {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
newEvent.m_schedTime = OsGetAsyncTimeMsPrecise() + newEvent.m_interval;
|
||||
|
||||
for (auto event = this->m_eventList.Head(); event; event = this->m_eventList.Link(event)->Next()) {
|
||||
// Keep event listed sorted by scheduled time
|
||||
if (newEvent.m_schedTime - event->m_schedTime < 0) {
|
||||
this->m_eventList.LinkNode(&newEvent, 2, event);
|
||||
|
||||
this->m_critSect.Leave();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_eventList.LinkToTail(&newEvent);
|
||||
|
||||
this->m_critSect.Leave();
|
||||
}
|
||||
|
||||
uint32_t Grunt::Timer::Pump() {
|
||||
this->m_critSect.Enter();
|
||||
|
||||
auto* event = this->m_eventList.Head();
|
||||
|
||||
if (!event) {
|
||||
this->m_critSect.Leave();
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
int32_t timeUntilSched = event->m_schedTime - OsGetAsyncTimeMsPrecise();
|
||||
|
||||
if (timeUntilSched <= 0) {
|
||||
this->m_eventList.UnlinkNode(event);
|
||||
|
||||
this->m_critSect.Leave();
|
||||
|
||||
event->Call();
|
||||
this->Insert(*event);
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
this->m_critSect.Leave();
|
||||
|
||||
return timeUntilSched;
|
||||
}
|
||||
37
src/net/grunt/Timer.hpp
Normal file
37
src/net/grunt/Timer.hpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef NET_GRUNT_TIMER_HPP
|
||||
#define NET_GRUNT_TIMER_HPP
|
||||
|
||||
#include "net/grunt/Grunt.hpp"
|
||||
#include "storm/List.hpp"
|
||||
#include "storm/Thread.hpp"
|
||||
|
||||
class Grunt::Timer {
|
||||
public:
|
||||
// Types
|
||||
class Event {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<Event> m_link;
|
||||
uint32_t m_schedTime;
|
||||
uint32_t m_interval;
|
||||
|
||||
// Virtual methods
|
||||
virtual void Call() = 0;
|
||||
};
|
||||
|
||||
// Static functions
|
||||
static uint32_t ThreadProc(void* param);
|
||||
|
||||
// Member variables
|
||||
SEvent m_event = SEvent(0, 0);
|
||||
SThread m_thread;
|
||||
SCritSect m_critSect;
|
||||
STORM_EXPLICIT_LIST(Event, m_link) m_eventList;
|
||||
|
||||
// Member functions
|
||||
Timer();
|
||||
void Insert(Event&);
|
||||
uint32_t Pump();
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue