Cube-World-Mod-Launcher/CubeModLoader/main.cpp

130 lines
4.2 KiB
C++
Raw Normal View History

2019-09-13 08:41:28 +08:00
#include <iostream>
#include <windows.h>
#include <vector>
2019-09-15 03:24:12 +08:00
#include "DLL.h"
2019-10-06 03:59:20 +08:00
#define MOD_MAJOR_VERSION 4
2019-09-15 03:24:12 +08:00
#define MOD_MINOR_VERSION 1
#define no_optimize __attribute__((optimize("O0")))
#define MUST_IMPORT(dllname, name)\
dllname->name = GetProcAddress(dllname->handle, #name);\
if (!dllname->name) {\
2019-09-25 07:03:07 +08:00
char ERROR_MESSAGE_POPUP[512] = {0};\
sprintf(ERROR_MESSAGE_POPUP, "%s does not export " #name ".\n", dllname->fileName.c_str());\
Popup("Error", ERROR_MESSAGE_POPUP);\
2019-09-15 03:24:12 +08:00
exit(1);\
}
#define IMPORT(dllname, name)\
dllname->name = GetProcAddress(dllname->handle, #name);
2019-09-22 01:12:00 +08:00
#define PUSH_ALL "push rax\npush rbx\npush rcx\npush rdx\npush rsi\npush rdi\npush rbp\npush r8\npush r9\npush r10\npush r11\npush r12\npush r13\npush r14\npush r15\n"
#define POP_ALL "pop r15\npop r14\npop r13\npop r12\npop r11\npop r10\npop r9\npop r8\npop rbp\npop rdi\npop rsi\npop rdx\npop rcx\npop rbx\npop rax\n"
2019-09-23 07:17:15 +08:00
#define PREPARE_STACK "mov rax, rsp \n and rsp, 0xFFFFFFFFFFFFFFF0 \n push rax \n sub rsp, 0x28 \n"
#define RESTORE_STACK "add rsp, 0x28 \n pop rsp \n"
2019-09-13 08:41:28 +08:00
using namespace std;
2019-09-15 03:24:12 +08:00
void* base;
vector <DLL*> modDLLs;
void WriteFarJMP(void* source, void* destination) {
DWORD dwOldProtection;
VirtualProtect(source, 14, PAGE_EXECUTE_READWRITE, &dwOldProtection);
char* location = (char*)source;
// Far jump
*((UINT16*)&location[0]) = 0x25FF;
// mode
*((UINT32*)&location[2]) = 0x00000000;
*((UINT64*)&location[6]) = (UINT64)destination;
VirtualProtect(location, 14, dwOldProtection, &dwOldProtection);
}
2019-10-06 03:59:20 +08:00
#include "callbacks/ChatHandler.h"
#include "callbacks/P2PRequestHandler.h"
2019-09-15 03:24:12 +08:00
void SetupHandlers() {
2019-09-22 01:12:00 +08:00
SetupChatHandler();
2019-10-06 03:59:20 +08:00
SetupP2PRequestHandler();
2019-09-15 03:24:12 +08:00
}
2019-10-10 18:14:22 +08:00
void Popup(const char* title, char* msg ){
2019-09-23 07:17:15 +08:00
MessageBoxA(0, msg, title, MB_OK | MB_ICONINFORMATION);
}
2019-09-13 08:41:28 +08:00
extern "C" __declspec(dllexport) BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
2019-09-15 03:24:12 +08:00
base = GetModuleHandle(NULL);
2019-09-13 08:41:28 +08:00
2019-09-15 03:24:12 +08:00
SetupHandlers();
2019-09-13 08:41:28 +08:00
//Find mods
HANDLE hFind;
WIN32_FIND_DATA data;
CreateDirectory("Mods", NULL);
hFind = FindFirstFile("Mods\\*.dll", &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
2019-09-15 03:24:12 +08:00
// We should be loaded into the application's address space, so we can just LoadLibraryA
DLL* dll = new DLL(string("Mods\\") + data.cFileName);
dll->Load();
2019-09-15 07:59:24 +08:00
printf("Loaded %s\n", dll->fileName.c_str());
2019-09-15 03:24:12 +08:00
modDLLs.push_back(dll);
2019-09-13 08:41:28 +08:00
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
2019-09-15 03:24:12 +08:00
// Find all the functions the mods may export
for (DLL* dll: modDLLs) {
MUST_IMPORT(dll, ModMajorVersion);
MUST_IMPORT(dll, ModMinorVersion);
2019-09-15 07:59:24 +08:00
MUST_IMPORT(dll, ModPreInitialize);
IMPORT(dll, ModInitialize);
2019-09-22 01:12:00 +08:00
IMPORT(dll, HandleChat);
2019-10-06 03:59:20 +08:00
IMPORT(dll, HandleP2PRequest);
2019-09-15 03:24:12 +08:00
}
2019-09-15 07:59:24 +08:00
// Ensure version compatibility
2019-09-25 07:03:07 +08:00
char msg[512] = {0};
2019-09-15 07:59:24 +08:00
for (DLL* dll: modDLLs) {
int majorVersion = ((int(*)())dll->ModMajorVersion)();
int minorVersion = ((int(*)())dll->ModMinorVersion)();
if (majorVersion != MOD_MAJOR_VERSION) {
2019-09-25 07:03:07 +08:00
sprintf(msg, "%s has major version %d but requires %d.\n", dll->fileName.c_str(), majorVersion, MOD_MAJOR_VERSION);
Popup("Error", msg);
2019-09-15 07:59:24 +08:00
exit(1);
}
if (minorVersion > MOD_MINOR_VERSION) {
2019-09-25 07:03:07 +08:00
sprintf(msg, "%s has minor version %d but requires %d or lower.\n", dll->fileName.c_str(), minorVersion, MOD_MINOR_VERSION);
Popup("Error", msg);
2019-09-15 07:59:24 +08:00
exit(1);
}
}
2019-09-15 03:24:12 +08:00
// Run Initialization routines on all mods
for (DLL* dll: modDLLs) {
2019-09-15 07:59:24 +08:00
((void(*)())dll->ModPreInitialize)();
}
for (DLL* dll: modDLLs) {
if (dll->ModInitialize) {
((void(*)())dll->ModInitialize)();
}
2019-09-13 08:41:28 +08:00
}
2019-09-15 03:24:12 +08:00
2019-09-13 08:41:28 +08:00
}
return true;
}