#include "pch.h"
#include <windows.h>
#include <string>
extern "C" void __declspec(dllexport) __stdcall function1()
{
}
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc;
}
class UNetworkHandler {};
typedef void(__fastcall* RequestAutoSoulShotFn)(UNetworkHandler*, L2ParamStack*);
const uintptr_t unetworkOffset = 0x81F538;
UNetworkHandler** unetwork = nullptr;
RequestAutoSoulShotFn requestAutoSoulShotFn = nullptr;
static void RequestAutoSoulShot(int soulShotId) {
if (!unetwork || !requestAutoSoulShotFn) {
MessageBoxW(NULL, L"Erro: UNetworkHandler not initialized!", L"Debug", MB_OK);
return;
}
// Instância de L2ParamStack
// Chamar a função RequestAutoSoulShotFn com os parâmetros apropriados
requestAutoSoulShotFn(*unetwork, ¶mStack);
MessageBoxW(NULL, L"RequestAutoSoulShot success!", L"Debug", MB_OK);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"InGame", L"L2ConsoleState", MB_OK);
RequestAutoSoulShot(3952);
break;
}
Sleep(5000);
}
}
static DWORD WINAPI TestThread(LPVOID lpParameter) {
L2StatusLoad();
return 0;
}
// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
MessageBoxW(NULL, L"DLL Loading", L"L2ConsoleState", MB_OK);
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
MessageBoxW(NULL, L"DLL Loaded", L"L2ConsoleState", MB_OK);
HMODULE engineModule = GetModuleHandleW(L"engine.dll");
if (engineModule) {
unetwork = reinterpret_cast<UNetworkHandler**>(reinterpret_cast<uintptr_t>(engineModule) + unetworkOffset);
requestAutoSoulShotFn = (RequestAutoSoulShotFn)GetProcAddress(engineModule,"?RequestAutoSoulShot@UNetworkHandler@@UAEXAAVL2ParamStack@@@Z");
}
CreateThread(nullptr, 0, TestThread, nullptr, 0, nullptr);
}
return TRUE;
}
template <class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline TArray(const size_t size)
{
Data = new T[size];
Count = Max = 0;
};
inline void Add(T value)
{
Data[Count++] = value;
Max++;
}
inline size_t Num() const
{
return Count;
};
inline T& operator[](size_t i)
{
return Data[i];
};
inline const T& operator[](size_t i) const
{
return Data[i];
};
inline bool IsValidIndex(size_t i) const
{
return i < Num();
}
inline T& GetByIndex(size_t i)
{
return Data[i];
}
inline const T& GetByIndex(size_t i) const
{
return Data[i];
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString() = default;
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = const_cast<wchar_t*>(other);
}
};
inline bool IsValid() const
{
return Data != nullptr;
}
inline const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
std::wstring ToWString() const
{
return std::wstring(c_str());
}
};
struct L2ParamStack
{
public:
TArray<uint64_t> m_Stack;
int CurrentIndex;
int StackSize;
int StackTotalSize;
L2ParamStack(): m_Stack(50), CurrentIndex(0), StackSize(0), StackTotalSize(0)
{
}
void Push(uint64_t i)
{
m_Stack.Add(i);
CurrentIndex++;
StackSize++;
StackTotalSize++;
}
void Restart()
{
CurrentIndex = 0;
}
};
void RequestAutoSoulShot(const uint32_t item_id, const uint32_t type)
{
L2ParamStack param_stack;
param_stack.Push(item_id);
param_stack.Push(type);
param_stack.Restart();
requestAutoSoulShotFn(*unetwork, ¶m_stack)
}
C++:template <class T> struct TArray { friend struct FString; public: inline TArray() { Data = nullptr; Count = Max = 0; }; inline TArray(const size_t size) { Data = new T[size]; Count = Max = 0; }; inline void Add(T value) { Data[Count++] = value; Max++; } inline size_t Num() const { return Count; }; inline T& operator[](size_t i) { return Data[i]; }; inline const T& operator[](size_t i) const { return Data[i]; }; inline bool IsValidIndex(size_t i) const { return i < Num(); } inline T& GetByIndex(size_t i) { return Data[i]; } inline const T& GetByIndex(size_t i) const { return Data[i]; } private: T* Data; int32_t Count; int32_t Max; }; struct FString : private TArray<wchar_t> { FString() = default; FString(const wchar_t* other) { Max = Count = *other ? std::wcslen(other) + 1 : 0; if (Count) { Data = const_cast<wchar_t*>(other); } }; inline bool IsValid() const { return Data != nullptr; } inline const wchar_t* c_str() const { return Data; } std::string ToString() const { auto length = std::wcslen(Data); std::string str(length, '\0'); std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]); return str; } std::wstring ToWString() const { return std::wstring(c_str()); } }; struct L2ParamStack { public: TArray<uint64_t> m_Stack; int CurrentIndex; int StackSize; int StackTotalSize; L2ParamStack(): m_Stack(50), CurrentIndex(0), StackSize(0), StackTotalSize(0) { } void Push(uint64_t i) { m_Stack.Add(i); CurrentIndex++; StackSize++; StackTotalSize++; } void Restart() { CurrentIndex = 0; } };
And then you need push two params needed for packet (type 1 = on : 0 = off).
Guessed code:
C++:void RequestAutoSoulShot(const uint32_t item_id, const uint32_t type) { L2ParamStack param_stack; param_stack.Push(item_id); param_stack.Push(type); param_stack.Restart(); requestAutoSoulShotFn(*unetwork, ¶m_stack) }
TArray's source also included in my answer. L2ParamStack reconstructed from decompile manually (i'm not sure it's a fully same with original, but works for me)Привет, спасибо!! У меня есть вопрос: у меня проблема с TARRAY, у вас есть заголовочный файл? Или вы сделали какую-то реализацию для него? Еще вопрос: как вы пришли к этим функциям в paramstack? Я не нашел его реализацию в DLL.
TArray's source also included in my answer. L2ParamStack reconstructed from decompile manually (i'm not sure it's a fully same with original, but works for me)
#include "pch.h"
#include <windows.h>
#include <string>
#include <locale>
extern "C" void __declspec(dllexport) __stdcall function1()
{
}
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc;
}
template <class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline TArray(const size_t size)
{
Data = new T[size];
Count = Max = 0;
};
inline void Add(T value)
{
Data[Count++] = value;
Max++;
}
inline size_t Num() const
{
return Count;
};
inline T& operator[](size_t i)
{
return Data[i];
};
inline const T& operator[](size_t i) const
{
return Data[i];
};
inline bool IsValidIndex(size_t i) const
{
return i < Num();
}
inline T& GetByIndex(size_t i)
{
return Data[i];
}
inline const T& GetByIndex(size_t i) const
{
return Data[i];
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString() = default;
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = const_cast<wchar_t*>(other);
}
};
inline bool IsValid() const
{
return Data != nullptr;
}
inline const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
std::wstring ToWString() const
{
return std::wstring(c_str());
}
};
struct L2ParamStack
{
public:
TArray<uint64_t> m_Stack;
int CurrentIndex;
int StackSize;
int StackTotalSize;
L2ParamStack() : m_Stack(50), CurrentIndex(0), StackSize(0), StackTotalSize(0)
{
}
void Push(uint64_t i)
{
m_Stack.Add(i);
CurrentIndex++;
StackSize++;
StackTotalSize++;
}
void Restart()
{
CurrentIndex = 0;
}
};
class UNetworkHandler {};
typedef void(__thiscall* RequestAutoSoulShotFn)(UNetworkHandler*, L2ParamStack*);
const uintptr_t unetworkOffset = 0x81F538;
UNetworkHandler** unetwork = nullptr;
RequestAutoSoulShotFn requestAutoSoulShotFn = nullptr;
static void RequestAutoSoulShot(const uint32_t item_id, const uint32_t type) {
if (!unetwork || !requestAutoSoulShotFn) {
MessageBoxW(NULL, L"Erro: UNetworkHandler not initialized!", L"Debug", MB_OK);
return;
}
L2ParamStack param_stack;
param_stack.Push(item_id);
param_stack.Push(type);
param_stack.Restart();
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"Item pushed: item_id=%llu, type=%llu",
param_stack.m_Stack[0], param_stack.m_Stack[1]);
MessageBoxW(NULL, debugMsg, L"Debug", MB_OK);
requestAutoSoulShotFn(*unetwork, ¶m_stack);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"InGame", L"L2ConsoleState", MB_OK);
RequestAutoSoulShot(3952, 1);
break;
}
Sleep(5000);
}
}
static DWORD WINAPI TestThread(LPVOID lpParameter) {
L2StatusLoad();
return 0;
}
// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
MessageBoxW(NULL, L"DLL Loading", L"L2ConsoleState", MB_OK);
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
MessageBoxW(NULL, L"DLL Loaded", L"L2ConsoleState", MB_OK);
HMODULE engineModule = GetModuleHandleW(L"engine.dll");
if (engineModule) {
unetwork = reinterpret_cast<UNetworkHandler**>(reinterpret_cast<uintptr_t>(engineModule) + unetworkOffset);
requestAutoSoulShotFn = (RequestAutoSoulShotFn)GetProcAddress(engineModule,"?RequestAutoSoulShot@UNetworkHandler@@UAEXAAVL2ParamStack@@@Z");
}
CreateThread(nullptr, 0, TestThread, nullptr, 0, nullptr);
}
return TRUE;
}
I'm just tested in my own client extender and all works perfectly. But i'm using VT hooking for NetworkHandler.
So i'm not sure you are hooking RequestAutoSoulShot correctly.
Ваша задача отправить правильную структуру, наличие или отсутствие метода ни на что не влияет. Я проверял только на High Five.Я подозревал, что проблема в отсутствии функции TOP(), которая используется в функции, но вы проверяли это в IL? Я думаю, что мой offset для NetworkHandler правильный, и, возможно, проблема в функции RequestAutoSoulShot, потому что пакет дошел до моего сервера, но он пришел с нулевыми значениями ss_id и type.
=) u are saying gibberish things , Push Is used to push something into some address/space and TOP -"translated" to get rid of something, in other words retrieve data from previous address/space into an variable/variables .I suspected that the problem might be the absence of the TOP() function, which is used in the code, but did you test it in the IL? I think my offset for NetworkHandler is correct, and maybe the issue is with the RequestAutoSoulShot function, because the packet reached my server, but it arrived with ss_id and type set to zero.
I ended up getting confused; actually, I thought I needed to implement all the functions of ParamStack. I implemented a few, tested with int64, and it started sending the correct item_id value to the server. However, it seems something is happening where the index of _type is not being retrieved, and it always sends 0 to the server. I suspect it might be something in the stack implementation:=) u are saying gibberish things , Push Is used to push something into some address/space and TOP -"translated" to get rid of something, in other words retrieve data from previous address/space into an variable/variables .
What could be the problem in HighFive vs Interlude is 64 32 bit space , stack could be TArray<uint32_t> m_Stack; that's first issue , but more like it that Tarray has incorrect alignment and structure data CurrentIndex has to be part of Tarray .
More of that int StackSize; logically its not StackSize its PushNum and it should be increased only once per call; like this PushNum=PushNum+ 1; and StackTotalSize its not StackTotalSize but TopPopNum and is increased once per call ( to the function) , if this won't be done then when original L2Top function is called in "?RequestAutoSoulShot@UNetworkHandler@@UAEXAAVL2ParamStack@@@Z" function it won't handle the data and return 0( because TopPopNum is allready bigger orEquals then PushNum ) ;
template <class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline TArray(const size_t size)
{
Data = new T[size];
Count = 0;
Max = static_cast<int32_t>(size); // Defina o tamanho máximo corretamente
};
inline void Add(T value)
{
if (Count < Max) { // Certifique-se de que não exceda o limite
Data[Count++] = value;
}
}
inline size_t Num() const
{
return Count;
};
inline T& operator[](size_t i)
{
return Data[i];
};
inline const T& operator[](size_t i) const
{
return Data[i];
};
inline bool IsValidIndex(size_t i) const
{
return i < Num();
}
inline T& GetByIndex(size_t i)
{
return Data[i];
}
inline const T& GetByIndex(size_t i) const
{
return Data[i];
}
// Getter para o tamanho máximo
inline int32_t GetMax() const
{
return Max;
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString() = default;
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = const_cast<wchar_t*>(other);
}
};
inline bool IsValid() const
{
return Data != nullptr;
}
inline const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
std::wstring ToWString() const
{
return std::wstring(c_str());
}
};
struct L2ParamStack
{
public:
TArray<uint64_t> m_Stack;
int PushNum;
int TopPopNum;
L2ParamStack() : m_Stack(50), PushNum(0), TopPopNum(0)
{
}
int PushBack(uint64_t value)
{
m_Stack.Add(value);
PushNum++;
TopPopNum = PushNum;
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"PushBack: Value=%llu, PushNum=%d, TopPopNum=%d", value, PushNum, TopPopNum);
MessageBoxW(NULL, debugMsg, L"Debug - PushBack", MB_OK);
return PushNum;
}
void Restart()
{
TopPopNum = 0;
}
};
class UNetworkHandler {};
typedef void(__thiscall* RequestAutoSoulShotFn)(UNetworkHandler*, L2ParamStack*);
const uintptr_t unetworkOffset = 0x81F538;
UNetworkHandler** unetwork = nullptr;
RequestAutoSoulShotFn requestAutoSoulShotFn = nullptr;
static void RequestAutoSoulShot(const uint64_t item_id, const uint64_t type) {
if (!unetwork || !requestAutoSoulShotFn) {
MessageBoxW(NULL, L"Erro: UNetworkHandler not initialized!", L"Debug", MB_OK);
return;
}
L2ParamStack param_stack;
param_stack.PushBack(type);
param_stack.PushBack(item_id);
param_stack.Restart();
// Log do estado do L2ParamStack
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"L2ParamStack: Stack[0]=%llu, Stack[1]=%llu, PushNum=%d, TopPopNum=%d",
param_stack.m_Stack[0], param_stack.m_Stack[1],
param_stack.PushNum, param_stack.TopPopNum);
MessageBoxW(NULL, debugMsg, L"Debug - L2ParamStack", MB_OK);
requestAutoSoulShotFn(*unetwork, ¶m_stack);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"InGame", L"L2ConsoleState", MB_OK);
RequestAutoSoulShot(3952, 1);
break;
}
Sleep(5000);
}
}
StackTotalSize = PushNum;
StackSize = TopPopNum ;
TopPopNum shouldn't be increased(Atleast)
#include "pch.h"
#include <windows.h>
#include <string>
#include <locale>
extern "C" void __declspec(dllexport) __stdcall function1()
{
}
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc;
}
template <class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline TArray(const size_t size)
{
Data = new T[size];
Count = 0;
Max = static_cast<int32_t>(size); // Defina o tamanho máximo corretamente
};
inline void Add(T value)
{
if (Count < Max) { // Certifique-se de que não exceda o limite
Data[Count++] = value;
}
}
inline size_t Num() const
{
return Count;
};
inline T& operator[](size_t i)
{
return Data[i];
};
inline const T& operator[](size_t i) const
{
return Data[i];
};
inline bool IsValidIndex(size_t i) const
{
return i < Num();
}
inline T& GetByIndex(size_t i)
{
return Data[i];
}
inline const T& GetByIndex(size_t i) const
{
return Data[i];
}
void Restart() {
Count = 0;
}
// Getter para o tamanho máximo
inline int32_t GetMax() const
{
return Max;
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString() = default;
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = const_cast<wchar_t*>(other);
}
};
inline bool IsValid() const
{
return Data != nullptr;
}
inline const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
std::wstring ToWString() const
{
return std::wstring(c_str());
}
};
struct L2ParamStack
{
public:
TArray<uint32_t> m_Stack;
int PushNum;
int TopPopNum;
L2ParamStack() : m_Stack(50), PushNum(0), TopPopNum(0)
{
}
int Push(uint32_t value)
{
if (PushNum > m_Stack.GetMax()) {
MessageBoxW(NULL, L"Erro: Stack cheio!", L"Debug - PushBack", MB_OK);
return -1;
}
m_Stack.Add(value);
PushNum++;
TopPopNum = PushNum;
return PushNum;
/* m_Stack.Add(value);
PushNum++;
TopPopNum = PushNum;
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"PushBack: Value=%llu, PushNum=%d, TopPopNum=%d", value, PushNum, TopPopNum);
MessageBoxW(NULL, debugMsg, L"Debug - PushBack", MB_OK);
return PushNum;*/
}
void Restart()
{
TopPopNum = 0;
PushNum = 0;
m_Stack.Restart();
}
};
class UNetworkHandler {};
typedef void(__thiscall* RequestAutoSoulShotFn)(UNetworkHandler*, L2ParamStack*);
const uintptr_t unetworkOffset = 0x81F538;
UNetworkHandler** unetwork = nullptr;
RequestAutoSoulShotFn requestAutoSoulShotFn = nullptr;
static void RequestAutoSoulShot(const uint32_t item_id, const bool useSoulShot) {
if (!unetwork || !requestAutoSoulShotFn) {
MessageBoxW(NULL, L"Erro: UNetworkHandler not initialized!", L"Debug", MB_OK);
return;
}
L2ParamStack param_stack;
uint8_t type = useSoulShot ? 0x01 : 0x00;
param_stack.Push(item_id);
param_stack.Push(type);
param_stack.Restart();
// Log do estado do L2ParamStack
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"L2ParamStack: Stack[0]=%llu, Stack[1]=%llu, PushNum=%d, TopPopNum=%d",
param_stack.m_Stack[0], param_stack.m_Stack[1],
param_stack.PushNum, param_stack.TopPopNum);
MessageBoxW(NULL, debugMsg, L"Debug - L2ParamStack", MB_OK);
requestAutoSoulShotFn(*unetwork, ¶m_stack);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"InGame", L"L2ConsoleState", MB_OK);
RequestAutoSoulShot(3952, true);
break;
}
Sleep(5000);
}
}
static DWORD WINAPI TestThread(LPVOID lpParameter) {
L2StatusLoad();
return 0;
}
// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
MessageBoxW(NULL, L"DLL Loading", L"L2ConsoleState", MB_OK);
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
MessageBoxW(NULL, L"DLL Loaded", L"L2ConsoleState", MB_OK);
HMODULE engineModule = GetModuleHandleW(L"engine.dll");
if (engineModule) {
unetwork = reinterpret_cast<UNetworkHandler**>(reinterpret_cast<uintptr_t>(engineModule) + unetworkOffset);
requestAutoSoulShotFn = (RequestAutoSoulShotFn)GetProcAddress(engineModule,"?RequestAutoSoulShot@UNetworkHandler@@UAEXAAVL2ParamStack@@@Z");
}
CreateThread(nullptr, 0, TestThread, nullptr, 0, nullptr);
}
return TRUE;
}
extern "C" __declspec(dllexport) void RequestAutoSoulShot(const uint32_t item_id, const bool useSoulShot)
{
// ... your function implementation ...
}
native function RequestAutoSoulShot(int itemId, bool useSoulShot);
struct L2ParamStack
{
public:
TArray<uint32_t> m_Stack;
int PushNum;
int TopPopNum;
L2ParamStack() : m_Stack(50), PushNum(0), TopPopNum(0)
{
}
int Push(uint32_t value)
{
if (PushNum > m_Stack.GetMax()) {
MessageBoxW(NULL, L"Erro: Stack cheio!", L"Debug - PushBack", MB_OK);
return -1;
}
m_Stack.Add(value);
PushNum++;
TopPopNum++;
return PushNum;
/* m_Stack.Add(value);
PushNum++;
TopPopNum = PushNum;
wchar_t debugMsg[256];
swprintf(debugMsg, 256, L"PushBack: Value=%llu, PushNum=%d, TopPopNum=%d", value, PushNum, TopPopNum);
MessageBoxW(NULL, debugMsg, L"Debug - PushBack", MB_OK);
return PushNum;*/
}
void Restart()
{
PushNum = 0;
m_Stack.Restart();
}
};
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#define RESULT_DECL void*const Result
typedef void (*Native)(struct FFrame& TheStack, RESULT_DECL);
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);
GRegisterNative_fnType volatile GRegisterNative_fn = NULL;
void RequestAutoSoulShot(struct FFrame& Stack, RESULT_DECL)
{
MessageBox(nullptr, L"TEST", L"hook", MB_OK);
}
// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call != DLL_PROCESS_ATTACH) {
return TRUE;
}
auto hCore = GetModuleHandleA("Core.dll");
if (!hCore) {
MessageBoxW(NULL, L"FailedToGetHCore", L"hook", MB_OK);
return true;
}
GRegisterNative_fn = (GRegisterNative_fnType)GetProcAddress(hCore, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z");
if (!GRegisterNative_fn) {
MessageBox(nullptr, L"Nullable GRegisterNative_fn", L"hook", MB_OK);
return true;
}
GRegisterNative_fn(4004, &RequestAutoSoulShot);
return TRUE;
}
native(4004) final function RequestAutoSoulShot( int itemID, _type bool );
when u push u push dont increment Top , its incremented when its being used .TopPopNum++;
I'm not sure about that but u can/should define it in same Package/Script.uc that your Package.Dll name is , u can try to define it elsewhere in Nwindow.u or Interface.u but as far as i remember UScript Linker is looking in exact Package.dll for native function , i might be wrong.at any point in my UC? For example, NWindow/UIScript.UC?
It depends on what u want that function to be doing, look for other similiar function implementation for that.arguments itemID and _type from the stack? Can you tell me if that's correct?
Got it, I understand about the stack now, thank you!!quando você empurra, você empurra, não aumenta o topo, ele é incrementado quando está sendo usado.
Não tenho certeza sobre isso, mas você pode/deve defini-lo no mesmo Package/Script.uc que seu nome Package.Dll é, você pode tentar defini-lo em outro lugar em Nwindow.u ou Interface.u, mas pelo que me lembro O UScript Linker está procurando no Package.dll exato a função nativa, posso estar errado.
Depende do que você deseja que essa função faça, procure outra implementação de função semelhante para isso.
class AutoShotItemWnd extends UICommonAPI;
var WindowHandle zzMe;
var ItemWindowHandle zzinventory_item;
var ItemWindowHandle rhand;
var ItemInfo zziteminfoka;
var int _type;
var int _activateShotType;
var int _shotID;
var int zzkiaka2a;
var bool zzasnewk;
var ShortcutWnd zzshortcut;
function registerload()
{
RegisterEvent(150);
RegisterEvent(40);
RegisterEvent(2610);
RegisterEvent(693);
RegisterEvent(44467);
return;
}
function sendRequestToServer(optional int shotID, optional int _type)
{
local string zParam;
// End:0x21
if( shotID > 10000 )
{
shotID = shotID - 10000;
}
RequestAutoSoulShot(shotID, True);
//RequestBypassToServer((("RequestAutoShot: ShotID="$string(shotID))$" bEnable=")$string(_type));
ParamAdd(zParam, "ShotID", string(shotID));
ParamAdd(zParam, "bEnable", string(_type));
if( _type == 1 )
{
ActivateAnimation(zParam);
}
return;
}
function OnLoad()
{ handleEquipRHandItem();
registerload();
inithandle();
sendRequestToServer();
return;
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?