aboutsummaryrefslogtreecommitdiff
path: root/LauncherInjector/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'LauncherInjector/main.cpp')
-rw-r--r--LauncherInjector/main.cpp453
1 files changed, 0 insertions, 453 deletions
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp
deleted file mode 100644
index 99e5ba15..00000000
--- a/LauncherInjector/main.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <TlHelp32.h>
-#include <filesystem>
-#include <sstream>
-#include <fstream>
-#include <Shlwapi.h>
-#include <iostream>
-
-#pragma comment(lib, "Ws2_32.lib")
-
-#include <winsock2.h>
-#include <WS2tcpip.h>
-
-namespace fs = std::filesystem;
-
-extern "C"
-{
- __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
- __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
-}
-
-HMODULE hLauncherModule;
-HMODULE hHookModule;
-HMODULE hTier0Module;
-
-wchar_t exePath[4096];
-wchar_t buffer[8192];
-
-bool noLoadPlugins = false;
-
-DWORD GetProcessByName(std::wstring processName)
-{
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-
- PROCESSENTRY32 processSnapshotEntry = {0};
- processSnapshotEntry.dwSize = sizeof(PROCESSENTRY32);
-
- if (snapshot == INVALID_HANDLE_VALUE)
- return 0;
-
- if (!Process32First(snapshot, &processSnapshotEntry))
- return 0;
-
- while (Process32Next(snapshot, &processSnapshotEntry))
- {
- if (!wcscmp(processSnapshotEntry.szExeFile, processName.c_str()))
- {
- CloseHandle(snapshot);
- return processSnapshotEntry.th32ProcessID;
- }
- }
-
- CloseHandle(snapshot);
- return 0;
-}
-
-bool GetExePathWide(wchar_t* dest, DWORD destSize)
-{
- if (!dest)
- return NULL;
- if (destSize < MAX_PATH)
- return NULL;
-
- DWORD length = GetModuleFileNameW(NULL, dest, destSize);
- return length && PathRemoveFileSpecW(dest);
-}
-
-FARPROC GetLauncherMain()
-{
- static FARPROC Launcher_LauncherMain;
- if (!Launcher_LauncherMain)
- Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain");
- return Launcher_LauncherMain;
-}
-
-void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location)
-{
- char text[8192];
- std::string message = std::system_category().message(dwMessageId);
-
- sprintf_s(
- text,
- "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs\n\nMake sure you followed the Northstar installation instructions carefully "
- "before reaching out for help.",
- 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.\n\nTry the following steps:\n1. Install Visual C++ 2022 Redistributable: "
- "https://aka.ms/vs/17/release/vc_redist.x64.exe\n2. Repair game files",
- text);
- }
- else if (!fs::exists("Titanfall2.exe") && (fs::exists("..\\Titanfall2.exe") || fs::exists("..\\..\\Titanfall2.exe")))
- {
- auto curDir = std::filesystem::current_path().filename().string();
- auto aboveDir = std::filesystem::current_path().parent_path().filename().string();
- sprintf_s(
- text,
- "%s\n\nWe detected that in your case you have extracted the files into a *subdirectory* of your Titanfall 2 "
- "installation.\nPlease move all the files and folders from current folder (\"%s\") into the Titanfall 2 installation directory "
- "just above (\"%s\").\n\nPlease try out the above steps by yourself before reaching out to the community for support.",
- text,
- curDir.c_str(),
- aboveDir.c_str());
- }
- else if (!fs::exists("Titanfall2.exe"))
- {
- sprintf_s(
- text,
- "%s\n\nRemember: you need to unpack the contents of this archive into your Titanfall 2 game installation directory, not just "
- "to any random folder.",
- text);
- }
- else if (fs::exists("Titanfall2.exe"))
- {
- sprintf_s(
- text,
- "%s\n\nTitanfall2.exe has been found in the current directory: is the game installation corrupted or did you not unpack all "
- "Northstar files here?",
- text);
- }
-
- MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Error", 0);
-}
-
-void AwaitOriginStartup()
-{
- WSADATA wsaData;
- WSAStartup(MAKEWORD(2, 2), &wsaData);
- SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- if (sock != INVALID_SOCKET)
- {
- const int LSX_PORT = 3216;
-
- sockaddr_in lsxAddr;
- lsxAddr.sin_family = AF_INET;
- inet_pton(AF_INET, "127.0.0.1", &(lsxAddr.sin_addr));
- lsxAddr.sin_port = htons(LSX_PORT);
-
- std::cout << "LSX: connect()" << std::endl;
- connect(sock, (struct sockaddr*)&lsxAddr, sizeof(lsxAddr));
-
- char buf[4096];
- memset(buf, 0, sizeof(buf));
-
- do
- {
- recv(sock, buf, 4096, 0);
- std::cout << buf << std::endl;
-
- // honestly really shit, this isn't needed for origin due to being able to check OriginClientService
- // but for ea desktop we don't have anything like this, so atm we just have to wait to ensure that we start after logging in
- Sleep(8000);
- } while (!strstr(buf, "<LSX>")); // ensure we're actually getting data from lsx
- }
-
- WSACleanup(); // cleanup sockets and such so game can contact lsx itself
-}
-
-void EnsureOriginStarted()
-{
- if (GetProcessByName(L"Origin.exe") || GetProcessByName(L"EADesktop.exe"))
- return; // already started
-
- // unpacked exe will crash if origin isn't open on launch, so launch it
- // get origin path from registry, code here is reversed from OriginSDK.dll
- HKEY key;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Origin", 0, KEY_READ, &key) != ERROR_SUCCESS)
- {
- MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
- return;
- }
-
- char originPath[520];
- DWORD originPathLength = 520;
- if (RegQueryValueExA(key, "ClientPath", 0, 0, (LPBYTE)&originPath, &originPathLength) != ERROR_SUCCESS)
- {
- MessageBoxA(0, "Error: failed reading Origin path!", "Northstar Launcher Error", MB_OK);
- return;
- }
-
- std::cout << "[*] Starting Origin..." << std::endl;
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_MINIMIZE;
- CreateProcessA(
- originPath,
- (char*)"",
- NULL,
- NULL,
- false,
- CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP,
- NULL,
- NULL,
- (LPSTARTUPINFOA)&si,
- &pi);
-
- std::cout << "[*] Waiting for Origin..." << std::endl;
-
- // wait for origin process to boot
- do
- {
- Sleep(500);
- } while (!GetProcessByName(L"OriginClientService.exe") && !GetProcessByName(L"EADesktop.exe"));
-
- // wait for origin to be ready to start
- AwaitOriginStartup();
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
-}
-
-void PrependPath()
-{
- wchar_t* pPath;
- size_t len;
- errno_t err = _wdupenv_s(&pPath, &len, L"PATH");
- if (!err)
- {
- swprintf_s(buffer, L"PATH=%s\\bin\\x64_retail\\;%s", exePath, pPath);
- auto result = _wputenv(buffer);
- if (result == -1)
- {
- MessageBoxW(
- GetForegroundWindow(),
- L"Warning: could not prepend the current directory to app's PATH environment variable. Something may break because of "
- L"that.",
- L"Northstar Launcher Warning",
- 0);
- }
- free(pPath);
- }
- else
- {
- MessageBoxW(
- GetForegroundWindow(),
- L"Warning: could not get current PATH environment variable in order to prepend the current directory to it. Something may "
- L"break because of that.",
- L"Northstar Launcher Warning",
- 0);
- }
-}
-
-bool ShouldLoadNorthstar(int argc, char* argv[])
-{
- bool loadNorthstar = true;
- for (int i = 0; i < argc; i++)
- if (!strcmp(argv[i], "-vanilla"))
- loadNorthstar = false;
-
- 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 = false;
- }
- return loadNorthstar;
-}
-
-bool LoadNorthstar()
-{
- FARPROC Hook_Init = nullptr;
- {
- swprintf_s(buffer, L"%s\\Northstar.dll", exePath);
- hHookModule = LoadLibraryExW(buffer, 0i64, 8u);
- if (hHookModule)
- Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar");
- if (!hHookModule || Hook_Init == nullptr)
- {
- LibraryLoadError(GetLastError(), L"Northstar.dll", buffer);
- return false;
- }
- }
- ((bool (*)())Hook_Init)();
-
- FARPROC LoadPlugins = nullptr;
- if (!noLoadPlugins)
- {
- LoadPlugins = GetProcAddress(hHookModule, "LoadPlugins");
- if (!hHookModule || LoadPlugins == nullptr)
- {
- std::cout << "Failed to get function pointer to LoadPlugins of Northstar.dll" << std::endl;
- LibraryLoadError(GetLastError(), L"Northstar.dll", buffer);
- return false;
- }
- ((bool (*)())LoadPlugins)();
- }
-
- return true;
-}
-
-HMODULE LoadDediStub(const char* name)
-{
- // this works because materialsystem_dx11.dll uses relative imports, and even a DLL loaded with an absolute path will take precedence
- std::cout << "[*] Loading " << name << std::endl;
- swprintf_s(buffer, L"%s\\bin\\x64_dedi\\%hs", exePath, name);
- HMODULE h = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!h)
- {
- wprintf(L"[*] Failed to load stub %hs from \"%ls\": %hs\n", name, buffer, std::system_category().message(GetLastError()).c_str());
- }
- return h;
-}
-
-int main(int argc, char* argv[])
-{
-
- if (!GetExePathWide(exePath, sizeof(exePath)))
- {
- MessageBoxA(
- GetForegroundWindow(),
- "Failed getting game directory.\nThe game cannot continue and has to exit.",
- "Northstar Launcher Error",
- 0);
- return 1;
- }
-
- bool noOriginStartup = false;
- bool dedicated = false;
- bool nostubs = false;
-
- for (int i = 0; i < argc; i++)
- if (!strcmp(argv[i], "-noOriginStartup"))
- noOriginStartup = true;
- else if (!strcmp(argv[i], "-dedicated")) // also checked by Northstar.dll
- dedicated = true;
- else if (!strcmp(argv[i], "-nostubs"))
- nostubs = true;
- else if (!strcmp(argv[i], "-noplugins"))
- noLoadPlugins = true;
-
- if (!noOriginStartup && !dedicated)
- {
- EnsureOriginStarted();
- }
-
- if (dedicated && !nostubs)
- {
- std::cout << "[*] Loading stubs" << std::endl;
- HMODULE gssao, gtxaa, d3d11;
- if (!(gssao = GetModuleHandleA("GFSDK_SSAO.win64.dll")) && !(gtxaa = GetModuleHandleA("GFSDK_TXAA.win64.dll")) &&
- !(d3d11 = GetModuleHandleA("d3d11.dll")))
- {
- if (!(gssao = LoadDediStub("GFSDK_SSAO.win64.dll")) || !(gtxaa = LoadDediStub("GFSDK_TXAA.win64.dll")) ||
- !(d3d11 = LoadDediStub("d3d11.dll")))
- {
- if ((!gssao || FreeLibrary(gssao)) && (!gtxaa || FreeLibrary(gtxaa)) && (!d3d11 || FreeLibrary(d3d11)))
- {
- std::cout <<"[*] WARNING: Failed to load d3d11/gfsdk stubs from bin/x64_dedi. "
- "The stubs have been unloaded and the original libraries will be used instead" << std::endl;
- }
- else
- {
- // this is highly unlikely
- MessageBoxA(
- GetForegroundWindow(),
- "Failed to load one or more stubs, but could not unload them either.\n"
- "The game cannot continue and has to exit.",
- "Northstar Launcher Error",
- 0);
- return 1;
- }
- }
- }
- else
- {
- // this should never happen
- std::cout << "[*] WARNING: Failed to load stubs because conflicting modules are already loaded, so those will be used instead "
- "(did Northstar initialize too late?)." << std::endl;
- }
- }
-
- {
- PrependPath();
-
- if (!fs::exists("ns_startup_args.txt"))
- {
- std::ofstream file("ns_startup_args.txt");
- std::string defaultArgs = "-multiple";
- file.write(defaultArgs.c_str(), defaultArgs.length());
- file.close();
- }
- if (!fs::exists("ns_startup_args_dedi.txt"))
- {
- std::ofstream file("ns_startup_args_dedi.txt");
- std::string defaultArgs = "+setplaylist private_match";
- file.write(defaultArgs.c_str(), defaultArgs.length());
- file.close();
- }
-
- std::cout << "[*] Loading tier0.dll" << std::endl;
- swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath);
- hTier0Module = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!hTier0Module)
- {
- LibraryLoadError(GetLastError(), L"tier0.dll", buffer);
- return 1;
- }
-
- bool loadNorthstar = ShouldLoadNorthstar(argc, argv);
- if (loadNorthstar)
- {
- std::cout << "[*] Loading Northstar" << std::endl;
- if (!LoadNorthstar())
- return 1;
- }
- else
- std::cout << "[*] Going to load the vanilla game" << std::endl;
-
- std::cout << "[*] Loading launcher.dll" << std::endl;
- swprintf_s(buffer, L"%s\\bin\\x64_retail\\launcher.dll", exePath);
- hLauncherModule = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!hLauncherModule)
- {
- LibraryLoadError(GetLastError(), L"launcher.dll", buffer);
- return 1;
- }
- }
-
- std::cout << "[*] Launching the game..." << std::endl;
- auto LauncherMain = GetLauncherMain();
- if (!LauncherMain)
- MessageBoxA(
- GetForegroundWindow(),
- "Failed loading launcher.dll.\nThe game cannot continue and has to exit.",
- "Northstar Launcher Error",
- 0);
- // auto result = ((__int64(__fastcall*)())LauncherMain)();
- // auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64);
-
- std::cout.flush();
- return ((int(/*__fastcall*/*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(
- NULL, NULL, NULL, 0); // the parameters aren't really used anyways
-}