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>
127 lines
4.1 KiB
C++
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);
|