aboutsummaryrefslogtreecommitdiff
path: root/primedev/wsockproxy/loader.cpp
diff options
context:
space:
mode:
authorJack <66967891+ASpoonPlaysGames@users.noreply.github.com>2023-12-28 14:51:45 +0000
committerGitHub <noreply@github.com>2023-12-28 14:51:45 +0000
commit3b63cf5c83b9f68952195e62e202dd557f7ca6af (patch)
treebd977e3f566a635ab4c734f2c12621614d44ce83 /primedev/wsockproxy/loader.cpp
parent0b507aa3eb55c2d06f314a46998cf9415f6a064a (diff)
parentf5ab6fb5e8be7b73e6003d4145081d5e0c0ce287 (diff)
downloadNorthstarLauncher-3b63cf5c83b9f68952195e62e202dd557f7ca6af.tar.gz
NorthstarLauncher-3b63cf5c83b9f68952195e62e202dd557f7ca6af.zip
Merge branch 'main' into cmake-format
Diffstat (limited to 'primedev/wsockproxy/loader.cpp')
-rw-r--r--primedev/wsockproxy/loader.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/primedev/wsockproxy/loader.cpp b/primedev/wsockproxy/loader.cpp
new file mode 100644
index 00000000..3e46c1a6
--- /dev/null
+++ b/primedev/wsockproxy/loader.cpp
@@ -0,0 +1,141 @@
+#include "loader.h"
+#include <string>
+#include <system_error>
+#include <sstream>
+#include <fstream>
+#include <filesystem>
+#include <iostream>
+
+namespace fs = std::filesystem;
+
+void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location)
+{
+ char text[4096];
+ std::string message = std::system_category().message(dwMessageId);
+ sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str());
+ if (dwMessageId == 126 && std::filesystem::exists(location))
+ {
+ sprintf_s(
+ text,
+ "%s\n\nThe file at the specified location DOES exist, so this error indicates that one of its *dependencies* failed to be "
+ "found.",
+ text);
+ }
+ MessageBoxA(GetForegroundWindow(), text, "Northstar Wsock32 Proxy Error", 0);
+}
+
+bool ShouldLoadNorthstar()
+{
+ bool loadNorthstar = strstr(GetCommandLineA(), "-northstar");
+
+ if (loadNorthstar)
+ return loadNorthstar;
+
+ auto runNorthstarFile = std::ifstream("run_northstar.txt");
+ if (runNorthstarFile)
+ {
+ std::stringstream runNorthstarFileBuffer;
+ runNorthstarFileBuffer << runNorthstarFile.rdbuf();
+ runNorthstarFile.close();
+ if (!runNorthstarFileBuffer.str().starts_with("0"))
+ loadNorthstar = true;
+ }
+ return loadNorthstar;
+}
+
+bool LoadNorthstar()
+{
+ FARPROC Hook_Init = nullptr;
+ {
+ std::string strProfile = "R2Northstar";
+ char* clachar = strstr(GetCommandLineA(), "-profile=");
+ if (clachar)
+ {
+ std::string cla = std::string(clachar);
+ if (strncmp(cla.substr(9, 1).c_str(), "\"", 1))
+ {
+ int space = cla.find(" ");
+ std::string dirname = cla.substr(9, space - 9);
+ std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
+ strProfile = dirname.c_str();
+ }
+ else
+ {
+ std::string quote = "\"";
+ int quote1 = cla.find(quote);
+ int quote2 = (cla.substr(quote1 + 1)).find(quote);
+ std::string dirname = cla.substr(quote1 + 1, quote2);
+ std::cout << "[*] Found profile in command line arguments: " << dirname << std::endl;
+ strProfile = dirname;
+ }
+ }
+ else
+ {
+ std::cout << "[*] Profile was not found in command line arguments. Using default: R2Northstar" << std::endl;
+ strProfile = "R2Northstar";
+ }
+
+ wchar_t buffer[8192];
+
+ // Check if "Northstar.dll" exists in profile directory, if it doesnt fall back to root
+ swprintf_s(buffer, L"%s\\%s\\Northstar.dll", exePath, std::wstring(strProfile.begin(), strProfile.end()).c_str());
+
+ if (!fs::exists(fs::path(buffer)))
+ swprintf_s(buffer, L"%s\\Northstar.dll", exePath);
+
+ std::wcout << L"[*] Using: " << buffer << std::endl;
+
+ HMODULE hHookModule = LoadLibraryExW(buffer, 0, 8u);
+ if (hHookModule)
+ Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar");
+ if (!hHookModule || Hook_Init == nullptr)
+ {
+ LibraryLoadError(GetLastError(), L"Northstar.dll", buffer);
+ return false;
+ }
+ }
+ ((bool (*)())Hook_Init)();
+
+ return true;
+}
+
+typedef int (*LauncherMainType)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
+LauncherMainType LauncherMainOriginal;
+
+int LauncherMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+ if (ShouldLoadNorthstar())
+ LoadNorthstar();
+ return LauncherMainOriginal(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
+}
+
+bool ProvisionNorthstar()
+{
+ if (!ShouldLoadNorthstar())
+ return true;
+
+ if (MH_Initialize() != MH_OK)
+ {
+ MessageBoxA(
+ GetForegroundWindow(), "MH_Initialize failed\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0);
+ return false;
+ }
+
+ auto launcherHandle = GetModuleHandleA("launcher.dll");
+ if (!launcherHandle)
+ {
+ MessageBoxA(
+ GetForegroundWindow(),
+ "Launcher isn't loaded yet.\nThe game cannot continue and has to exit.",
+ "Northstar Wsock32 Proxy Error",
+ 0);
+ return false;
+ }
+
+ LPVOID pTarget = (LPVOID)GetProcAddress(launcherHandle, "LauncherMain");
+ if (MH_CreateHook(pTarget, (LPVOID)&LauncherMainHook, reinterpret_cast<LPVOID*>(&LauncherMainOriginal)) != MH_OK ||
+ MH_EnableHook(pTarget) != MH_OK)
+ MessageBoxA(GetForegroundWindow(), "Hook creation failed for function LauncherMain.", "Northstar Wsock32 Proxy Error", 0);
+
+ return true;
+}