Files
BT412/engine/MUNGA_L4/L4STEAMTRANSPORT.h
T
CydandClaude Fable 5 5ebb9a5906 Net: NetTransport seam + Steam transport (Workstream C.1)
The wire moves behind NetTransport (L4NETTRANSPORT): L4NET.CPP taken
from RP412 post-seam -- all ~24 Winsock call sites route through
NetTransport_Get() -- with BT's 3 BT_NET_TRACE blocks re-sited onto
their code anchors (they read message/packet metadata, not sockets, so
no collision). Default WinsockNetTransport = the arcade/LAN TCP wire.

SteamNetTransport (L4STEAMTRANSPORT, ISteamNetworkingSockets + FakeIP/
SDR) compiles under option(BT412_STEAM) (default OFF); Steamworks SDK
1.64 vendored at extern/steamworks_sdk_164. steam_appid.txt gitignored
(Spacewar 480 by hand until a real AppID). Ported gConsoleLossEndsMission
from RP412's APPMGR (default False = arcade re-listen).

Verified: default TCP build passes full loopback MP through the seam
(console -> egg msgID-3 chunks -> mesh complete -> both instances tick,
net-tx/net-rx traces fire through NetTransport_Get()); BT412_STEAM=ON
compiles + links against the SDK + boots solo. Live Steam session
deferred to Phase 6. (Phase 4 of docs/BT412-ROADMAP.md)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 08:33:34 -05:00

98 lines
4.6 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 BT412_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 BT412_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 + SteamID here
// before anything dials out. The SteamID matters on accept: Steam
// reports incoming callers under locally-allocated alias addresses,
// so the transport maps the caller's identity back to the global
// FakeIP the egg promised. Registering is idempotent per IP.
void
SteamNetTransport_RegisterPeer(
const char *fake_ip,
int fake_console_port,
int fake_game_port,
unsigned __int64 steam_id
);
#endif // BT412_STEAM