fix(steamdeck): install the plugin runner + harden Deck pad typing + repair update.sh
- scripts/steamdeck/install.sh (§2b) + update.sh: build and install the scripting runner user-scoped (~/.local wrapper + pinned bun + bundle) — SteamOS's read-only /usr can't take the .deb layout, so the console's plugin store reported "the plugin runner isn't installed" on every SteamOS host. update.sh retrofits it onto existing installs. - plugins.rs runner discovery: check the ~/.local layout after the /usr ones; mention the SteamOS path in the not-installed error. - update.sh: define warn() — it was used but never defined, so under `set -e` the first warn aborted the update before services restarted. - pf-client-core gamepad: a Steam Input virtual pad forwarded on a real Deck (the only-pad case) now declares the DECK kind in its per-pad arrival instead of the wrapper's Xbox 360 identity — the session-level auto_pref already resolved SteamDeck, but the arrival overrides it on current hosts. - reject tests: cover SetupFailed; move the foreign-code probe off 0x68. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -876,10 +876,16 @@ impl Worker {
|
||||
);
|
||||
return;
|
||||
};
|
||||
let pref = self
|
||||
.pad_info(id)
|
||||
.map(|p| p.pref)
|
||||
.unwrap_or(GamepadPref::Xbox360);
|
||||
let pref = match self.pad_info(id) {
|
||||
// Steam Input's virtual pad standing in front of the Deck's built-in controls (the
|
||||
// only-pad-forwarded case, [`Self::forwarded_ids`]): declare the DECK kind, not the
|
||||
// wrapper's Xbox 360 identity. [`Self::auto_pref`] already resolves the SESSION
|
||||
// default this way, but a current host honors the per-pad arrival over the session
|
||||
// default — so without this the host builds an X-Box 360 pad on a real Deck.
|
||||
Some(p) if p.steam_virtual && is_steam_deck() => GamepadPref::SteamDeck,
|
||||
Some(p) => p.pref,
|
||||
None => GamepadPref::Xbox360,
|
||||
};
|
||||
match self.subsystem.open(sdl3::sys::joystick::SDL_JoystickID(id)) {
|
||||
Ok(pad) => {
|
||||
let mut slot = Slot::new(id, index, pref, pad);
|
||||
|
||||
@@ -146,7 +146,7 @@ impl std::fmt::Display for RejectReason {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const ALL: [RejectReason; 9] = [
|
||||
const ALL: [RejectReason; 10] = [
|
||||
RejectReason::PairingNotArmed,
|
||||
RejectReason::PairingBoundToOtherDevice,
|
||||
RejectReason::PairingRateLimited,
|
||||
@@ -156,6 +156,7 @@ mod tests {
|
||||
RejectReason::Superseded,
|
||||
RejectReason::WireVersionMismatch,
|
||||
RejectReason::Busy,
|
||||
RejectReason::SetupFailed,
|
||||
];
|
||||
|
||||
#[test]
|
||||
@@ -177,7 +178,7 @@ mod tests {
|
||||
fn foreign_codes_stay_untyped() {
|
||||
// Bare closes, the client's own pair-done codes, and the deliberate-end codes must
|
||||
// never read as a host rejection.
|
||||
for code in [0u32, 1, 0x41, 0x51, 0x52, 0x5f, 0x68, u32::MAX] {
|
||||
for code in [0u32, 1, 0x41, 0x51, 0x52, 0x5f, 0x69, u32::MAX] {
|
||||
assert_eq!(RejectReason::from_close_code(code), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ pub(crate) async fn serve(
|
||||
}
|
||||
conn_err.close(
|
||||
punktfunk_core::reject::SETUP_FAILED_CLOSE_CODE.into(),
|
||||
detail[..cut].as_bytes(),
|
||||
&detail.as_bytes()[..cut],
|
||||
);
|
||||
tracing::warn!(%peer, error = %detail, "session ended with error")
|
||||
}
|
||||
|
||||
@@ -158,9 +158,25 @@ pub(crate) fn runner_command() -> Result<(std::path::PathBuf, Vec<String>)> {
|
||||
if bun.exists() && runner.exists() {
|
||||
return Ok((bun, vec![runner.to_string_lossy().into_owned()]));
|
||||
}
|
||||
// Immutable-/usr distros (SteamOS): scripts/steamdeck/install.sh lays the SAME payload
|
||||
// out user-scoped under ~/.local — wrapper, private bun, and bundle mirroring the deb's
|
||||
// /usr layout — because a system package can't exist there.
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
let home = std::path::Path::new(&home);
|
||||
let wrapper = home.join(".local/bin/punktfunk-scripting");
|
||||
if wrapper.exists() {
|
||||
return Ok((wrapper, Vec::new()));
|
||||
}
|
||||
let bun = home.join(".local/lib/punktfunk-scripting/bun");
|
||||
let runner = home.join(".local/share/punktfunk-scripting/runner-cli.js");
|
||||
if bun.exists() && runner.exists() {
|
||||
return Ok((bun, vec![runner.to_string_lossy().into_owned()]));
|
||||
}
|
||||
}
|
||||
bail!(
|
||||
"the plugin runner isn't installed — install it first (Debian/Ubuntu: \
|
||||
`sudo apt install punktfunk-scripting`)"
|
||||
`sudo apt install punktfunk-scripting`; SteamOS: re-run \
|
||||
scripts/steamdeck/install.sh)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user