Commit graph

8 commits

Author SHA1 Message Date
MiTHRAL
3016f14fe8 netcode-revival: fix the live-flag address + force the live-user cache flags
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
The live-flag address was wrong: sub_8263E788's lis r11,-32003 gives
r11 = -2097348608 = 0x82FD0000 (recompiler value + 2^32), so the flag is at
0x82FC8851, not 0x83028851 (an arithmetic slip mis-multiplied 0x82FD0000).
We were forcing/reading an unrelated mapped byte, so the gate never saw the
forced value. Also force the game's cached 'live user exists' flags the
frontend online-access controllers check: 0x8308396C (14700) and 0x83084690
(18064).
2026-08-28 22:08:51 -04:00
MiTHRAL
7b9d706f79 netcode-revival: expose gate-status diagnostics for the Party Play frontend gate
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
2026-08-28 21:37:37 -04:00
MiTHRAL
e09f224a6b netcode-revival: answer Xam user shims for every slot + live flag = user 0
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
The game's 'Party Play' gate treats its internal live flag (0x83028851) as a
USER INDEX, then checks XamUserGetSigninState(idx) and XamUserGetSigninInfo
(idx). rexglue only answered user 0, so the predicate failed and the option
stayed greyed out (no rexglue API is even reached on click). Now:

- XamUserGetSigninState/GetSigninInfo/GetXUID/GetName/GetGamerTag/
  GetMembershipTier accept any slot < 4 and return the single profile
  (signed-in, live, Gold).
- ForceLiveFlag writes 0 (the profile's real slot) instead of 1, since the
  flag is a user index; slot 0 is safe for every index-into-live-array read.
2026-08-28 14:52:17 -04:00
MiTHRAL
73d8f36af2 netcode-revival: XNetTransport::ForceLiveFlag - force the game's live-user static
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
Writes the title's internal 'live user' flag byte (0x83028851, derived from
sub_8263E788's lis -32003 / lbz -30639 = recompiler value -2097348608 ->
0x83030000 - 0x77AF) to 1 so the frontend stops refusing Xbox Live features
before it ever calls a rexglue API. Logs the first force.
2026-08-28 14:32:13 -04:00
MiTHRAL
6fcc96de18 netcode-revival: fix SetRelay deadlock + grant multiplayer privileges
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
- Deadlock: SetRelay held the transport mutex while join()ing the receive
  thread, which needs the mutex to observe running_ and exit. With the 200ms
  recv timeout the thread woke and hit the lock -> a room/server change froze
  the game (every room keystroke reconnects the transport). StopThread now
  detaches the thread under the lock and joins WITHOUT it.
- XamUserCheckPrivilege denied everything, which is the gate the game's
  'create a party' flow checks (multiplayer sessions); grant requested
  privileges so the P2P session flow opens, and log the mask.
2026-08-28 13:52:20 -04:00
MiTHRAL
3ec27d115b netcode-revival: receive timeout on the relay transport socket
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
The Run thread blocked in recvfrom with no SO_RCVTIMEO, so when there was no
inbound game traffic the 4s heartbeat never fired (the relay swept the
silent transport client after ~8s) AND StopLocked()'s join() deadlocked
SetRelay on a room change (hanging the ghost network loop). A 200ms receive
timeout wakes the loop regularly: the heartbeat keeps the transport alive
and shutdown/room-change joins complete promptly.
2026-08-28 13:28:58 -04:00
MiTHRAL
01fe706c13 netcode-revival: pack the relay wire structs + heartbeat + transport logging
- #pragma pack(push,1) on the wire structs (the relay's proto is packed; the
  transport's were not, which would inflate sizes and corrupt every datagram)
  plus static_asserts pinning sizes to 7/31/1410/25/801.
- Heartbeat re-JOIN every 4s so the relay never times the transport out.
- REXLOG info for connect/join/session-reply so the flow is observable.
2026-08-28 02:14:19 -04:00
MiTHRAL
bf3635d7ad netcode-revival: relay transport for the game's netcode (Phase 1b)
Some checks are pending
Lint & Format Check / Format Check (push) Waiting to run
Route the game's own RakNet UDP through the ghost relay so real internet
peers can play, with the server as a pure relay/NAT stabilizer:

- XNetTransport: a rexglue relay client (joins the same relay + room as the
  ghost client), a receive thread, and:
  - SendGame(): wraps a datagram addressed to a virtual 10.80.0.x peer in a
    relay Game payload and sends it OUTBOUND to the relay (no inbound
    reachability / port forwarding needed).
  - QuerySessions()/Sessions(): discovery - the room members that
    XNetQosLookup reports to the game's session search.
  - Receive injection: relayed Game payloads are pushed into the game's
    registered sockets via XSocket::QueuePacket.
- XSocket: SendTo() to a virtual address routes through the transport;
  RecvFrom() drains queued relayed packets first; sockets register with the
  transport on Initialize.
- XNetQosLookup: queries the relay and returns the room's members as
  discovered sessions (with their virtual addresses), signaling completion.
- XNetGetTitleXnAddr identity now shares one source of truth with the
  transport (same 10.80.0.x).

Wire structs are minimal copies of the game's ghost protocol (kept
dependency-free); the relay's version check refuses mismatches.
2026-08-28 02:11:24 -04:00