Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
89 changes: 80 additions & 9 deletions launch_modded_eldenring/launch_modded_eldenring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
/*
Expand All @@ -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) {
Expand All @@ -52,23 +84,39 @@ 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;
};

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;
};

Expand All @@ -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;
};

Expand All @@ -107,4 +157,25 @@ bool LaunchModdedEldenRing::InjectMod(const char* mod_name) {

CloseHandle(elden_ring_handle_open);
return true;
};
};

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);
}

6 changes: 6 additions & 0 deletions launch_modded_eldenring/launch_modded_eldenring.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
#include <windows.h>
#include <chrono>
#include <thread>
#include <fstream>
#include <string>

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;
Expand Down