Added lsteamclient for proton 9 and 11 for bionic steam client as well#1683
Conversation
📝 WalkthroughWalkthroughThe PR updates bionic Steam asset selection and boot-time ChangesBionic Steam asset lifecycle
Steam bootstrap status tracking
Diagnostics and real Steam launch settings
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
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
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
app/src/main/java/app/gamenative/ui/screen/library/appscreen/BaseAppScreen.ktapp/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.ktapp/src/main/java/app/gamenative/utils/launchdependencies/BionicSteamAssetsDependency.ktapp/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
There was a problem hiding this comment.
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
This reverts commit 84ac26f.
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.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/SteamBootstrap.kt (1)
160-170: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winCheck
getProcessStatus()before!proc.isAlivein the polling loop.The
!proc.isAlivecheck at line 159 returns beforegetProcessStatus()is ever called. If the host writesFAILED:<reason>to the ready file and then exits, theFailedstatus 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
⛔ Files ignored due to path filters (1)
app/src/main/jniLibs/arm64-v8a/libsteambootstrap.sois excluded by!**/*.so
📒 Files selected for processing (1)
app/src/main/java/app/gamenative/SteamBootstrap.kt
| 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) | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 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.
Description
Recording
Type of Change
Checklist
#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.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.soto the latest with structured host status for reliable startup.New Features
Bug Fixes
libsteamclient.socheck; improved bionic‑vs‑real detection; structuredsteambootstraphost status (Init/Ready/Failed/Closed) supported by the updatedlibsteambootstrap.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.
Summary by CodeRabbit