Compare commits
1 Commits
3174fe4c1f
...
c5424158b9
| Author | SHA1 | Date | |
|---|---|---|---|
| c5424158b9 |
@@ -24,6 +24,7 @@
|
||||
//! falls back to it, so an existing working setup cannot be broken by upgrading.
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, Stdio};
|
||||
@@ -67,6 +68,7 @@ pub fn launch(
|
||||
for (k, v) in &profile.env {
|
||||
cmd.env(k, v);
|
||||
}
|
||||
cmd.env("WINEDLLOVERRIDES", hook_dll_overrides(&profile.env));
|
||||
if !profile.wine_prefix.trim().is_empty() {
|
||||
cmd.env("WINEPREFIX", &profile.wine_prefix);
|
||||
}
|
||||
@@ -93,6 +95,30 @@ pub fn launch(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The `WINEDLLOVERRIDES` value the game must be started with.
|
||||
///
|
||||
/// The hook ships as a `version.dll` proxy inside the game directory, and Proton
|
||||
/// prefers a local DLL over its own builtin ONLY when `WINEDLLOVERRIDES` names it
|
||||
/// (see `setup::STEAM_LAUNCH_OPTIONS`). Steam users get that from their launch
|
||||
/// options; when the launcher spawns the runner itself, nothing else supplies it.
|
||||
///
|
||||
/// Without it the failure is silent and badly misleading: the hook never loads, so
|
||||
/// the `openfut.cfg` the launcher just wrote is inert, the game ignores the
|
||||
/// configured Blaze ports, and `/etc/hosts` quietly routes it to whatever answers
|
||||
/// on EA's real ports. It looks like a working launch against the configured
|
||||
/// server while actually talking to a different one.
|
||||
///
|
||||
/// A profile that already pins `version=` wins: an operator overriding the hijack
|
||||
/// deliberately must not be silently overruled.
|
||||
fn hook_dll_overrides(env: &BTreeMap<String, String>) -> String {
|
||||
const HOOK: &str = "version=n,b";
|
||||
match env.get("WINEDLLOVERRIDES").map(|v| v.trim()) {
|
||||
Some(existing) if existing.contains("version=") => existing.to_string(),
|
||||
Some(existing) if !existing.is_empty() => format!("{existing};{HOOK}"),
|
||||
_ => HOOK.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the Wine prefix's `dosdevices` entries the profile asks for.
|
||||
///
|
||||
/// Equivalent to `mkdir -p $WINEPREFIX/dosdevices && ln -sfn <target> <link>`:
|
||||
@@ -463,4 +489,32 @@ mod tests {
|
||||
let err = launch(&profile, &log(), || {}).unwrap_err().to_string();
|
||||
assert!(err.contains("game_dir does not exist"), "{err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_profile_without_overrides_still_gets_the_hook_hijack() {
|
||||
// The regression this guards: FIFA launched from the launcher ignored the
|
||||
// configured Blaze ports entirely, because Proton loaded its own builtin
|
||||
// version.dll and the hook proxy never ran. The launch looked healthy.
|
||||
assert_eq!(hook_dll_overrides(&BTreeMap::new()), "version=n,b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unrelated_overrides_are_preserved_and_appended_to() {
|
||||
let env = BTreeMap::from([("WINEDLLOVERRIDES".to_string(), "d3d11=n".to_string())]);
|
||||
assert_eq!(hook_dll_overrides(&env), "d3d11=n;version=n,b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_explicit_version_override_is_never_overruled() {
|
||||
// An operator disabling the hijack on purpose must win, otherwise the
|
||||
// setting is a lie.
|
||||
let env = BTreeMap::from([("WINEDLLOVERRIDES".to_string(), "version=b".to_string())]);
|
||||
assert_eq!(hook_dll_overrides(&env), "version=b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_blank_override_is_treated_as_absent_rather_than_appended_to() {
|
||||
let env = BTreeMap::from([("WINEDLLOVERRIDES".to_string(), " ".to_string())]);
|
||||
assert_eq!(hook_dll_overrides(&env), "version=n,b");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user