aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest/dllmain.cpp
diff options
context:
space:
mode:
authorEmma Miler <27428383+emma-miler@users.noreply.github.com>2022-03-04 00:16:01 +0100
committerGitHub <noreply@github.com>2022-03-03 23:16:01 +0000
commit13dcc7d9307b160131ed80832efda99001aa6c6d (patch)
treeff7e021c2927f7d3e0ee0bb84642c6ee1c9b24ab /NorthstarDedicatedTest/dllmain.cpp
parent62e137b32ad7c601b2db37e69b9f435a7dbc730d (diff)
downloadNorthstarLauncher-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.cpp112
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);
}