aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/dllmain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDLL/dllmain.cpp')
-rw-r--r--NorthstarDLL/dllmain.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/NorthstarDLL/dllmain.cpp b/NorthstarDLL/dllmain.cpp
new file mode 100644
index 00000000..02b3fefc
--- /dev/null
+++ b/NorthstarDLL/dllmain.cpp
@@ -0,0 +1,305 @@
+#include "pch.h"
+#include "hooks.h"
+#include "main.h"
+#include "squirrel.h"
+#include "dedicated.h"
+#include "dedicatedmaterialsystem.h"
+#include "sourceconsole.h"
+#include "logging.h"
+#include "concommand.h"
+#include "modmanager.h"
+#include "filesystem.h"
+#include "serverauthentication.h"
+#include "scriptmodmenu.h"
+#include "scriptserverbrowser.h"
+#include "keyvalues.h"
+#include "masterserver.h"
+#include "gameutils.h"
+#include "chatcommand.h"
+#include "modlocalisation.h"
+#include "playlist.h"
+#include "miscserverscript.h"
+#include "clientauthhooks.h"
+#include "latencyflex.h"
+#include "scriptbrowserhooks.h"
+#include "scriptmainmenupromos.h"
+#include "miscclientfixes.h"
+#include "miscserverfixes.h"
+#include "rpakfilesystem.h"
+#include "bansystem.h"
+#include "memalloc.h"
+#include "maxplayers.h"
+#include "languagehooks.h"
+#include "audio.h"
+#include "buildainfile.h"
+#include "configurables.h"
+#include "serverchathooks.h"
+#include "clientchathooks.h"
+#include "localchatwriter.h"
+#include "scriptservertoclientstringcommand.h"
+#include "plugin_abi.h"
+#include "plugins.h"
+#include "debugoverlay.h"
+#include "clientvideooverrides.h"
+#include "clientruihooks.h"
+#include <string.h>
+#include "version.h"
+#include "pch.h"
+#include "scriptutility.h"
+
+#include "rapidjson/document.h"
+#include "rapidjson/stringbuffer.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/error/en.h"
+#include "ExploitFixes.h"
+
+typedef void (*initPluginFuncPtr)(void* (*getPluginObject)(PluginObject));
+
+bool initialised = false;
+
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
+
+void WaitForDebugger(HMODULE baseAddress)
+{
+ // earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier
+ if (CommandLine()->CheckParm("-waitfordebugger"))
+ {
+ spdlog::info("waiting for debugger...");
+
+ while (!IsDebuggerPresent())
+ Sleep(100);
+ }
+}
+
+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()
+{
+ if (initialised)
+ {
+ // spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen
+ return false;
+ }
+
+ initialised = true;
+
+ parseConfigurables();
+ InitialiseVersion();
+
+ // Fix some users' failure to connect to respawn datacenters
+ SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000");
+
+ curl_global_init_mem(CURL_GLOBAL_DEFAULT, _malloc_base, _free_base, _realloc_base, _strdup_base, _calloc_base);
+
+ InitialiseLogging();
+ InstallInitialHooks();
+ CreateLogFiles();
+
+ // Write launcher version to log
+ spdlog::info("NorthstarLauncher version: {}", version);
+
+ InitialiseInterfaceCreationHooks();
+
+ AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions);
+ AddDllLoadCallback("engine.dll", WaitForDebugger);
+ AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
+ AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions);
+
+ // dedi patches
+ {
+ AddDllLoadCallbackForDedicatedServer("tier0.dll", InitialiseDedicatedOrigin);
+ AddDllLoadCallbackForDedicatedServer("engine.dll", InitialiseDedicated);
+ AddDllLoadCallbackForDedicatedServer("server.dll", InitialiseDedicatedServerGameDLL);
+ AddDllLoadCallbackForDedicatedServer("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem);
+ // this fucking sucks, but seemingly we somehow load after rtech_game???? unsure how, but because of this we have to apply patches
+ // here, not on rtech_game load
+ AddDllLoadCallbackForDedicatedServer("engine.dll", InitialiseDedicatedRtechGame);
+ }
+
+ AddDllLoadCallback("engine.dll", InitialiseConVars);
+ AddDllLoadCallback("engine.dll", InitialiseConCommands);
+
+ // client-exclusive patches
+ {
+
+ AddDllLoadCallbackForClient("tier0.dll", InitialiseTier0LanguageHooks);
+ AddDllLoadCallbackForClient("client.dll", InitialiseClientSquirrel);
+ AddDllLoadCallbackForClient("client.dll", InitialiseSourceConsole);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseChatCommands);
+ AddDllLoadCallbackForClient("client.dll", InitialiseScriptModMenu);
+ AddDllLoadCallbackForClient("client.dll", InitialiseScriptServerBrowser);
+ AddDllLoadCallbackForClient("localize.dll", InitialiseModLocalisation);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseClientAuthHooks);
+ AddDllLoadCallbackForClient("client.dll", InitialiseLatencyFleX);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseScriptExternalBrowserHooks);
+ AddDllLoadCallbackForClient("client.dll", InitialiseScriptMainMenuPromos);
+ AddDllLoadCallbackForClient("client.dll", InitialiseMiscClientFixes);
+ AddDllLoadCallbackForClient("client.dll", InitialiseClientPrintHooks);
+ AddDllLoadCallbackForClient("client.dll", InitialisePluginCommands);
+ AddDllLoadCallbackForClient("client.dll", InitialiseClientChatHooks);
+ AddDllLoadCallbackForClient("client.dll", InitialiseLocalChatWriter);
+ AddDllLoadCallbackForClient("client.dll", InitialiseScriptServerToClientStringCommands);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseEngineClientVideoOverrides);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseEngineClientRUIHooks);
+ AddDllLoadCallbackForClient("engine.dll", InitialiseDebugOverlay);
+ AddDllLoadCallbackForClient("client.dll", InitialiseClientSquirrelUtilityFunctions);
+ // audio hooks
+ AddDllLoadCallbackForClient("client.dll", InitialiseMilesAudioHooks);
+ }
+
+ AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks);
+ AddDllLoadCallback("server.dll", InitialiseServerSquirrel);
+ AddDllLoadCallback("engine.dll", InitialiseBanSystem);
+ AddDllLoadCallback("engine.dll", InitialiseServerAuthentication);
+ AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer);
+ AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand);
+ AddDllLoadCallback("server.dll", InitialiseMiscServerFixes);
+ AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks);
+ AddDllLoadCallback("server.dll", InitialiseServerSquirrelUtilityFunctions);
+
+ AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);
+
+ AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem);
+ AddDllLoadCallback("engine.dll", InitialiseEngineRpakFilesystem);
+ AddDllLoadCallback("engine.dll", InitialiseKeyValues);
+
+ AddDllLoadCallback("engine.dll", InitialiseServerChatHooks_Engine);
+ AddDllLoadCallback("server.dll", InitialiseServerChatHooks_Server);
+
+ // maxplayers increase
+ AddDllLoadCallback("engine.dll", InitialiseMaxPlayersOverride_Engine);
+ AddDllLoadCallback("client.dll", InitialiseMaxPlayersOverride_Client);
+ AddDllLoadCallback("server.dll", InitialiseMaxPlayersOverride_Server);
+
+ // mod manager after everything else
+ AddDllLoadCallback("engine.dll", InitialiseModManager);
+
+ {
+ // activate multi-module exploitfixes callbacks
+ constexpr const char* EXPLOITFIXES_MULTICALLBACK_MODS[] = {"client.dll", "engine.dll", "server.dll"};
+ for (const char* mod : EXPLOITFIXES_MULTICALLBACK_MODS)
+ AddDllLoadCallback(mod, ExploitFixes::LoadCallback_MultiModule);
+
+ // activate exploit fixes later
+ AddDllLoadCallback("server.dll", ExploitFixes::LoadCallback_Full);
+ }
+
+ // run callbacks for any libraries that are already loaded by now
+ CallAllPendingDLLLoadCallbacks();
+
+ return true;
+}