fix(launcher): run LSX locally on Windows (only autopatch is in-process)

The prior Windows branch treated BOTH companions as in-process and started
neither. That is wrong for LSX: FIFA dials the Origin/LSX emulator on
127.0.0.1:4216 and it must run locally on the client (the STEAMPUNKS
stp-origin_emu.dll is the crack's activation emu, not OpenFUT's LSX). Only
autopatch is genuinely in-process on Windows (its ProtoSSL cert patch is done by
the version.dll hook), so skip just that one and spawn LSX through the normal
path. Also resolve the companion as openfut-lsx.exe on Windows.
This commit is contained in:
funman300
2026-08-20 19:57:16 +00:00
parent cf515f5584
commit 966e92b304
+17 -15
View File
@@ -80,12 +80,18 @@ impl Service {
/// keeps `spawn` responsible for reporting a missing binary, with one error message
/// instead of two.
fn resolve_binary(service: Service) -> PathBuf {
let name = service.binary();
let base = service.binary();
// On Windows the built companion is `openfut-lsx.exe`; a bare name without the
// extension matches neither the sibling file nor CreateProcess resolution.
#[cfg(windows)]
let name = format!("{base}.exe");
#[cfg(unix)]
let name = base.to_string();
if let Some(dir) = std::env::current_exe()
.ok()
.and_then(|p| p.parent().map(Path::to_path_buf))
{
let sibling = dir.join(name);
let sibling = dir.join(&name);
if sibling.is_file() {
return sibling;
}
@@ -434,21 +440,18 @@ impl ServiceSupervisor {
/// Start `service` only if it is not already usable. Never restarts a healthy
/// service, and never adopts a foreign one as ours.
pub fn ensure_running(&mut self, service: Service, spec: SpawnSpec) -> Result<Ensured, String> {
// On native Windows the "companion services" are NOT separate processes:
// LSX/Origin login and the ProtoSSL cert path are provided in-process by
// stp-origin_emu.dll and the version.dll hook once the game runs. There is
// nothing for the launcher to spawn or supervise, so report ready.
// On Windows the ProtoSSL cert-verify patch (autopatch's job on unix, via
// /proc/PID/mem) is performed in-process by the version.dll hook, so there
// is no autopatch process to run. LSX is different: the game dials it on
// 127.0.0.1:4216, so it MUST run locally here exactly as on unix.
#[cfg(windows)]
{
let _ = spec;
self.log.lock().push(format!(
"[launcher] {} is in-process on Windows (stp/hook) — nothing to start.",
service.label()
));
if service == Service::Autopatch {
self.log.lock().push(
"[launcher] autopatch runs in-process on Windows (version.dll hook) — nothing to start."
.to_string(),
);
return Ok(Ensured::Reused);
}
#[cfg(unix)]
{
let runtime = self.observe(service);
if runtime.ready() {
self.log.lock().push(format!(
@@ -476,7 +479,6 @@ impl ServiceSupervisor {
.map_err(|e| e.to_string())?;
*self.slot(service) = ManagedService::from_child(child);
Ok(Ensured::Started)
}
}
/// Stop a service the launcher owns. A foreign process is reported, never