Skip to content

Added lsteamclient for proton 9 and 11 for bionic steam client as well#1683

Merged
utkarshdalal merged 12 commits into
masterfrom
lsteamclient-other-protons
Jul 10, 2026
Merged

Added lsteamclient for proton 9 and 11 for bionic steam client as well#1683
utkarshdalal merged 12 commits into
masterfrom
lsteamclient-other-protons

Conversation

@utkarshdalal

@utkarshdalal utkarshdalal commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Description

Recording

Type of Change

  • Bug fix
  • Performance / stability improvement
  • Compatibility improvements
  • Other (requires prior approval)

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by cubic

Adds per‑Proton lsteamclient support for Proton 9/10/11 and updates the bionic Steam client with version‑gated assets. Auto-selects the correct steam.exe (adds steam-proton11.exe), re‑extracts lsteamclient on each boot to prevent ABI mismatches, and updates libsteambootstrap.so to the latest with structured host status for reliable startup.

  • New Features

    • Map wine versions to Proton 9/10/11 lsteamclient archives (x86_64, arm64ec) with a safe fallback.
    • Proton-aware steam.exe selection (adds steam-proton11.exe) and exposed cache names for detection.
  • Bug Fixes

    • Reworked lsteamclient flow: download at install; re-extract into the Proton tree and copy into the prefix every boot to avoid ABI mismatches.
    • Versioned bionic Steam install with a marker, extraction retry, and libsteamclient.so check; improved bionic‑vs‑real detection; structured steambootstrap host status (Init/Ready/Failed/Closed) supported by the updated libsteambootstrap.so; reduced Steam launch noise, always show diagnostics options, and removed a synchronous read on game open.

Written for commit 024433d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Diagnostics options are now available for all installed games, independent of graphics driver configuration.
  • Bug Fixes
    • Improved Bionic Steam handling to select the correct cached Steam assets per container.
    • More reliable detection across possible cached Bionic Steam executable variants.
    • Steam component updates now refresh lsteamclient into the active Proton prefix on every boot.
    • Improved Steam bootstrap readiness/status handling for more consistent startup.
  • Refactor
    • Reduced Steam debug/logging noise by omitting related environment variables in the real Steam launch setup.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates bionic Steam asset selection and boot-time lsteamclient extraction, adds explicit Steam host process states, broadens diagnostics menu availability for installed games, and removes Steam diagnostic logging variables from real Steam launches.

Changes

Bionic Steam asset lifecycle

Layer / File(s) Summary
Asset resolution and dependency validation
app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt
Wine-version mappings resolve Steam executable and lsteamclient assets, while readiness checks validate cached prerequisites and versioned bionic installation markers.
Dynamic asset installation
app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt
Installation downloads selected Steam and lsteamclient assets, with retry handling for versioned bionic Steam archive extraction.
Boot-time Steam integration
app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt, app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt
Bionic Steam setup selects cached executable variants, extracts lsteamclient into the prefix on boot, and checks all cached bionic Steam executable names.

Steam bootstrap status tracking

Layer / File(s) Summary
Host process status model
app/src/main/java/app/gamenative/SteamBootstrap.kt
SteamBootstrap defines Init, Failed, Ready, and Closed states with ready-file parsing and serialization.
Readiness initialization and polling
app/src/main/java/app/gamenative/SteamBootstrap.kt
Bootstrap initializes the ready file to INIT, derives status through getProcessStatus(), and returns for ready or terminal host states.

Diagnostics and real Steam launch settings

Layer / File(s) Summary
Installed-game diagnostics options
app/src/main/java/app/gamenative/ui/screen/library/appscreen/BaseAppScreen.kt
Installed games always show “Play with diagnostics” and “Share diagnostics”, regardless of the container graphics driver.
Real Steam launch environment
app/src/main/java/com/winlator/xenvironment/components/BionicProgramLauncherComponent.java
Real Steam launches no longer receive the removed Steam debugging and logging environment variables.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant XServerScreen
  participant BionicSteamAssetsDependency
  participant ProtonPrefix
  XServerScreen->>BionicSteamAssetsDependency: Resolve container-specific Steam executable
  XServerScreen->>BionicSteamAssetsDependency: Extract lsteamclient on boot
  BionicSteamAssetsDependency->>ProtonPrefix: Copy lsteamclient DLLs
  XServerScreen->>BionicSteamAssetsDependency: Check cached bionic executable names
Loading
sequenceDiagram
  participant SteamBootstrap
  participant ReadyFile
  participant HostProcess
  SteamBootstrap->>ReadyFile: Write INIT
  SteamBootstrap->>HostProcess: Check process liveness
  SteamBootstrap->>ReadyFile: Parse process status
  SteamBootstrap->>SteamBootstrap: Continue polling or return
Loading

Possibly related PRs

Suggested reviewers: phobos665

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is related to the main lsteamclient and bionic Steam client changes, though it omits other notable updates.
Description check ✅ Passed The required template sections are present and the auto-generated summary explains the change, though the recording and checklist are not filled.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lsteamclient-other-protons

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@utkarshdalal utkarshdalal marked this pull request as ready for review July 9, 2026 22:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt`:
- Around line 72-84: The lsteamclientArchiveFor function incorrectly synthesizes
Proton archive names for unmapped versions, potentially causing launch failures
when files are unavailable. Remove the major-version fallback logic and return
null for any wineVersion not present in LSTEAMCLIENT_ARCHIVE_BY_WINE, unless the
generated archive is verified to exist on the server.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cefacc75-7c1b-4b86-9775-e89f3f90a9d1

📥 Commits

Reviewing files that changed from the base of the PR and between 7cc9f93 and ee3231c.

📒 Files selected for processing (4)
  • app/src/main/java/app/gamenative/ui/screen/library/appscreen/BaseAppScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt
  • app/src/main/java/com/winlator/xenvironment/components/BionicProgramLauncherComponent.java
💤 Files with no reviewable changes (1)
  • app/src/main/java/com/winlator/xenvironment/components/BionicProgramLauncherComponent.java

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt">

<violation number="1" location="app/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.kt:143">
P2: The `extractLsteamclientIntoPrefix` function logs extraction/copy failures but does not surface them to the caller. The old `install()` code threw `IllegalStateException` on these failures, making them impossible to miss. Since `isSatisfied()` now only checks whether the archive is cached (not whether the DLLs are actually in the prefix), a silent failure means the game could launch without the correct lsteamclient DLLs in place, leading to confusing runtime errors. Consider at minimum throwing (or propagating the failure to the caller so the boot flow can surface it) rather than silently returning on extraction/copy errors.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Utkarsh Dalal and others added 6 commits July 9, 2026 17:34
Introduces a `ProcessStatus` sealed class to explicitly define the lifecycle states (Init, Failed, Ready, Closed) of the native `steambootstrap` host process. This allows for more robust and precise tracking of its status.

The host process initialization now leverages this structured status, improving error detection and reliability by distinguishing between a process that is still initializing, ready, or has unexpectedly failed or closed.

The accompanying `libsteambootstrap.so` binary update supports writing these detailed status messages.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/SteamBootstrap.kt (1)

160-170: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Check getProcessStatus() before !proc.isAlive in the polling loop.

The !proc.isAlive check at line 159 returns before getProcessStatus() is ever called. If the host writes FAILED:<reason> to the ready file and then exits, the Failed status is never observed by the loop — the return is indistinguishable from a crash, undermining the PR's failure-detection goal.

Reorder to check status first, and only fall through to the liveness check when the status is still Init:

♻️ Proposed reorder
         while (System.currentTimeMillis() < deadline) {
-            if (!proc.isAlive) return
-
             val status = getProcessStatus()
             when (status) {
                 is ProcessStatus.Ready -> return
                 is ProcessStatus.Failed, is ProcessStatus.Closed -> return
-                is ProcessStatus.Init -> {}
+                is ProcessStatus.Init -> {
+                    if (!proc.isAlive) return
+                }
             }
 
             try { Thread.sleep(100) } catch (_: InterruptedException) { return }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/SteamBootstrap.kt` around lines 160 - 170,
Reorder the polling logic so getProcessStatus() runs before the !proc.isAlive
check. In the loop containing ProcessStatus.Ready, Failed, Closed, and Init
handling, return immediately for Ready, Failed, or Closed; only when status is
Init should you evaluate process liveness and return if the process has exited,
then continue sleeping.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/main/java/app/gamenative/SteamBootstrap.kt`:
- Around line 172-190: Update getProcessStatus() so that after parsing the
ready-file content with ProcessStatus.fromString, an Init result is
cross-checked against hostProcess?.isAlive; return Init only while the process
is alive, otherwise return Closed. Preserve existing handling for missing,
unreadable, empty, and non-Init statuses.

---

Nitpick comments:
In `@app/src/main/java/app/gamenative/SteamBootstrap.kt`:
- Around line 160-170: Reorder the polling logic so getProcessStatus() runs
before the !proc.isAlive check. In the loop containing ProcessStatus.Ready,
Failed, Closed, and Init handling, return immediately for Ready, Failed, or
Closed; only when status is Init should you evaluate process liveness and return
if the process has exited, then continue sleeping.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34449d52-1838-4a39-a6f9-f4b908c76646

📥 Commits

Reviewing files that changed from the base of the PR and between 72a00e3 and 7161b3f.

⛔ Files ignored due to path filters (1)
  • app/src/main/jniLibs/arm64-v8a/libsteambootstrap.so is excluded by !**/*.so
📒 Files selected for processing (1)
  • app/src/main/java/app/gamenative/SteamBootstrap.kt

Comment on lines +172 to +190
fun getProcessStatus(): ProcessStatus {
val cfg = hostCfg ?: return ProcessStatus.Init
val readyFile = File(cfg.context.cacheDir, "sb_host_ready")

if (!readyFile.exists()) {
return if (hostProcess?.isAlive == true) {
ProcessStatus.Init
} else {
ProcessStatus.Closed
}
}

val content = runCatching { readyFile.readText().trim() }.getOrNull() ?: ""
return if (content.isEmpty()) {
ProcessStatus.Init
} else {
ProcessStatus.fromString(content)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

getProcessStatus() returns Init for a dead host process when the ready file still contains "INIT".

The !readyFile.exists() branch (lines 176–182) correctly cross-checks hostProcess?.isAlive, but the file-exists branch (lines 184–189) does not. If the host crashes or is stopped after prepareApp writes "INIT" but before the native code writes a terminal status, the file still says "INIT" and getProcessStatus() returns Init indefinitely for a process that is no longer running. External callers could hang waiting for a dead process to become ready.

Apply the same liveness cross-check when the parsed status is Init:

🐛 Proposed fix
         val content = runCatching { readyFile.readText().trim() }.getOrNull() ?: ""
-        return if (content.isEmpty()) {
-            ProcessStatus.Init
-        } else {
-            ProcessStatus.fromString(content)
+        val status = if (content.isEmpty()) {
+            ProcessStatus.Init
+        } else {
+            ProcessStatus.fromString(content)
         }
+        return if (status is ProcessStatus.Init && hostProcess?.isAlive != true) {
+            ProcessStatus.Closed
+        } else {
+            status
+        }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/SteamBootstrap.kt` around lines 172 - 190,
Update getProcessStatus() so that after parsing the ready-file content with
ProcessStatus.fromString, an Init result is cross-checked against
hostProcess?.isAlive; return Init only while the process is alive, otherwise
return Closed. Preserve existing handling for missing, unreadable, empty, and
non-Init statuses.

@utkarshdalal utkarshdalal merged commit 268816f into master Jul 10, 2026
2 checks passed
@utkarshdalal utkarshdalal deleted the lsteamclient-other-protons branch July 10, 2026 05:09
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.

2 participants