ValveSoftware / halflife

Half-Life 1 engine based games
Other
3.72k stars 624 forks source link

[MP games] make it possible to create online servers from home without port forwarding #2658

Open CS-PRO1 opened 5 years ago

CS-PRO1 commented 5 years ago

Simply as per title. Sven Co-op added this feature in v5.19 and explained in this article: https://steamcommunity.com/sharedfiles/filedetails/?id=1705149010 Would be very cool if this was implemented in vanilla Goldsrc titles as well!

SamVanheer commented 5 years ago

This is the P2P networking interface that Steam provides: https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/public/steam/isteamnetworking.h

Based on their description it sounds like they're directing all traffic through the P2P interface when connected this way, so it's probably an abstraction over the socket API used by the engine, meaning most of the engine's code is the same but the code that reads and writes the actual packets will be directed to either the platform-specific API or the ISteamNetworking API.

Quake 2's NetChan code is a good reference: https://github.com/id-Software/Quake-2/blob/372afde46e7defc9dd2d719a1732b8ace1fa096e/win32/net_wins.c#L386-L456

This is where packets are actually sent on Windows, so an alternate implementation would call ISteamNetworking::SendP2PPacket here, though the packet data will likely need to be split up if it exceeds the API's maximum size (1200 bytes according to the documentation) since some calls will exceed this.

CL_ClientDllQuery for instance will allow the client to send data as large as 2048 bytes.

An easy way to implement this is to create a C-style interface struct (struct of function pointers) that points either to the native socket API or the ISteamNetworking API, then initializing it when receiving the first packet when setting up the client_t instance.

Given that NET_SendPacket takes a netadr_t a way to map that to the Steam id will be needed when sending packets with this API. Either a lot of refactoring is needed there (unfeasible) or a global map used by the interface implementation.

Also, you might want to change the title to use the term port forwarding, since fast forwarding has nothing to do with low-level networking.

kungfulon commented 3 years ago

Not sure if you still need it or not, I wrote something that allow P2P networking on GoldSrc games here: https://github.com/kungfulon/GoldSrcNetworking