mirror of
https://github.com/Ragora/T2-CPP.git
synced 2026-03-05 05:20:21 +00:00
Begin transition to the new ModLoader paradigm. Begin cleaning up code.
This commit is contained in:
parent
015a9f4dc8
commit
cb9895a38e
39 changed files with 1429 additions and 967 deletions
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue