Begin transition to the new ModLoader paradigm. Begin cleaning up code.

This commit is contained in:
Robert MacGregor 2017-07-21 04:30:15 -04:00
parent 015a9f4dc8
commit cb9895a38e
39 changed files with 1429 additions and 967 deletions

View file

@ -4,16 +4,24 @@
#include "stdafx.h"
#include <LinkerAPI.h>
#include <DXAPI\ScriptObject.h>
#include <ModLoader\ModLoader.h>
static std::tr1::unordered_set<ServerProcessPointer> sServerProcessResponders;
//! A vector of mod callables.
static std::vector<ModLoader::ModLoaderCallables*> sModCallables;
void serverProcessReplacement(unsigned int timeDelta)
{
unsigned int servertickaddr=0x602350;
unsigned int serverthisptr=0x9E5EC0;
for (auto it = sServerProcessResponders.begin(); it != sServerProcessResponders.end(); it++)
(*it)(timeDelta);
// Call the server process hook for all eligible mods
for (auto it = sModCallables.begin(); it != sModCallables.end(); it++)
{
ModLoader::ModLoaderCallables* currentCallables = *it;
if (currentCallables->mServerProcessPointer != NULL)
currentCallables->mServerProcessPointer(timeDelta);
}
__asm
{
@ -23,48 +31,92 @@ void serverProcessReplacement(unsigned int timeDelta)
}
return;
}
// Mod Loader Implementation
bool conUnloadLoadMod(Linker::SimObject *obj,S32 argc, const char* argv[])
{
const char* targetName = argv[1];
for (auto it = sModCallables.begin(); it != sModCallables.end(); it++)
{
ModLoader::ModLoaderCallables* currentMod = *it;
if (strcmp(currentMod->mGetManagementName(), targetName) == 0)
{
// Deinitialize the mod and remove it from the list.
if (currentMod->mDeinitializeModPointer != NULL)
currentMod->mDeinitializeModPointer();
sModCallables.erase(it);
return true;
}
}
// Something weird happened.
Con::errorf(0, "Failed to unload mod: '%s'.", targetName);
return false;
}
bool conLoadMod(Linker::SimObject *obj,S32 argc, const char* argv[])
{
typedef void (*LPMODINIT)(void);
HINSTANCE hDLL = NULL;
LPMODINIT lpInitMod = NULL;
HINSTANCE hDLL = NULL;
std::string raw = "mods\\";
raw += argv[1];
raw += ".dll";
std::string raw = "mods\\";
raw += argv[1];
raw += ".dll";
std::wstring modification(raw.begin(), raw.end());
std::wstring modification(raw.begin(), raw.end());
hDLL = LoadLibrary(modification.c_str());
if (hDLL == NULL)
hDLL = LoadLibrary(modification.c_str());
if (hDLL == NULL)
{
Con::errorf(0, "loadMod(): Failed to load DLL '%s'. Does it exist in GameData\\mods? (%u)", raw.c_str(), GetLastError());
return false; // The DLL doesn't exist
}
// Attempt to load supported loader information first
ModLoader::GetModLoaderVersionPointer getModLoaderVersion = (ModLoader::GetModLoaderVersionPointer)GetProcAddress(hDLL, "getModLoaderVersion");
if (getModLoaderVersion == NULL)
{
Con::errorf(0, "loadMod(): Failed to locate entry point 'getModLoaderVersion' in mod DLL '%s'. Is it a good mod DLL? (%u)", raw.c_str(), GetLastError());
return false; // Unable to load entry point
}
// Check if there's a server process responder in this DLL
ModLoader::GetModCallablesPointer getModCallables = (ModLoader::GetModCallablesPointer)GetProcAddress(hDLL, "getModCallables");
if (getModCallables == NULL)
{
Con::errorf(0, "loadMod(): Failed to locate entry point 'getModCallables' in mod DLL '%s'. Is it a good mod DLL? (%u)", raw.c_str(), GetLastError());
return false; // Unable to load entry point
}
unsigned int modLoaderVersion = getModLoaderVersion();
ModLoader::ModLoaderCallables* callables = getModCallables();
// Management name function must be provided
if (callables->mGetManagementName == NULL)
{
Con::errorf(0, "loadMod(): Loaded mod did not provide a management name. This is required.", raw.c_str(), GetLastError());
return false; // Unable to load entry point
}
const char* managementName = callables->mGetManagementName();
// Is the mod already loaded?
for (auto it = sModCallables.begin(); it != sModCallables.end(); it++)
{
ModLoader::ModLoaderCallables* currentMod = *it;
if (strcmp(currentMod->mGetManagementName(), managementName) == 0)
{
Con::errorf(0, "loadMod(): Failed to load DLL '%s'. Does it exist in GameData\\mods? (%u)", raw.c_str(), GetLastError());
return false; // The DLL doesn't exist
Con::errorf(0, "loadMod(): The mod is already loaded.", raw.c_str(), GetLastError());
return false;
}
lpInitMod = (LPMODINIT)GetProcAddress(hDLL, "ModInitialize"); // Attempt to load our entry point
}
if (lpInitMod == NULL)
{
Con::errorf(0, "loadMod(): Failed to locate entry point 'ModInitialize' in mod DLL '%s'. Is it a good mod DLL? (%u)", raw.c_str(), GetLastError());
return false; // Unable to load entry point
}
// FIXME: We should probably only run this once at init
Con::addMethodB(NULL, "unloadMod", &conUnloadLoadMod, "Unloads a C++ modification by name.", 2, 2);
lpInitMod();
Con::errorf(0, "loadMod(): Loaded and executed entry point code for mod DLL '%s'", raw.c_str());
if (callables->mInitializeModPointer != NULL)
callables->mInitializeModPointer();
// Check if there's a server process responder in this DLL
ServerProcessPointer serverProcess = (ServerProcessPointer)GetProcAddress(hDLL, "ServerProcess"); // Attempt to load our entry point
if (serverProcess != NULL)
{
sServerProcessResponders.insert(sServerProcessResponders.end(), serverProcess);
Con::errorf(0, "loadMod(): Added server process responder for mod");
}
return true;
sModCallables.push_back(callables);
return true;
}

View file

@ -7,6 +7,7 @@
#include <stdafx.h>
#include <LinkerAPI.h>
#include <DXAPI\DXAPI.h>
#include <modLoader.h>
#include <unordered_set>
@ -20,8 +21,22 @@ BOOL APIENTRY DllMain( HMODULE hModule,
{
return true;
}
const unsigned char moduroutine[] = {0x8B, 0x3D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x8B, 0x14, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0x83, 0xFA, 0x00, 0x74, 0x30, 0x8B, 0x3D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x31, 0xD2, 0x89, 0xF8, 0x8B, 0x04, 0x85, 0x00, 0xA6, 0x88, 0x00, 0xF7, 0x34, 0xBD, 0xFC, 0xA5, 0x88, 0x00, 0xFF, 0x0D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x89, 0x14, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0, 0xFF, 0x0D, 0xEC, 0x82, 0x9E, 0x00, 0xC7, 0x04, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0};
const unsigned char interpreterRoutine[] = {0x8B ,0x56 ,0x18 ,0x89 ,0x15 ,0x10 ,0xB7 ,0xA3 ,0x00 ,0x89 ,0x1D ,0x14 ,0xB7 ,0xA3 ,0x00 ,0x8B ,0x55 ,0x80 ,0x89 ,0xD0 ,0xBF ,0xD9 ,0xCE ,0x42 ,0x00 ,0x3D ,0x55 ,0x00 ,0x00 ,0x00 ,0xFF ,0xE7};
const unsigned char moduroutine[] = {
0x8B, 0x3D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x8B, 0x14, 0x85, 0xFC,
0xA5, 0x88, 0x00, 0x83, 0xFA, 0x00, 0x74, 0x30, 0x8B, 0x3D, 0xEC, 0x82,
0x9E, 0x00, 0x89, 0xF8, 0x31, 0xD2, 0x89, 0xF8, 0x8B, 0x04, 0x85, 0x00,
0xA6, 0x88, 0x00, 0xF7, 0x34, 0xBD, 0xFC, 0xA5, 0x88, 0x00, 0xFF, 0x0D,
0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x89, 0x14, 0x85, 0xFC, 0xA5, 0x88,
0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0, 0xFF, 0x0D, 0xEC, 0x82,
0x9E, 0x00, 0xC7, 0x04, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0x00, 0x00, 0x00,
0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0};
const unsigned char interpreterRoutine[] = {
0x8B, 0x56, 0x18, 0x89, 0x15, 0x10, 0xB7, 0xA3 ,0x00, 0x89, 0x1D, 0x14,
0xB7, 0xA3, 0x00, 0x8B, 0x55, 0x80, 0x89, 0xD0 ,0xBF, 0xD9, 0xCE, 0x42, 0x00,
0x3D, 0x55, 0x00, 0x00, 0x00, 0xFF, 0xE7};
const char* congetServPAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
{
char test[256] = "";
@ -30,6 +45,7 @@ const char* congetServPAddr(Linker::SimObject *obj, S32 argc, const char *argv[]
sprintf(test2,"B8%08XFFD089EC5DC3",endian(spr));
return test2;
}
const char* congetModuAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
{
char test[256] = "";
@ -38,6 +54,7 @@ const char* congetModuAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
sprintf(test2,"B8%08XFFE0",endian(spr));
return test2;
}
const char* congetInterpreterAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
{
char test[256] = "";
@ -63,6 +80,7 @@ class CImmDevice
Con::addVariable("$cpuspeed",TypeS32,reinterpret_cast<void*>(0x8477F8)); //1 - S32, this is so i can set my cpu speed to 31337 or osmething =P
Con::addVariable("$GameBase::showBoundingBox",TypeBool,reinterpret_cast<void*>(0x9ECF24));
DWORD oldprotect=0;
// Mod Loader Function
Con::addMethodB(NULL, "loadMod", &conLoadMod, "Loads a C++ modification.",2,2);
Con::addMethodS(NULL, "getServPAddr",&congetServPAddr,"Gets the memPatch data for ServerProcess",1,1);
@ -87,6 +105,9 @@ class CImmDevice
else
lpinitT2DLL(); // The function was loaded, call TribesNext and move on to postTN Startup
// Initialize all engine hooks
DX::initializeHooks();
return 0;
}