Files
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

127 lines
4.1 KiB
C++

//===========================================================================//
// File: l4nettransport.h //
// Project: MUNGA Brick: Network Transport Seam //
// Contents: The wire interface under the network manager //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "..\munga\style.h"
#include <Winsock2.h>
//########################################################################
// NetTransport - the seam between the network manager's mesh/console
// logic and the wire (see context/steamification.md). Mirrors
// the RIOBase pattern: L4NET keeps hosts, message queues, and the
// deterministic mesh ordering; only connect/listen/send/recv live
// behind this interface.
//
// Implementations:
// WinsockNetTransport (l4nettransport.cpp) - TCP; the arcade/LAN wire
// SteamNetTransport (future) - ISteamNetworkingSockets
// P2P over SDR
//
// Addresses stay SOCKADDR_IN-shaped on purpose: Steam's FakeIP system
// hands out fake IPv4 addresses for exactly this kind of engine, so
// the [pilots] list keeps working as ip[:port] strings in both worlds.
//########################################################################
class NetTransport
{
public:
// Opaque connection handle. SOCKET for Winsock (SOCKET is UINT_PTR),
// HSteamNetConnection for Steam - both fit; callers must not
// interpret it.
typedef UINT_PTR Connection;
static const Connection InvalidConnection = (Connection) ~0; // == INVALID_SOCKET
// Receive() results when no payload came back
enum
{
ReceiveDisconnected = 0, // orderly close or connection reset
ReceiveNoData = -1 // nothing pending (connections are nonblocking)
};
virtual ~NetTransport()
{
}
//---------------------------------------------------------------
// Lifecycle
//---------------------------------------------------------------
virtual Logical
Startup() = 0;
virtual void
Cleanup() = 0;
//---------------------------------------------------------------
// Addressing: the local interface list (the mesh identifies
// "which [pilots] entry is me" against it) and numeric ip[:port]
// parsing. Port 0 in the result means "caller applies default".
//---------------------------------------------------------------
virtual int
GetLocalAddresses(
unsigned long *addresses,
int max_count
) = 0;
virtual Logical
Resolve(
const char *host_name,
SOCKADDR_IN *address
) = 0;
//---------------------------------------------------------------
// Connections (the deterministic mesh + the console channel).
// Connect blocks until the remote end accepts (the mesh relies
// on retry-until-up ordering), then goes nonblocking. Listeners
// are nonblocking from the start; Accept polls one.
//---------------------------------------------------------------
virtual Connection
Connect(
const SOCKADDR_IN *remote,
int local_port
) = 0;
virtual Connection
Listen(
int local_port,
int backlog
) = 0;
virtual Connection
Accept(Connection listener) = 0;
virtual void
Close(Connection connection) = 0;
//---------------------------------------------------------------
// Data plane (nonblocking)
//---------------------------------------------------------------
virtual int
Send(
Connection connection,
const void *data,
int size
) = 0;
virtual int
Receive(
Connection connection,
void *buffer,
int size
) = 0;
// remote endpoint of a live connection (mesh identity checks)
virtual Logical
GetRemoteAddress(
Connection connection,
SOCKADDR_IN *address
) = 0;
};
// The process-wide transport. Defaults to Winsock TCP; a Steam build
// installs its transport BEFORE the network manager comes up.
NetTransport *
NetTransport_Get();
void
NetTransport_Set(NetTransport *transport);