diff --git a/README.md b/README.md index f3f03b5..7b675f6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,17 @@ Launches Elden Ring without Easy Anti-Cheat. By default the game will not connec Intended for convenience, and may be useful as launchers to inject dlls in order to run offline mods. -The "launch_modded_eldenring.exe" launcher must be in the ELDENRING/Game directory (where eldenring.exe is located) +Users can inject dlls by creating a `eldenring_mods.txt` file and putting the name of each dll you want to load into the file on a new line. + +The "launch_modded_eldenring.exe" launcher must be in the `ELDEN RING/Game` directory (where eldenring.exe is located) + +You can prefix a mod with a folder name, and organize your mods, if you'd like. Example: + +``` +dllmods/elden_ring_seamless_coop.dll +``` + +this will look for `elden_ring_seamless_coop.dll` in the `ELDEN RING/Game/dllmods` folder. Please don't attempt to play online without Easy Anti-Cheat. diff --git a/launch_modded_eldenring/launch_modded_eldenring.cpp b/launch_modded_eldenring/launch_modded_eldenring.cpp index 1d56e4a..f4a7f0d 100644 --- a/launch_modded_eldenring/launch_modded_eldenring.cpp +++ b/launch_modded_eldenring/launch_modded_eldenring.cpp @@ -7,15 +7,26 @@ int main() { } void LaunchModdedEldenRing::Run() { - using namespace std::chrono_literals; + if (!CheckConditions()) { + should_run = false; + system("PAUSE"); + return; + }; + if (!LaunchGame()) { should_run = false; system("PAUSE"); return; }; + if (!InjectDLLMods()) { + should_run = false; + system("PAUSE"); + return; + }; + // Replace with anything else you'd like to do // doesn't have to be a dll injection /* @@ -35,8 +46,29 @@ void LaunchModdedEldenRing::Run() { return; }; -bool LaunchModdedEldenRing::LaunchGame() { +bool LaunchModdedEldenRing::CheckConditions() { + if (FileNotFound(L"eldenring.exe")) { + printf_s("Failed to find: \"eldenring.exe\". Make sure you put the mod files inside your \"ELDEN RING\\Game\\\" folder!\n"); + return false; + } + + std::string exe_path = GetExePath() + "eldenring.exe"; + if (exe_path.length() > MAX_PATH) { + printf_s("Cannot load path! Path is too long! %llu\\%d \n\"%s\"\n", exe_path.length(), MAX_PATH, exe_path.c_str()); + return false; + } + + //Warnings - These do not cause failure. + if (!FileNotFound(L"dinput8.dll")) { + printf_s("Warning: You are launching seamless with the launcher and there is a dinput8.dll.\n" + "If this dinput8.dll is a mod loader, it is recommended you use the dll mod loader included with this launcher\n" + "Check the README for details on how to add dll mods to the launcher via \"eldenring_mods.txt\"\n"); + } + return true; +} + +bool LaunchModdedEldenRing::LaunchGame() { OFSTRUCT file_struct = {}; HFILE elden_ring_exe_handle = OpenFile("eldenring.exe", &file_struct, OF_EXIST); if (elden_ring_exe_handle == HFILE_ERROR) { @@ -52,7 +84,7 @@ bool LaunchModdedEldenRing::LaunchGame() { STARTUPINFOA startup_info = {}; PROCESS_INFORMATION process_info = {}; if (!CreateProcessA("eldenring.exe", nullptr, nullptr, nullptr, - false, 0, nullptr, nullptr, &startup_info, &process_info)) { + false, 0, nullptr, nullptr, &startup_info, &process_info)) { printf_s("Failed to launch \"eldenring.exe\"\n"); return false; }; @@ -60,15 +92,31 @@ bool LaunchModdedEldenRing::LaunchGame() { elden_ring_thread = process_info.hThread; elden_ring_handle = process_info.hProcess; + return true; +} + +bool LaunchModdedEldenRing::InjectDLLMods() { + std::ifstream file("eldenring_mods.txt"); + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + printf_s("Loading %s...\n", line.c_str()); + if (!InjectMod(line.c_str())) { + printf_s("Failed to load %s...\n", line.c_str()); + return false; + }; + } + file.close(); + } return true; }; bool LaunchModdedEldenRing::InjectMod(const char* mod_name) { - OFSTRUCT file_struct = {}; HFILE elden_ring_exe_handle = OpenFile(mod_name, &file_struct, OF_EXIST); if (elden_ring_exe_handle == HFILE_ERROR) { - printf_s("Failed to find \"%s\"\n", mod_name); + std::string mod_path = GetExePath() + "eldenring.exe"; + printf_s("Failed to find: (%llu)\n\"%s\"\n", mod_path.length(), mod_path.c_str()); return false; }; @@ -87,15 +135,17 @@ bool LaunchModdedEldenRing::InjectMod(const char* mod_name) { FARPROC load_library_a = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA"); if (!load_library_a) { - printf_s("Unable to load mod dll\n"); + printf_s("Unable to load Kernel32.dll. Cannot call \"LoadLibraryA\" to load dll mods!\n"); return false; }; WriteProcessMemory(elden_ring_handle, dll_path, mod_name, memory_alloc, nullptr); - HANDLE dll_load_thread = CreateRemoteThread(elden_ring_handle, 0, 0, (LPTHREAD_START_ROUTINE)load_library_a, dll_path, 0, 0); + HANDLE dll_load_thread = CreateRemoteThread(elden_ring_handle, 0, 0, (LPTHREAD_START_ROUTINE)load_library_a, + dll_path, 0, 0); if (!dll_load_thread) { - printf_s("Unable to inject mod dll\n"); + std::string modPath = GetExePath() + mod_name; + printf_s("Unable to inject dll mod: (%llu)\n\"%s\"\n", modPath.length(), modPath.c_str()); return false; }; @@ -107,4 +157,25 @@ bool LaunchModdedEldenRing::InjectMod(const char* mod_name) { CloseHandle(elden_ring_handle_open); return true; -}; \ No newline at end of file +}; + +bool LaunchModdedEldenRing::FileNotFound(const std::wstring& name) { + return INVALID_FILE_ATTRIBUTES == GetFileAttributes(name.c_str()) && GetLastError() == ERROR_FILE_NOT_FOUND; +} + +std::string LaunchModdedEldenRing::GetExePath() { + char module_dir[MAX_PATH + 1]; + HMODULE mod; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCWSTR)&"", &mod); + GetModuleFileNameA(mod, module_dir, sizeof(module_dir)); + char* module_file_path_point = strrchr(module_dir, '\\'); + if (!module_file_path_point) { + MessageBoxA(0, "Failed to parse filepath string", "Item Randomiser Mod - Error", MB_ICONERROR); + throw std::runtime_error("Failed to parse filepath string"); + }; + *module_file_path_point = '\\\0'; //add slash and null terminator + return std::string(module_dir); +} + diff --git a/launch_modded_eldenring/launch_modded_eldenring.h b/launch_modded_eldenring/launch_modded_eldenring.h index d8a1b3b..33c13a3 100644 --- a/launch_modded_eldenring/launch_modded_eldenring.h +++ b/launch_modded_eldenring/launch_modded_eldenring.h @@ -1,12 +1,18 @@ #include #include #include +#include +#include class LaunchModdedEldenRing { public: void Run(); bool LaunchGame(); + bool InjectDLLMods(); bool InjectMod(const char* mod_name); + bool FileNotFound(const std::wstring& name); + bool CheckConditions(); + std::string GetExePath(); LaunchModdedEldenRing() { should_run = true;