Skip to content

Don't reject external LSX connections#42

Draft
p0358 wants to merge 1 commit into
ArmchairDevelopers:masterfrom
p0358:patch-external-lsx
Draft

Don't reject external LSX connections#42
p0358 wants to merge 1 commit into
ArmchairDevelopers:masterfrom
p0358:patch-external-lsx

Conversation

@p0358
Copy link
Copy Markdown

@p0358 p0358 commented Jan 26, 2026

This is a simple change to allow external LSX connections to be accepted. This works, though Maxima doesn't show the player state as in-game and I have no idea how this affects presence.

Why? Because the user might have external WINE prefix with a working game installation (it requires some mods to game), and LSX is just a TCP server. Personally for me launching games with Maxima doesn't seem to work at all currently, so this makes the difference between being able to use it at all or not... (this will work out of the box with Titanfall with my Black Market Edition mod in its next version)

The PR just makes the code not drop the connection if maxima.playing isn't populated, moving the PID grabbing code to conditionally happen only if it is.

INFO - [maxima::lsx::service] - New LSX connection: 127.0.0.1:47146
WARN - [maxima::lsx::connection] - External LSX connection (the game was not started through Maxima)
INFO - [maxima::lsx::request::challenge] - Game Connected - Name: Titanfall, Offer ID: 1011172, Multiplayer Id: 1011172
INFO - [maxima::lsx::request::auth] - Retrieving authorization code for 'TITANFALL'

@p0358 p0358 marked this pull request as draft January 28, 2026 23:41
@p0358
Copy link
Copy Markdown
Author

p0358 commented Jan 28, 2026

Changed to draft, since it still has some issues:

INFO - [maxima::lsx::request::profile] - Setting Presence to Joinable: Private lobby

thread 'tokio-runtime-worker' (773397) panicked at maxima-lib/src/lsx/request/profile.rs:93:45:
called `Option::unwrap()` on a `None` value

Some changes will be needed, so that the offer id of a given connection can be retrieved.

AA-EION added a commit to AA-EION/Maxima-Draconis that referenced this pull request May 15, 2026
* fix: console visibility, NSIS registry view, and external LSX connections (#3)

Four independent bugs that combined to make Maxima invisible on TF2 launch
in v0.2.1, plus a fifth that prevented Northstar online play.

== maxima-cli/src/main.rs + Cargo.toml ==

Rewrote the startup prologue so each step happens in the right order:

1. Panic hook installed first — any subsequent crash writes to
   %LOCALAPPDATA%\Maxima\Logs\maxima-cli.panic.log before the process
   exits, giving a durable record even when no console is attached yet.

2. ensure_console_attached() now also rewires STD_OUTPUT_HANDLE /
   STD_ERROR_HANDLE / STD_INPUT_HANDLE to CONOUT$/CONIN$ via SetStdHandle
   after AllocConsole. Without this, the v0.2.1 console window opened but
   stayed blank: Rust's println! was still writing to the invalid handles
   inherited from maxima-bootstrap (a GUI-subsystem parent with no stdio).
   Added winapi features: processenv, fileapi, winbase, winnt.

3. main() is now a plain fn (no #[tokio::main]) that builds the tokio
   runtime manually with Runtime::new().block_on(startup(args)). Previously
   #[tokio::main] constructed the runtime before user code ran, so a panic
   in IOCP/thread-pool init under Wine would kill the process before
   AllocConsole or the logger ever executed.

4. init_logger_named() is called before Args::parse(). If clap exits on a
   bad argv it writes to stderr — which was the unattached pipe. Logger
   first means clap errors hit the file sink.

== maxima-bootstrap/src/main.rs ==

Log the exit code of maxima-cli to maxima_execution.log when it exits
non-zero. Previously bootstrap returned Ok(true) / "Result: Success"
regardless of whether the child succeeded, making failures invisible in
the one log file users are directed to check.

== installer/maxima-setup.nsi ==

SetRegView 64 was set at line ~173 for HKLM WOW6432Node writes and never
reset. The HKCR protocol-handler BackupProtocol calls and WriteRegStr ops
that followed inherited view 64. On a 32-bit NSIS installer the default
view is 32-bit; so v0.2.0 wrote HKCR\link2ea (etc.) under the 32-bit
view. v0.2.1 wrote them under the 64-bit view. 32-bit Wine consumers
(Titanfall2.exe, origin2:// emitters) resolve HKCR via the 32-bit view
and saw the stale v0.2.0 entries or nothing — link2ea:// was never
dispatched to maxima-bootstrap, so nothing appeared on launch.

Fixes:
- SetRegView default before BackupProtocol calls and before HKCR writes.
- SetRegView default inside RestoreProtocol so uninstaller targets the
  same store.
- Upgrade guard in BackupProtocol: if HKLM\Software\Maxima\InstallPath
  already exists (prior Maxima install), skip the backup phase. This
  prevents an upgrade from overwriting the original pre-Maxima EA handler
  backup with Maxima's own values, which would cause the uninstaller to
  "restore" a deleted binary.
- Same guard via BackupValueUpgradeSafe for the two HKLM BackupValue calls
  (Origin\ClientPath, EA Desktop\InstallSuccessful).

== maxima-lib/src/lsx/connection.rs + profile.rs ==

Port of catornot/Maxima@patch-external-lsx (upstream PR ArmchairDevelopers#42 by p0358).

When Northstar is launched via Steam (steam.exe -applaunch 1237970
-northstar), the game starts without going through maxima-cli launch, so
maxima.playing() is None when TF2's LSX module connects back to Maxima's
TCP server. The old code shut the socket immediately and returned
LSXConnectionError::GameContext — no LSX, no auth ticket, no online play.

connection.rs: instead of dropping the connection when playing() is None,
log a warning and continue. The PID/Kyber path only executes when a
context exists.

profile.rs: handle_set_presence_request unwrapped playing() unconditionally
(line 93), panicking on external connections. Replace .unwrap() with a
let-else that returns a harmless success response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Northstar setup guide and credit catornot

Add a dedicated "Northstar online play" section to the README explaining:
- Launch via Steam (-northstar flag), not NorthstarLauncher.exe
- Required launch args: -noOriginStartup -multiple -northstar
  (identified by catornot; without -noOriginStartup Northstar hangs
  trying to start Origin in Wine)
- Reference to catornot/flightcore-ng for the source

Credit catornot in the Upstream section for the external LSX connection
patch and the launch argument discovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: apply Gemini review suggestions from PR #3

Three suggestions from the automated review, all accepted:

1. maxima-bootstrap (link2ea + origin2): replace manual log + Ok(true) on
   non-zero maxima-cli exit with a proper Err return. handle_launch_args
   already routes any Err from run() to maxima_execution.log and
   maxima_bootstrap_error.log, so the manual writes were redundant. Returning
   Err also makes failures visible as errors in the log instead of "Success".

2. maxima-lib/lsx/connection.rs: replace the if-let-Err / else-if-unwrap
   pattern on the pid Result with a single idiomatic match &pid { ... }.
   Avoids the technically-safe-but-stylistically-poor .unwrap().

No behavior change for the happy path; non-zero maxima-cli exits now
propagate as errors instead of being swallowed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: AA-EION <contactus@eionstudios.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant