diff --git a/CHANGELOG.md b/CHANGELOG.md index 251310b..da5a3a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,23 @@ the contract is "it works on RS50 and G Pro as listed here". ## Unreleased +**The SDK proxy is no longer recommended where it cannot load, and the +tools catch it.** ACC and AC EVO check the signature of Logitech's library +before loading it, and the proxy `logi-shim --proxy` puts in its place is +unsigned, so there the game drops TrueForce and every force the library +carries, silently. The README, the game setup guide and the apps' setup +hints recommended the proxy to G923 owners in exactly those two games; they +now point to Simulated TrueForce. `logi-shim --proxy` warns when it is +installed for either game, `setup.sh doctor` fails on a prefix that has it, +and `logi-launch` no longer grants raw HID on the strength of it there, +since raw HID would then take away the DirectInput force feedback as well. +It prints the two commands that put Logitech's own library back. + +**`logi-launch` starts the `logi-tf-sim` it reports.** The daemon runs as a +user service, and the user manager looked the binary up on its own PATH, so +a copy earlier on the game's PATH was named in the log's versions line while +the installed one ran. The launcher now resolves the binary itself. + **The DiRT Rally 2.0 recipe is written down, end to end.** With the proxy turned on (`690790 ffb=proxy`), the telemetry set to `extradata="3"`, and a one-line `device_defines.xml` entry that gives the stand-in wheel an diff --git a/README.md b/README.md index b1f8cf2..8510d22 100644 --- a/README.md +++ b/README.md @@ -434,10 +434,9 @@ generated from the same registry the app uses, so the two cannot disagree. Proton prefix (the app's Setup page, or `tools/install-tf-shim.sh`), and launch with `logi-launch %command%`, which turns raw HID on for the wheels that want it and stages the proxy that answers the SDK's rotation - question. Set `PROTON_ENABLE_HIDRAW=1` by hand only with something - answering that question (`tools/install-tf-shim.sh --proxy`): with - Logitech's stock library alone the game's steering and force feedback - stop on track, and the launcher refuses to set it in that state. The + question. Leave `PROTON_ENABLE_HIDRAW` to the launcher: with Logitech's + stock library alone the game's steering and force feedback stop on + track, and the launcher refuses to set it in that state. The DLLs are the one part nobody can automate, because Logitech's files cannot be redistributed. The one-time recipe is on the [Force feedback in games](https://github.com/mescon/logitech-trueforce-linux-driver/wiki/Force-Feedback-in-Games) @@ -447,12 +446,12 @@ generated from the same registry the app uses, so the two cannot disagree. **On a G923 the recipe is different, not absent.** That wheel does not answer the TrueForce SDK, so `PROTON_ENABLE_HIDRAW` must stay unset: there it does not add TrueForce, it takes away the force feedback you already - had. Install the shim with `--proxy` instead. That puts this project's own - SDK proxy in the game's path, where it copies the TrueForce the game is - already producing and streams it to the wheel directly, so a G923 gets the - game's real haptics without the SDK needing to cooperate. The same proxy - answers the game's rotation question, which is the packaged fix for the - 90-degree clamp (#27). See [G923 support](#g923-support). + had. For haptics, turn the game on under Simulated TrueForce instead: + `logi-tf-sim` synthesizes an engine note from the game's own telemetry, + confirmed working on a G923 in ACC and AC EVO. The shim's `--proxy` + option does not help in those two: both check the library's signature + and refuse the unsigned proxy, so it carries nothing there. See + [G923 support](#g923-support). **Where the SDK files go.** Copy the `Logi` folder out of a Windows G HUB install into `~/.local/share/logitech-trueforce/sdk`, keeping its own diff --git a/docs/GAME_SETUP.md b/docs/GAME_SETUP.md index b6ae2f4..be66d35 100644 --- a/docs/GAME_SETUP.md +++ b/docs/GAME_SETUP.md @@ -35,13 +35,11 @@ game's own telemetry, read out of its shared memory by a small relay (`docs/SHARED_MEMORY_RELAY.md`). Confirmed working on a G923 in Assetto Corsa Competizione and EVO. -There is a second route that carries the real thing: installing the -shim with `--proxy` puts this project's own SDK proxy in the game's -path, where it copies the TrueForce the game is already producing -and streams it to the wheel. It is the same proxy that ships the -packaged fix for the 90-degree rotation clamp, so it loads and -works; the apps do not install it yet, so -`tools/install-tf-shim.sh --proxy` is how to turn it on. +The shim's `--proxy` option is not a second route in these games. +Both check the library's signature before loading it and refuse the +unsigned proxy, so it carries nothing, and on a wheel that uses +Logitech's library it costs the game that library's force feedback +too. `./tools/setup.sh doctor` flags a prefix that has it. Launch options go in Steam under the game's Properties. Paste them exactly, `%command%` included: it is the placeholder Steam replaces @@ -136,7 +134,7 @@ app's Setup page afterwards. ## What each recipe means - **Install the shim.** Stage Logitech's signed SDK DLLs into the game's Proton prefix, from the app's Setup page or `tools/install-tf-shim.sh`. Install the TrueForce shim once, from the app's Setup page; launch options `logi-launch %command%` (it turns raw HID on, stages the proxy that answers the SDK's rotation question, without which the stock library stops steering and force on track, and everything else this game needs); turn Steam Input off. No engine-note texture merge here: ACC produces its own TrueForce audio, so the merge is not wired for it. -- **On a wheel with no SDK TrueForce.** Leave PROTON_ENABLE_HIDRAW unset: on this wheel it costs you force feedback. For haptics, turn this game on under Simulated TrueForce; logi-launch puts the telemetry relay in the game's prefix and starts the daemon for you, and that route is confirmed working on a G923. Installing the shim WITH --proxy carries the game's own TrueForce to the wheel instead, the same proxy that ships the 90-degree rotation fix; the apps install the plain shim, so use tools/install-tf-shim.sh --proxy. Steam Input off. +- **On a wheel with no SDK TrueForce.** Leave PROTON_ENABLE_HIDRAW unset: on this wheel it costs you force feedback. For haptics, turn this game on under Simulated TrueForce; logi-launch puts the telemetry relay in the game's prefix and starts the daemon for you, and that route is confirmed working on a G923. Steam Input off. - **Launch via logi-ffb.** Launch options `logi-launch %command%` (it keeps raw HID off, runs the logi-ffb helper and puts the telemetry relay in the game's prefix for you); Steam Input off. Simulated TrueForce also needs the community rF2SharedMemoryMapPlugin installed in the game. - **Nothing to do.** The wheel is an ordinary Linux force feedback device and the game drives it directly. diff --git a/tools/install-tf-shim.sh b/tools/install-tf-shim.sh index 0385682..92687a7 100755 --- a/tools/install-tf-shim.sh +++ b/tools/install-tf-shim.sh @@ -261,14 +261,15 @@ Options: --sdk-dir Directory holding your Logitech SDK DLLs (default: \$LOGITECH_TRUEFORCE_SDK_DIR, the repo sdk/ tree, or $(default_sdk_dir)) - --proxy Also install this project's SDK proxy. It does - two things: answers the rotation question so a - game stops clamping the wheel to 90 degrees - (#27), and carries the game's own TrueForce to - a wheel Logitech's SDK will not drive, which is - how a G923 gets TrueForce in ACC and AC EVO. - Spelled --range-proxy before it did the second - job; both names still work. + --proxy Also install this project's SDK proxy, which + answers the rotation question (#27) and copies + TrueForce samples a game hands the library to + logi-tf-sim. It is unsigned, and games that + check the library's signature refuse it: ACC + and AC EVO then run with no TrueForce and no + force from the library at all, so do not use + it for them. Spelled --range-proxy before it + did the second job; both names still work. --oem-ffb Also install G HUB's DirectInput force-feedback driver (hidpp_forcefeedback), from a "Logitech" folder beside the "Logi" one. Windows routes @@ -377,6 +378,15 @@ install_in_prefix() { mv -f "$tf_dir/trueforce_sdk_x64.dll" "$tf_dir/trueforce_real.dll" install -m 0644 "$proxy" "$tf_dir/trueforce_sdk_x64.dll" echo " rotation shim installed in $prefix" + # These two verify the library's signature before loading it, + # and the proxy is unsigned (docs/DINPUT_ESCAPE.md). + case $prefix in + */compatdata/805550/pfx|*/compatdata/805550/pfx/|*/compatdata/3058630/pfx|*/compatdata/3058630/pfx/) + echo " WARNING: this game checks the library's signature and refuses the proxy:" >&2 + echo " it will run with no TrueForce and no force from the library." >&2 + echo " Undo: $0 --uninstall-prefix \"$prefix\", then --prefix without --proxy." >&2 + ;; + esac else echo " WARNING: --range-proxy asked for but tf-range-proxy.dll was not found" >&2 echo " in the checkout or /usr/share/logitech-trueforce/." >&2 diff --git a/tools/logi-launch.sh b/tools/logi-launch.sh index 69844ea..3b2cca2 100755 --- a/tools/logi-launch.sh +++ b/tools/logi-launch.sh @@ -302,6 +302,16 @@ if [ -n "$prefix_root" ]; then [ -f "$f" ] && have_tf_proxy=1 && break done fi +# ACC and AC EVO check the library's signature before loading it and +# refuse the unsigned proxy, so there it answers nothing: the SDK never +# loads, the game falls back to DirectInput, and raw HID would then take +# that force feedback away as well (AC EVO, 2026-09-24). +tf_proxy_refused=0 +if [ "$have_tf_proxy" = "1" ]; then + case "${SteamAppId:-${SteamGameId:-0}}" in + 805550|3058630) tf_proxy_refused=1; have_tf_proxy=0 ;; + esac +fi # Nonzero when the plan granted the game raw HID access (an SDK title): # those sessions can leave the wheel's TrueForce engine started, so they @@ -360,7 +370,16 @@ case "$want_hidraw" in [ -r "$(share_file dinput8-escape.dll 2>/dev/null || echo /nonexistent)" ]; then can_stage_proxy=1 fi - if [ "$have_tf_files" = "1" ] && [ "$have_tf_proxy" = "0" ] && \ + if [ "$tf_proxy_refused" = "1" ]; then + export PROTON_ENABLE_HIDRAW=0 + say "NOT setting PROTON_ENABLE_HIDRAW: this prefix has the SDK proxy" + say "(logi-shim --proxy), and this game checks the library's" + say "signature and refuses it, so the SDK never loads here and raw HID" + say "would only take away the force feedback you have. To get the" + say "game's TrueForce back, reinstall the shim without the proxy:" + say " logi-shim --uninstall-prefix \"$prefix_root/pfx\"" + say " logi-shim --prefix \"$prefix_root/pfx\" (tools/install-tf-shim.sh from a checkout)" + elif [ "$have_tf_files" = "1" ] && [ "$have_tf_proxy" = "0" ] && \ [ "$can_stage_proxy" = "0" ]; then export PROTON_ENABLE_HIDRAW=0 say "NOT setting PROTON_ENABLE_HIDRAW: Logitech's TrueForce files are in" @@ -795,17 +814,21 @@ if [ "${LOGI_LAUNCH_TF_SIM:-1}" = "1" ] && [ "${want_tfsim:-1}" = "1" ]; then # Steam, a system without a user manager), the daemon runs as a child # of this wrapper instead and is stopped when the game exits, which # is the honest alternative: a later session starts it again. + # The service is started by the user manager, which searches its own + # PATH, not this session's; the binary is resolved here so the daemon + # that runs is the one the versions line above reported. start_tf_sim() { + tfsim_bin=$(command -v logi-tf-sim 2>/dev/null || echo logi-tf-sim) if command -v systemd-run >/dev/null 2>&1 && \ systemd-run --user --quiet --collect \ --description="logi-tf-sim (started by logi-launch)" \ --property=StandardOutput=append:"$LOG" \ --property=StandardError=append:"$LOG" \ - env "$@" logi-tf-sim 2>/dev/null; then + env "$@" "$tfsim_bin" 2>/dev/null; then say "logi-tf-sim runs as a user service, outside Steam's process tree" return 0 fi - setsid env "$@" logi-tf-sim >>"$LOG" 2>&1 >"$LOG" 2>&1 /dev/null | tail -1) @@ -636,12 +642,23 @@ doctor() { grep -aq "trueforce_real" "$d/trueforce_sdk_x64.dll" 2>/dev/null || continue proxied=$((proxied+1)) [ -f "$d/trueforce_real.dll" ] || orphaned=$((orphaned+1)) + case $appid in + 805550|3058630) + refused_n=$((refused_n+1)) + refused="$refused$root/steamapps/compatdata/$appid/pfx +" ;; + esac done done <<< "$roots" + local pfx + while IFS= read -r pfx; do + [ -n "$pfx" ] || continue + bad "rotation shim installed in $pfx, a game that refuses it: no TrueForce and no force from Logitech's library there (fix: ./tools/install-tf-shim.sh --uninstall-prefix \"$pfx\", then --prefix \"$pfx\" without --proxy)" + done <<< "$refused" if [ "$orphaned" -gt 0 ]; then bad "rotation shim installed in $orphaned prefix(es) without Logitech's library beside it - those games get no force feedback (re-run: ./tools/install-tf-shim.sh --all-steam --range-proxy)" - elif [ "$proxied" -gt 0 ]; then - ok "rotation shim installed in $proxied SDK sim(s), with Logitech's library beside it" + elif [ "$proxied" -gt "$refused_n" ]; then + ok "rotation shim installed in $((proxied-refused_n)) SDK sim(s), with Logitech's library beside it" fi fi diff --git a/userspace/logi-wheel/crates/logi-wheel-core/src/games.rs b/userspace/logi-wheel/crates/logi-wheel-core/src/games.rs index 499dbe0..92fbc0b 100644 --- a/userspace/logi-wheel/crates/logi-wheel-core/src/games.rs +++ b/userspace/logi-wheel/crates/logi-wheel-core/src/games.rs @@ -502,9 +502,7 @@ impl GameCompat { // has nothing to synthesise from, so it must not be offered. "Leave PROTON_ENABLE_HIDRAW unset: on this wheel it costs you \ force feedback, and this game publishes no telemetry yet, so \ - there is no simulated TrueForce to turn on either. Installing \ - the shim WITH --proxy carries the game's own TrueForce to the \ - wheel instead (tools/install-tf-shim.sh --proxy). Steam Input \ + there is no simulated TrueForce to turn on either. Steam Input \ off." } else if self.ffb == Ffb::TrueForceShim && !caps.sdk_trueforce { // Worded as "not available on this wheel" rather than "this @@ -515,11 +513,7 @@ impl GameCompat { force feedback. For haptics, turn this game on under Simulated \ TrueForce; logi-launch puts the telemetry relay in the game's \ prefix and starts the daemon for you, and that route is \ - confirmed working on a G923. Installing the shim WITH --proxy \ - carries the game's own TrueForce to the wheel instead, the same \ - proxy that ships the 90-degree rotation fix; the apps install \ - the plain shim, so use tools/install-tf-shim.sh --proxy. Steam \ - Input off." + confirmed working on a G923. Steam Input off." } else { self.setup } diff --git a/userspace/logi-wheel/crates/logi-wheel-core/src/steam.rs b/userspace/logi-wheel/crates/logi-wheel-core/src/steam.rs index c9710f1..0d2d7ef 100644 --- a/userspace/logi-wheel/crates/logi-wheel-core/src/steam.rs +++ b/userspace/logi-wheel/crates/logi-wheel-core/src/steam.rs @@ -331,8 +331,8 @@ pub fn resolve_sdk_dir(field: &str, installer: Option<&Path>) -> Option /// The plain shim, without the SDK proxy: the rotation question the SDK /// must have answered under Proton is answered by the dinput8 escape /// proxy `logi-launch` stages for every native-TrueForce session. The SDK -/// proxy (`--proxy`) stays a by-hand route; ACC on an RS50 would not load -/// it at all (2026-09-05), while it is what carries TrueForce to a G923. +/// proxy (`--proxy`) stays a by-hand route: it is unsigned, and ACC and +/// AC EVO check the library's signature and refuse it outright. pub fn shim_install_args(prefix: &str, sdk_dir: Option<&Path>) -> Vec { let mut args = vec!["--prefix".to_string(), prefix.to_string()]; if let Some(dir) = sdk_dir { diff --git a/userspace/logi-wheel/crates/logi-wheel-core/tests/game_setup_doc.rs b/userspace/logi-wheel/crates/logi-wheel-core/tests/game_setup_doc.rs index a2de8e8..f26c7d4 100644 --- a/userspace/logi-wheel/crates/logi-wheel-core/tests/game_setup_doc.rs +++ b/userspace/logi-wheel/crates/logi-wheel-core/tests/game_setup_doc.rs @@ -111,13 +111,11 @@ fn render() -> String { game's own telemetry, read out of its shared memory by a small relay\n\ (`docs/SHARED_MEMORY_RELAY.md`). Confirmed working on a G923 in\n\ Assetto Corsa Competizione and EVO.\n\n\ - There is a second route that carries the real thing: installing the\n\ - shim with `--proxy` puts this project's own SDK proxy in the game's\n\ - path, where it copies the TrueForce the game is already producing\n\ - and streams it to the wheel. It is the same proxy that ships the\n\ - packaged fix for the 90-degree rotation clamp, so it loads and\n\ - works; the apps do not install it yet, so\n\ - `tools/install-tf-shim.sh --proxy` is how to turn it on.\n\n", + The shim's `--proxy` option is not a second route in these games.\n\ + Both check the library's signature before loading it and refuse the\n\ + unsigned proxy, so it carries nothing, and on a wheel that uses\n\ + Logitech's library it costs the game that library's force feedback\n\ + too. `./tools/setup.sh doctor` flags a prefix that has it.\n\n", ); out.push_str( "Launch options go in Steam under the game's Properties. Paste them\n\