diff options
author | Emma Miler <27428383+emma-miler@users.noreply.github.com> | 2022-03-04 00:16:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-03 23:16:01 +0000 |
commit | 13dcc7d9307b160131ed80832efda99001aa6c6d (patch) | |
tree | ff7e021c2927f7d3e0ee0bb84642c6ee1c9b24ab /NorthstarDedicatedTest/dllmain.cpp | |
parent | 62e137b32ad7c601b2db37e69b9f435a7dbc730d (diff) | |
download | NorthstarLauncher-13dcc7d9307b160131ed80832efda99001aa6c6d.tar.gz NorthstarLauncher-13dcc7d9307b160131ed80832efda99001aa6c6d.zip |
Add launcher code for plugin support (#93)
* rpc
* RPC
* Undoing broken shit
* temp
* Revert "temp"
This reverts commit 4875b5aca2b0d6b03183d220120c03df28759a95.
* Include a whole bunch of new stuff
* fix id
* Added manifest and added some verification
* Fixed my oopsies
* Safety commit
* Moved over to new plugin abi
* Small docs changes and made plugin loading use ABI_VERSION
* Moving discord rpc plugin stuff to a separate repo
* Add some comments to `plugins.cpp`
* Moved internal structs from `plugin_abi.h` to `plugins.cpp`
* Add CLA `-noplugins`
* Code formatting changes so clang-format doesn't scream at me
* i hate clang-format
* why does this fail to build now wtf
* Update plugins.cpp
* Merged and updated to new convar system
* Implemented changes requested in review
* Removed a few more of those nasty comments
* Removed extra build configs
Co-authored-by: BobTheBob <32057864+BobTheBob9@users.noreply.github.com>
Diffstat (limited to 'NorthstarDedicatedTest/dllmain.cpp')
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index dcff9f4a..d6bc5091 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -39,6 +39,15 @@ #include "localchatwriter.h" #include <string.h> #include "pch.h" +#include "plugin_abi.h" +#include "plugins.h" + +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" +#include "rapidjson/error/en.h" + +typedef void (*initPluginFuncPtr)(void* getPluginObject); bool initialised = false; @@ -68,6 +77,108 @@ void WaitForDebugger(HMODULE baseAddress) } } +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"; + + // 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()); + } + // system("pause"); + initGameState(); + // spdlog::info("Loading the following DLLs in plugins folder:"); + 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, MAKEINTRESOURCE(101), MAKEINTRESOURCE(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() { if (initialised) @@ -123,6 +234,7 @@ bool InitialiseNorthstar() AddDllLoadCallback("client.dll", InitialiseScriptMainMenuPromos); AddDllLoadCallback("client.dll", InitialiseMiscClientFixes); AddDllLoadCallback("client.dll", InitialiseClientPrintHooks); + AddDllLoadCallback("client.dll", InitialisePluginCommands); AddDllLoadCallback("client.dll", InitialiseClientChatHooks); AddDllLoadCallback("client.dll", InitialiseLocalChatWriter); } |