diff options
Diffstat (limited to 'NorthstarDLL/dllmain.cpp')
-rw-r--r-- | NorthstarDLL/dllmain.cpp | 135 |
1 files changed, 115 insertions, 20 deletions
diff --git a/NorthstarDLL/dllmain.cpp b/NorthstarDLL/dllmain.cpp index 6fc49be8..a697da5b 100644 --- a/NorthstarDLL/dllmain.cpp +++ b/NorthstarDLL/dllmain.cpp @@ -7,8 +7,6 @@ #include "plugins/plugins.h" #include "util/version.h" #include "squirrel/squirrel.h" -#include "shared/gamepresence.h" -#include "server/serverpresence.h" #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" @@ -18,6 +16,8 @@ #include <string.h> #include <filesystem> +typedef void (*initPluginFuncPtr)(void* (*getPluginObject)(PluginObject)); + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) @@ -32,6 +32,110 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv return TRUE; } +void freeLibrary(HMODULE hLib) +{ + if (!FreeLibrary(hLib)) + { + spdlog::error("There was an error while trying to free library"); + } +} + +bool LoadPlugins() +{ + + std::vector<fs::path> paths; + + std::string pluginPath = GetNorthstarPrefix() + "/plugins"; + if (!fs::exists(pluginPath)) + { + spdlog::warn("Could not find a plugins directory. Skipped loading plugins"); + return false; + } + // ensure dirs exist + fs::recursive_directory_iterator iterator(pluginPath); + if (std::filesystem::begin(iterator) == std::filesystem::end(iterator)) + { + spdlog::warn("Could not find any plugins. Skipped loading plugins"); + return false; + } + for (auto const& entry : iterator) + { + if (fs::is_regular_file(entry) && entry.path().extension() == ".dll") + paths.emplace_back(entry.path().filename()); + } + initGameState(); + for (fs::path path : paths) + { + std::string pathstring = (pluginPath / path).string(); + std::wstring wpath = (pluginPath / path).wstring(); + + LPCWSTR wpptr = wpath.c_str(); + HMODULE datafile = + LoadLibraryExW(wpptr, 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); // Load the DLL as a data file + if (datafile == NULL) + { + spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); + continue; + } + HRSRC manifestResource = FindResourceW(datafile, MAKEINTRESOURCEW(101), MAKEINTRESOURCEW(RT_RCDATA)); + + if (manifestResource == NULL) + { + spdlog::info("Could not find manifest for library {}", pathstring); + freeLibrary(datafile); + continue; + } + spdlog::info("Loading resource from library"); + HGLOBAL myResourceData = LoadResource(datafile, manifestResource); + if (myResourceData == NULL) + { + spdlog::error("Failed to load resource from library"); + freeLibrary(datafile); + continue; + } + int manifestSize = SizeofResource(datafile, manifestResource); + std::string manifest = std::string((const char*)LockResource(myResourceData), 0, manifestSize); + freeLibrary(datafile); + + rapidjson_document manifestJSON; + manifestJSON.Parse(manifest.c_str()); + + if (manifestJSON.HasParseError()) + { + spdlog::error("Manifest for {} was invalid", pathstring); + continue; + } + if (!manifestJSON.HasMember("api_version")) + { + spdlog::error("{} does not have a version number in its manifest", pathstring); + continue; + // spdlog::info(manifestJSON["version"].GetString()); + } + if (strcmp(manifestJSON["api_version"].GetString(), std::to_string(ABI_VERSION).c_str())) + { + spdlog::error("{} has an incompatible API version number in its manifest", pathstring); + continue; + } + // Passed all checks, going to actually load it now + + HMODULE pluginLib = LoadLibraryW(wpptr); // Load the DLL as a data file + if (pluginLib == NULL) + { + spdlog::info("Failed to load library {}: ", std::system_category().message(GetLastError())); + continue; + } + initPluginFuncPtr initPlugin = (initPluginFuncPtr)GetProcAddress(pluginLib, "initializePlugin"); + if (initPlugin == NULL) + { + spdlog::info("Library {} has no function initializePlugin", pathstring); + continue; + } + spdlog::info("Succesfully loaded {}", pathstring); + initPlugin(&getPluginObject); + } + return true; +} + bool InitialiseNorthstar() { static bool bInitialised = false; @@ -40,29 +144,13 @@ bool InitialiseNorthstar() bInitialised = true; - InitialiseNorthstarPrefix(); - // initialise the console if needed (-northstar needs this) InitialiseConsole(); // initialise logging before most other things so that they can use spdlog and it have the proper formatting InitialiseLogging(); - InitialiseVersion(); - CreateLogFiles(); - - InitialiseCrashHandler(); - - // Write launcher version to log - spdlog::info("NorthstarLauncher version: {}", version); - spdlog::info("Command line: {}", GetCommandLineA()); - spdlog::info("Using profile: {}", GetNorthstarPrefix()); - - InstallInitialHooks(); - g_pServerPresence = new ServerPresenceManager(); - - g_pGameStatePresence = new GameStatePresence(); - g_pPluginManager = new PluginManager(); - g_pPluginManager->LoadPlugins(); + InitialiseNorthstarPrefix(); + InitialiseVersion(); InitialiseSquirrelManagers(); @@ -71,6 +159,13 @@ bool InitialiseNorthstar() curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base); + InitialiseCrashHandler(); + InstallInitialHooks(); + CreateLogFiles(); + + // Write launcher version to log + spdlog::info("NorthstarLauncher version: {}", version); + // run callbacks for any libraries that are already loaded by now CallAllPendingDLLLoadCallbacks(); |