refactor how mods are created, add new callback
This commit is contained in:
parent
3eba6f4ec5
commit
5c0ce6c139
|
@ -2,6 +2,7 @@
|
|||
#define DLL_H
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include "GenericMod.h"
|
||||
|
||||
class DLL
|
||||
{
|
||||
|
@ -10,14 +11,11 @@ class DLL
|
|||
HMODULE handle;
|
||||
|
||||
FARPROC ModPreInitialize;
|
||||
FARPROC ModInitialize;
|
||||
FARPROC ModMajorVersion;
|
||||
FARPROC ModMinorVersion;
|
||||
FARPROC MakeMod;
|
||||
|
||||
// Callbacks
|
||||
FARPROC HandleChat;
|
||||
FARPROC HandleP2PRequest;
|
||||
FARPROC HandleCheckInventoryFull;
|
||||
GenericMod* mod;
|
||||
|
||||
DLL(std::string fileName);
|
||||
HMODULE Load();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef GENERICMOD_H
|
||||
#define GENERICMOD_H
|
||||
|
||||
class GenericMod {
|
||||
public:
|
||||
virtual void Initialize() {}
|
||||
virtual int OnChat(void* msg) { return 0; }
|
||||
virtual int OnCheckInventoryFull(void* player, void* item) { return 0; }
|
||||
virtual int OnP2PRequest(uint64_t steamID) { return 0; }
|
||||
virtual void OnGameTick(void* game) {}
|
||||
};
|
||||
|
||||
#endif // GENERICMOD_H
|
|
@ -1,11 +1,9 @@
|
|||
extern "C" int ChatHandler(wchar_t* msg) {
|
||||
extern "C" int ChatHandler(void* msg) {
|
||||
for (DLL* dll: modDLLs) {
|
||||
if (dll->HandleChat) {
|
||||
if ( ((int(*)(wchar_t*))dll->HandleChat)(msg) ){
|
||||
if (dll->mod->OnChat(msg)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -15,7 +13,7 @@ void ASMChatHandler() {
|
|||
asm(".intel_syntax \n"
|
||||
PUSH_ALL
|
||||
|
||||
"mov rcx, rbx \n" // The message
|
||||
"mov rcx, rbx \n" //The (std::wstring*) message
|
||||
|
||||
PREPARE_STACK
|
||||
|
||||
|
@ -30,9 +28,12 @@ void ASMChatHandler() {
|
|||
POP_ALL
|
||||
|
||||
// original code
|
||||
"mov qword ptr [rbp+0x88], 7 \n"
|
||||
"mov [rbp+0x80], r12 \n"
|
||||
"mov [rbp+0x70], r12w \n"
|
||||
"mov [rsp+0x48], rax \n"
|
||||
"mov r8, [rbx+0x10] \n"
|
||||
"cmp qword ptr [rbx+0x18], 8 \n"
|
||||
"jb 1f \n"
|
||||
"mov rbx, [rbx] \n"
|
||||
"1: \n"
|
||||
DEREF_JMP(ASMChatHandler_jmpback)
|
||||
|
||||
|
||||
|
@ -42,7 +43,7 @@ void ASMChatHandler() {
|
|||
);
|
||||
}
|
||||
void SetupChatHandler() {
|
||||
WriteFarJMP(Offset(base, 0x97198), (void*)&ASMChatHandler);
|
||||
ASMChatHandler_jmpback = Offset(base, 0x971B0);
|
||||
WriteFarJMP(Offset(base, 0x97175), (void*)&ASMChatHandler);
|
||||
ASMChatHandler_jmpback = Offset(base, 0x97188);
|
||||
ASMChatHandler_bail = Offset(base, 0x9777A);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
extern "C" int CheckInventoryFullHandler(void* player, void* item) {
|
||||
for (DLL* dll: modDLLs) {
|
||||
if (dll->HandleCheckInventoryFull) {
|
||||
if ( int result = ((int(*)(void*, void*))dll->HandleCheckInventoryFull)(player, item) ){
|
||||
if ( int result = dll->mod->OnCheckInventoryFull(player, item) ){
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
extern "C" void GameTickHandler(void* game) {
|
||||
for (DLL* dll: modDLLs) {
|
||||
dll->mod->OnGameTick(game);
|
||||
}
|
||||
}
|
||||
|
||||
GETTER_VAR(void*, ASMGameTickHandler_jmpback);
|
||||
void ASMGameTickHandler() {
|
||||
asm(".intel_syntax \n"
|
||||
PUSH_ALL
|
||||
|
||||
"mov rcx, rax \n" // cube::Game*
|
||||
|
||||
PREPARE_STACK
|
||||
|
||||
"call GameTickHandler \n"
|
||||
|
||||
RESTORE_STACK
|
||||
|
||||
POP_ALL
|
||||
|
||||
// original code
|
||||
"mov [rsp+0x20], ebx \n"
|
||||
"xor r9d, r9d \n"
|
||||
"xor r8d, r8d \n"
|
||||
"xor edx, edx \n"
|
||||
"lea rcx, [rbp+0xB8] \n"
|
||||
|
||||
DEREF_JMP(ASMGameTickHandler_jmpback)
|
||||
);
|
||||
}
|
||||
void SetupGameTickHandler() {
|
||||
WriteFarJMP(Offset(base, 0x136458), (void*)&ASMGameTickHandler);
|
||||
ASMGameTickHandler_jmpback = Offset(base, 0x13646B);
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
extern "C" int P2PRequestHandler(long long steamID) {
|
||||
for (DLL* dll: modDLLs) {
|
||||
if (dll->HandleP2PRequest) {
|
||||
if ( int result = ((int(*)(long long))dll->HandleP2PRequest)(steamID) ){
|
||||
if (int result = dll->mod->OnP2PRequest(steamID)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,13 @@ GETTER_VAR(void*, initterm_e); // A pointer to that function
|
|||
#include "callbacks/ChatHandler.h"
|
||||
#include "callbacks/P2PRequestHandler.h"
|
||||
#include "callbacks/CheckInventoryFullHandler.h"
|
||||
#include "callbacks/GameTickHandler.h"
|
||||
|
||||
void SetupHandlers() {
|
||||
SetupChatHandler();
|
||||
SetupP2PRequestHandler();
|
||||
SetupCheckInventoryFullHandler();
|
||||
SetupGameTickHandler();
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,10 +76,7 @@ extern "C" void StartMods() {
|
|||
MUST_IMPORT(dll, ModMajorVersion);
|
||||
MUST_IMPORT(dll, ModMinorVersion);
|
||||
MUST_IMPORT(dll, ModPreInitialize);
|
||||
IMPORT(dll, ModInitialize);
|
||||
IMPORT(dll, HandleChat);
|
||||
IMPORT(dll, HandleP2PRequest);
|
||||
IMPORT(dll, HandleCheckInventoryFull);
|
||||
MUST_IMPORT(dll, MakeMod);
|
||||
}
|
||||
|
||||
// Ensure version compatibility
|
||||
|
@ -100,12 +99,11 @@ extern "C" void StartMods() {
|
|||
// Run Initialization routines on all mods
|
||||
for (DLL* dll: modDLLs) {
|
||||
((void(*)())dll->ModPreInitialize)();
|
||||
dll->mod = ((GenericMod*(*)())dll->MakeMod)();
|
||||
}
|
||||
|
||||
for (DLL* dll: modDLLs) {
|
||||
if (dll->ModInitialize) {
|
||||
((void(*)())dll->ModInitialize)();
|
||||
}
|
||||
dll->mod->Initialize();
|
||||
}
|
||||
|
||||
if (hSelf) PrintLoadedMods();
|
||||
|
|
Loading…
Reference in New Issue