Files
RP412/MUNGA_L4/L4STEAMTRANSPORT.h
T
CydandClaude Fable 5 5892af318e Steam lobby: host, join, room, and launch into a marshaled race
RPL4LOBBY implements the multiplayer front door on ISteamMatchmaking.
The setup menu grows HOST STEAM RACE / JOIN STEAM RACE buttons when
the Steam wire is live; hosting creates a tagged public lobby, joining
finds one. Every member publishes FakeIP + fake ports + persona +
loadout as member data; the room screen lists members (host marked)
and gives the owner a launch button.

Launching writes a nonced go-roster into lobby data. Each pod
registers every peer with the Steam transport (two-port peer table:
engine console/game ports map to Steam fake ports on connect) and
enters the race: the owner through the hosted-race path - it builds
the multi-pilot egg from real personas and loadouts and its console
marshals everyone - and members as network pods that boot straight
into WaitingForEgg for the owner to feed over the wire.

The lobby outlives races: members loop back through WinMain into the
room (no local console needed - MissionCompleted is waived for member
races), and the owner returns to the room after its results screen.
Leaving the lobby clears the hosted-race priming.

Verified on this box: menu buttons appear under RP412STEAM=1, hosting
creates a lobby on the Steam backend, the room runs and leaves back to
the menu; single-player cycling and the LAN hosted race both still
pass. Full three-account mesh test is next, on real hardware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 21:26:31 -05:00

94 lines
4.3 KiB
C

//===========================================================================//
// File: l4steamtransport.h //
// Project: MUNGA Brick: Steam Network Transport //
// Contents: NetTransport over ISteamNetworkingSockets (FakeIP) //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "..\munga\style.h"
//########################################################################
// SteamNetTransport - the retail wire (l4steamtransport.cpp). Built
// only under RP412_STEAM (Steamworks SDK vendored at
// extern\steamworks_sdk_164; steam_api.dll ships beside the exe).
//
// Method mapping onto ISteamNetworkingSockets:
//
// Install SteamAPI_Init + InitRelayNetworkAccess, then
// BeginAsyncRequestFakeIP(2): fake port 0 is the
// console channel, fake port 1 the game mesh.
// On success installs itself via NetTransport_Set;
// on any failure the process stays on Winsock TCP.
// GetLocalAddresses our FakeIP (the mesh identifies "which [pilots]
// entry is me" against it).
// Resolve SteamNetworkingIPAddr::ParseString - FakeIPs ARE
// IPv4 strings, so egg text stays unchanged.
// Connect ConnectByIPAddress to the peer's FakeIP + fake
// game port (SDR routes it; NAT traversal and IP
// privacy come free); blocks pumping callbacks
// until Connected, retrying like the TCP
// connect-while-refused loop.
// Listen CreateListenSocketP2PFakeIP - first engine port
// seen maps to fake port 0, second to fake port 1.
// Accept connection-request callback AcceptConnections
// queue up; Accept() pops fully-connected ones.
// Send SendMessageToConnection, reliable lane (the
// engine's stream framing assumes ordered
// reliable delivery).
// Receive ReceiveMessagesOnConnection into the caller's
// buffer; normalized to ReceiveNoData /
// ReceiveDisconnected like the Winsock transport.
// GetRemoteAddress GetRemoteFakeIPForConnection, with the fake
// port translated back to the ENGINE port so the
// mesh's SOCKADDR_IN identity checks keep working.
//
// Addressing convention under Steam: every pod launches with the same
// -net port (the lobby fixes it), so the egg's [pilots] entries are
// "<fakeip>:<engine game port>" - the engine's self-match and peer
// checks all work on engine ports, and only this transport knows the
// Steam-assigned fake port values. The lobby layer exchanges each
// member's FakeIP + fake game port and feeds RegisterPeer before the
// egg is distributed.
//########################################################################
#ifdef RP412_STEAM
// Bring Steam up and make this the process transport. False (with the
// reason logged) leaves the Winsock transport in place - callers just
// carry on over TCP.
Logical
SteamNetTransport_Install();
// Our FakeIP as a dotted string ("169.254.x.y"), for lobby member data
// and the [pilots] list. Empty until Install succeeds.
const char *
SteamNetTransport_GetFakeAddressString();
// Our Steam-assigned fake ports (lobby member data): the console
// channel and the game mesh.
int
SteamNetTransport_GetFakeConsolePort();
int
SteamNetTransport_GetFakeGamePort();
// The engine-side port convention for this session (default 1501;
// game port is +1). Connect() maps an engine port in a SOCKADDR_IN to
// the peer's matching Steam fake port.
void
SteamNetTransport_SetEnginePorts(int console_port);
// The lobby feeds every member's FakeIP + fake ports here before
// anything dials out. Registering is idempotent per IP.
void
SteamNetTransport_RegisterPeer(
const char *fake_ip,
int fake_console_port,
int fake_game_port
);
#endif // RP412_STEAM