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