diff options
-rw-r--r-- | LauncherInjector/main.cpp | 18 | ||||
-rw-r--r-- | NorthstarDedicatedTest/hooks.cpp | 4 | ||||
-rw-r--r-- | NorthstarDedicatedTest/languagehooks.cpp | 8 | ||||
-rw-r--r-- | loader_launcher_proxy/dllmain.cpp | 9 | ||||
-rw-r--r-- | loader_wsock32_proxy/dllmain.cpp | 50 | ||||
-rw-r--r-- | loader_wsock32_proxy/loader.cpp | 13 | ||||
-rw-r--r-- | loader_wsock32_proxy/loader.h | 5 |
7 files changed, 78 insertions, 29 deletions
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp index 7697e80d..a5d70f76 100644 --- a/LauncherInjector/main.cpp +++ b/LauncherInjector/main.cpp @@ -65,17 +65,29 @@ FARPROC GetLauncherMain() void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location) { - char text[4096]; + 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.", libName, location, dwMessageId, message.c_str()); + 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 (!fs::exists("Titanfall2.exe") && fs::exists("..\\Titanfall2.exe")) + 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); } diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp index ce4d75ad..cdb5fef9 100644 --- a/NorthstarDedicatedTest/hooks.cpp +++ b/NorthstarDedicatedTest/hooks.cpp @@ -73,6 +73,10 @@ LPSTR GetCommandLineAHook() argBuffer << cmdlineArgFile.rdbuf(); cmdlineArgFile.close(); + // if some other command line option includes "-northstar" in the future then you have to refactor this check to check with both either space after or ending with + if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos) + MessageBoxA(NULL, "The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original Titanfall2.exe rather than NorthstarLauncher.exe to make use of it.", "Northstar Warning", MB_ICONWARNING); + args.append(argBuffer.str()); } diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDedicatedTest/languagehooks.cpp index 0929b73d..3a69df9d 100644 --- a/NorthstarDedicatedTest/languagehooks.cpp +++ b/NorthstarDedicatedTest/languagehooks.cpp @@ -26,6 +26,9 @@ std::vector<std::string> file_list(fs::path dir, std::regex ext_pattern) { std::vector<std::string> result; + if (!fs::exists(dir) || !fs::is_directory(dir)) + return result; + using iterator = fs::directory_iterator; const iterator end; @@ -77,7 +80,8 @@ char* GetGameLanguageHook() auto lang = GetGameLanguageOriginal(); if (!CheckLangAudioExists(lang)) { - spdlog::info("Origin detected language \"{}\", but we do not have audio for it installed, falling back to the next option", lang); + if (strcmp(lang, "russian") != 0) // don't log for "russian" since it's the default and that means Origin detection just didn't change it most likely + spdlog::info("Origin detected language \"{}\", but we do not have audio for it installed, falling back to the next option", lang); } else @@ -95,7 +99,7 @@ char* GetGameLanguageHook() { spdlog::warn("Caution, audio for this language does NOT exist. You might want to override your game language with -language command line option."); auto lang = GetAnyInstalledAudioLanguage(); - spdlog::warn("Falling back to first installed audio language: {}", lang.c_str()); + spdlog::warn("Falling back to the first installed audio language: {}", lang.c_str()); strncpy(ingameLang1, lang.c_str(), 256); return ingameLang1; } diff --git a/loader_launcher_proxy/dllmain.cpp b/loader_launcher_proxy/dllmain.cpp index cf69d63e..1215ca1f 100644 --- a/loader_launcher_proxy/dllmain.cpp +++ b/loader_launcher_proxy/dllmain.cpp @@ -5,6 +5,7 @@ #include <Shlwapi.h> #include <sstream> #include <fstream> +#include <filesystem> HMODULE hLauncherModule; HMODULE hHookModule; @@ -44,9 +45,13 @@ FARPROC GetLauncherMain() void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location) { - char text[2048]; - std::string message = std::system_category().message(dwMessageId); + 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 Launcher Proxy Error", 0); } diff --git a/loader_wsock32_proxy/dllmain.cpp b/loader_wsock32_proxy/dllmain.cpp index 0b518dbe..f4c0d604 100644 --- a/loader_wsock32_proxy/dllmain.cpp +++ b/loader_wsock32_proxy/dllmain.cpp @@ -18,8 +18,8 @@ bool GetExePathWide(wchar_t* dest, DWORD destSize) } wchar_t exePath[4096]; -wchar_t dllPath[8192]; -wchar_t dllPath2[4096]; +wchar_t buffer1[8192]; +wchar_t buffer2[12288]; BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) { @@ -30,30 +30,48 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) if (!GetExePathWide(exePath, 4096)) { MessageBoxA(GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.", "Northstar Wsock32 Proxy Error", 0); - return 1; + return true; } if (!ProvisionNorthstar()) // does not call InitialiseNorthstar yet, will do it on LauncherMain hook - return 1; + return true; // copy the original library for system to our local directory, with changed name so that we can load it - swprintf_s(dllPath, L"%s\\bin\\x64_retail\\wsock32.org.dll", exePath); - GetSystemDirectoryW(dllPath2, 4096); - swprintf_s(dllPath2, L"%s\\wsock32.dll", dllPath2); + swprintf_s(buffer1, L"%s\\bin\\x64_retail\\wsock32.org.dll", exePath); + GetSystemDirectoryW(buffer2, 4096); + swprintf_s(buffer2, L"%s\\wsock32.dll", buffer2); try { - std::filesystem::copy_file(dllPath2, dllPath); + std::filesystem::copy_file(buffer2, buffer1); } - catch (const std::exception& e) + catch (const std::exception& e1) { - if (!std::filesystem::exists(dllPath)) + if (!std::filesystem::exists(buffer1)) { - swprintf_s(dllPath, L"Failed copying wsock32.dll from system32 to \"%s\"\n\n%S", dllPath, e.what()); - MessageBoxW(GetForegroundWindow(), dllPath, L"Northstar Wsock32 Proxy Error", 0); + // fallback by copying to temp dir... + // because apparently games installed by EA Desktop app don't have write permissions in their directories + auto temp_dir = std::filesystem::temp_directory_path() / L"wsock32.org.dll"; + try + { + std::filesystem::copy_file(buffer2, temp_dir); + } + catch (const std::exception& e2) + { + if (!std::filesystem::exists(temp_dir)) + { + swprintf_s(buffer2, L"Failed copying wsock32.dll from system32 to \"%s\"\n\n%S\n\nFurthermore, we failed copying wsock32.dll into temporary directory at \"%s\"\n\n%S", buffer1, e1.what(), temp_dir.c_str(), e2.what()); + MessageBoxW(GetForegroundWindow(), buffer2, L"Northstar Wsock32 Proxy Error", 0); + return false; + } + } + swprintf_s(buffer1, L"%s", temp_dir.c_str()); } } - hL = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!hL) return false; + hL = LoadLibraryExW(buffer1, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hL) { + LibraryLoadError(GetLastError(), L"wsock32.org.dll", buffer1); + return false; + } // load the functions to proxy // it's only some of them, because in case of wsock32 most of the functions can actually be natively redirected @@ -75,10 +93,10 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) if (reason == DLL_PROCESS_DETACH) { FreeLibrary(hL); - return 1; + return true; } - return 1; + return true; } extern "C" diff --git a/loader_wsock32_proxy/loader.cpp b/loader_wsock32_proxy/loader.cpp index 907caa9d..61b4daf3 100644 --- a/loader_wsock32_proxy/loader.cpp +++ b/loader_wsock32_proxy/loader.cpp @@ -5,12 +5,17 @@ #include <system_error> #include <sstream> #include <fstream> +#include <filesystem> void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location) { - char text[2048]; + 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); } @@ -37,12 +42,12 @@ bool LoadNorthstar() { FARPROC Hook_Init = nullptr; { - swprintf_s(dllPath, L"%s\\Northstar.dll", exePath); - auto hHookModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + swprintf_s(buffer1, L"%s\\Northstar.dll", exePath); + auto hHookModule = LoadLibraryExW(buffer1, 0, LOAD_WITH_ALTERED_SEARCH_PATH); if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); if (!hHookModule || Hook_Init == nullptr) { - LibraryLoadError(GetLastError(), L"Northstar.dll", dllPath); + LibraryLoadError(GetLastError(), L"Northstar.dll", buffer1); return false; } } diff --git a/loader_wsock32_proxy/loader.h b/loader_wsock32_proxy/loader.h index 9a14b2e7..0c6fb053 100644 --- a/loader_wsock32_proxy/loader.h +++ b/loader_wsock32_proxy/loader.h @@ -1,8 +1,9 @@ #pragma once extern wchar_t exePath[4096]; -extern wchar_t dllPath[8192]; -extern wchar_t dllPath2[4096]; +extern wchar_t buffer1[8192]; +extern wchar_t buffer2[12288]; +void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location); bool ShouldLoadNorthstar(); bool ProvisionNorthstar(); |