launcher: auto-strip SteamStub DRM before patching

Steam-purchased Rec Room ships with SteamStub Variant 3.1 wrapping
Recroom_Release.exe so it refuses to launch without Steam loaded.
DorkNet spawns the exe directly, so for Steam installs we have to
unwrap it first or the user gets a silent crash on Launch.

- SteamDrmStripper.StripIfNeededAsync: PE-walks the exe's section
  table looking for the .bind section SteamStub adds, and only
  invokes Steamless when that section is present. Re-runs detect
  the already-unwrapped exe and short-circuit. Backs up the
  original next to the exe as Recroom_Release.exe.steamwrapped.
- SteamlessInstaller: resolves a usable Steamless.CLI.exe via
  side-by-side -> %LOCALAPPDATA%\DorkNet\Steamless\ cache ->
  download v3.1.0.5 from atom0s/Steamless GitHub releases. Same
  pattern as CloudflaredInstaller.
- Inserted as a step between "Download client patcher" and "Patch
  your Rec Room install" in both host (5 -> 6 steps) and join
  (2 -> 3 steps). Step detail reports Stripped / AlreadyUnpacked /
  NotApplicable so the user sees what happened.

Oculus / Quest builds and already-unwrapped installs skip the
Steamless download entirely.
This commit is contained in:
Alexa
2026-05-27 12:10:27 +03:00
parent de98ea694f
commit 26786527cd
4 changed files with 273 additions and 0 deletions
+24
View File
@@ -546,6 +546,18 @@ public partial class MainWindow : Window
CompleteStep(activeStep);
activeStep = StartStep(_hostSteps, 4);
var stripProgress = new Progress<DownloadProgress>(p => UpdateStepProgress(activeStep, p));
var stripResult = await SteamDrmStripper.StripIfNeededAsync(
_state.RecRoomPath!, stripProgress);
activeStep.Detail = stripResult switch
{
StripResult.Stripped => "Steam DRM removed; backup saved next to the exe.",
StripResult.AlreadyUnpacked => "Already unwrapped — skipped.",
_ => "Not a Steam build — skipped.",
};
CompleteStep(activeStep);
activeStep = StartStep(_hostSteps, 5);
var patch = await _patcher.ApplyAsync(
patcherDir, _state.RecRoomPath!,
_state.PhotonAppId, _state.PhotonVoiceAppId, _state.PhotonRegion, _hostApex);
@@ -749,6 +761,18 @@ public partial class MainWindow : Window
CompleteStep(activeStep);
activeStep = StartStep(_joinSteps, 1);
var stripProgress = new Progress<DownloadProgress>(p => UpdateStepProgress(activeStep, p));
var stripResult = await SteamDrmStripper.StripIfNeededAsync(
_state.RecRoomPath!, stripProgress);
activeStep.Detail = stripResult switch
{
StripResult.Stripped => "Steam DRM removed; backup saved next to the exe.",
StripResult.AlreadyUnpacked => "Already unwrapped — skipped.",
_ => "Not a Steam build — skipped.",
};
CompleteStep(activeStep);
activeStep = StartStep(_joinSteps, 2);
var patch = await _patcher.ApplyAsync(
patcherDir, _state.RecRoomPath!,
payload.PhotonAppId, payload.PhotonVoiceAppId, payload.PhotonRegion, payload.Host);