Skip to content

Add -onlinefix support for games that use EOS matchmaking#97

Open
Ran-Mewo wants to merge 1 commit into
OpenSteam001:mainfrom
Ran-Mewo:main
Open

Add -onlinefix support for games that use EOS matchmaking#97
Ran-Mewo wants to merge 1 commit into
OpenSteam001:mainfrom
Ran-Mewo:main

Conversation

@Ran-Mewo

@Ran-Mewo Ran-Mewo commented Jun 6, 2026

Copy link
Copy Markdown

Extends the existing -onlinefix flag to also work for games whose multiplayer runs on EOS instead of Steam. The 480-AppId trick can't reach those games (EOS traffic never crosses Steam) so the fix has to live inside the game process. This PR adds a small companion DLL (OnlineFix.dll) that the host injects into the game on launch, plus the host-side hook needed to inject it.
It's a very small DLL and doesn't need much maintenance. I know you might be against it, but it's a really simple solution that worked for all games I've tested.

Behavior for -onlinefix games that use Steam matchmaking is unchanged.

Explanation

Host side

  • Hooks_Inject — hooks CreateProcessW / CreateProcessAsUserW.
    • Hooks_Misc::OnSpawnProcessHit queues (exe basename → real AppId) when it sees a -onlinefix game.
    • The matching spawn is forced to be CREATE_SUSPENDED, and gets OnlineFix.dll injected via a remote-thread LoadLibraryW, then resumes.
    • Basename keys are used as lookup because the spawn handler and the real CreateProcessW fire on different threads.
  • RemoteInject::LoadDllVirtualAllocEx + WriteProcessMemory + CreateRemoteThread(LoadLibraryW). Header-only since the host and OnlineFix.dll are separate binaries that can't share a .obj.

Payload (src/Payload/, built as OnlineFix.dll)

  • payload.cpp — subscribes to LdrRegisterDllNotification and also walks EnumProcessModules, so EOSSDK-Win64-Shipping.dll is caught whether it's already loaded or arrives later.
  • EosBridge — the actual patch:
    • EOS_Connect_Login is rewritten as CreateDeviceId → re-Login with EOS_ECT_DEVICEID_ACCESS_TOKEN. Device ID auth has no Steam-ticket ownership check.
    • Display name is read from SteamFriends::GetPersonaName, so everyone still sees your actual name.
    • bPresenceEnabled is stripped from EOS_Lobby_CreateLobby / JoinLobby / JoinLobbyById — Device ID auth has no Epic presence to attach.
    • EOS_IntegratedPlatformOptionsContainer_Add is no-op'd, same reason.
  • SelfPropagate — Does the same CreateProcess*W hook that the host has but inside the game process. EOS titles are often spawned by a launcher, so the payload has to follow the process tree down to where the SDK actually loads.
  • PayloadLog — per-pid file at <Steam>/opensteamtool/payload/<pid>.log. Debug only; Release is empty stubs. This payload folder is also deleted on every Steam launch so that it doesn't bloat the disk.

Config / wiring

  • New [inject].enabled toggle (default true). Disabling skips the payload entirely; the 480 swap is unaffected.
  • New inject log module.
  • OnlineFix is a new add_library(... SHARED) target in src/CMakeLists.txt linking detours + psapi, with OPENSTEAMTOOL_LOGGING_ENABLED only on Debug — same convention as the host.
  • README "Online Fix" section updated to mention EOS support, and the [inject] block documented in the example TOML.

Notes on the diff

The diffs against README.md, src/CMakeLists.txt, src/Utils/Config.cpp, src/Utils/Config.h and src/dllmain.h look much larger than they really are because .gitattributes has eol=lf but the existing blobs for those files are CRLF, so git add re-normalizes them as a side effect of editing. Reviewing with ?w=1 (or git diff --ignore-all-space) shows the actual logical changes, which are small.

@OpenSteam001

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5cdee8974

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread README.md

## Usage
1. Run `build.bat` from the project root to build the project.
2. Copy generated `dwmapi.dll`, `xinput1_4.dll` and `OpenSteamTool.dll` to the Steam root directory.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the EOS payload in install instructions

For a fresh install following this Usage step, OnlineFix.dll is never copied to the Steam root, but InitializeSteamComponents now sets PayloadPath to <Steam>\OnlineFix.dll and the injection hook loads exactly that path. That means the new EOS -onlinefix path silently fails to install the payload even though the README says EOS matchmaking is supported; the copy step should include OnlineFix.dll.

Useful? React with 👍 / 👎.

Comment on lines +72 to +73
oCreateProcessW = reinterpret_cast<CreateProcessW_t> (GetProcAddress(k32, "CreateProcessW"));
oCreateProcessAsUserW = reinterpret_cast<CreateProcessAsUserW_t>(GetProcAddress(k32, "CreateProcessAsUserW"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Follow launchers that use ANSI process creation

When the injected process is only a launcher and it starts the actual EOS game via CreateProcessA/CreateProcessAsUserA, this propagation hook never runs because it only resolves and attaches the wide-character exports. In that scenario the child process starts without OnlineFix.dll, so EOSSDK-Win64-Shipping.dll loads unpatched and EOS matchmaking support fails for those launcher-based games; add the ANSI entry points or hook a common lower-level process creation path.

Useful? React with 👍 / 👎.

@OpenSteam001

Copy link
Copy Markdown
Owner

Thanks for the detailed explanation and for putting this together.

That said, I am currently not comfortable merging a feature that injects a companion DLL into the game process.

One of the boundaries I want to keep for OpenSteamTool is that it mainly works on the SteamClient side.

However, I understand that EOS support may be useful for some users. If you want, you can open a GitHub Discussion with a poll about this approach, so the community can share their opinions on whether OpenSteamTool should support EOS onlinefix through an optional injected payload.

If there is strong interest and the maintenance scope are clear, I may reconsider it later, possibly as an optional or experimental feature rather than something enabled by default.

@Ran-Mewo

Ran-Mewo commented Jun 6, 2026

Copy link
Copy Markdown
Author

@OpenSteam001 Since you're not comfortable with injecting a companion DLL (to be fair, neither am I), and it goes against the boundary of OpenSteamTool.

Is it possible to come to a compromise where OpenSteamTool provides support for injecting DLLs into the game
and I'll maintain the OnlineFix DLL. All the users have to do is download DLL from my repo and configure OpenSteamTool's toml

If you agree, then I can open another PR that adds third-party DLL injection support along with probably an API of some sort for all the information the DLL may need.

@OpenSteam001

OpenSteam001 commented Jun 6, 2026

Copy link
Copy Markdown
Owner

@Ran-Mewo
I think this compromise is acceptable.

I’m okay with OpenSteamTool providing a generic, opt-in DLL injection API/support layer, as long as OpenSteamTool itself does not ship or maintain the OnlineFix DLL. The actual third-party DLL can stay in your repo, and users would explicitly configure it in opensteamtool.toml.

Coincidentally, I’ve been working on game PID / pipe monitoring recently, mainly to distinguish the Denuvo authorization pipe from the game’s normal runtime pipe. During that work, I inevitably need to know when the real game process is created and associate some process-related information with the Steam pipe.

Because of that, I think the IPC handshake stage — for example when the game process calls something like SteamAPI_Init and establishes communication with Steam — may be a better injection point than raw CreateProcess interception.At that point,We wouldn't need a SelfPropagate-style mechanism.

That said, I haven’t actually tested this design yet, so this is only my current preferred direction rather than a final decision.

I’ll probably finish the pipe monitoring work within the next few days. After that, I can take a closer look at the injection mechanism you proposed and evaluate how it might fit into OpenSteamTool.

@Ran-Mewo

Ran-Mewo commented Jun 6, 2026

Copy link
Copy Markdown
Author

Alright, that sounds great! Let me know what direction you want me to take after you're done with the new changes.
And yeah, I'll remove the self-propagation mechanism if you manage to have something better.

Thanks!

@26mataa

26mataa commented Jun 7, 2026

Copy link
Copy Markdown

Hey guys. I absolutely don't have your level of expertise in this area, so here's what I'd like as an "Open Steam Tools user" regarding online fixes.

What I love about OpenSteamTools is its almost "Plug N play" aspect. I have my lua files that I drop into my lua folder and it appears on steam, I can download the game and apply or not goldberg to the game, in short, I love that.

Regarding the online fix, that's where I didn't quite understand the discussion so here's my point of view:
To play online games using OpenSteamTools, there is currently only one solution: go to online-fix.me, download the online version, and drag and drop it into the game folder. AND THAT is the part that bothers me.

I found the solution of simply adding -onlinefix to the game's startup parameters exceptional because it bypassed the need to go to a third-party site for this, except that, obviously, as previously mentioned, this solution does not work for all games.

That's exactly why, if you're doing a straw poll for the community, I am 100% in favor of integrating this. It would perfectly restore that seamless "plug and play" experience.
Since I don't have the technical background to follow all the details of the discussion, I just have one practical question to make sure I understand the end result: does this mean that all games using these types of servers will work with just a single OnlineFix.dll managed directly by the tool?

Basically, would this completely eliminate the need for me to manually find, download, and drag-and-drop specific OnlineFix files into each game's folder?

Thanks a lot for your hard work on this project!

@Ran-Mewo

Ran-Mewo commented Jun 7, 2026

Copy link
Copy Markdown
Author

@26mataa yes
This basically ensures games like Escape The Backrooms, the newest Subnautica game, Cloudheim, (and so much more) just work seamlessly if you add the -onlinefix to your launch options

So far in my testing, every online game just works now
If one doesn't, then, uh, let me know and I'll take a look

@26mataa

26mataa commented Jun 7, 2026

Copy link
Copy Markdown

@Ran-Mewo That sounds good to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants