summaryrefslogtreecommitdiff
path: root/public/steamnetworkingsockets
diff options
context:
space:
mode:
Diffstat (limited to 'public/steamnetworkingsockets')
-rw-r--r--public/steamnetworkingsockets/isteamnetworkingsockets.h330
-rw-r--r--public/steamnetworkingsockets/isteamnetworkingutils.h125
-rw-r--r--public/steamnetworkingsockets/steamdatagram_stats.h298
-rw-r--r--public/steamnetworkingsockets/steamdatagram_ticketgen.h60
-rw-r--r--public/steamnetworkingsockets/steamdatagram_tickets.h151
-rw-r--r--public/steamnetworkingsockets/steamnetworkingtypes.h641
6 files changed, 1605 insertions, 0 deletions
diff --git a/public/steamnetworkingsockets/isteamnetworkingsockets.h b/public/steamnetworkingsockets/isteamnetworkingsockets.h
new file mode 100644
index 0000000..b2d83ab
--- /dev/null
+++ b/public/steamnetworkingsockets/isteamnetworkingsockets.h
@@ -0,0 +1,330 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Purpose: A low level API similar to Berkeley socket, to send messages
+// between hosts over the Steam network and addressed using Steam IDs.
+//
+//=============================================================================
+
+#ifndef ISTEAMNETWORKINGSOCKETS
+#define ISTEAMNETWORKINGSOCKETS
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "steamnetworkingtypes.h"
+
+// #KLUDGE! This is so we don't have to link with steam_api.lib
+#include <steam/steam_api.h>
+#include <steam/steam_gameserver.h>
+
+//-----------------------------------------------------------------------------
+/// Lower level networking interface that more closely mirrors the standard
+/// Berkeley sockets model. Sockets are hard! You should probably only use
+/// this interface under the existing circumstances:
+///
+/// - You have an existing socket-based codebase you want to port, or coexist with.
+/// - You want to be able to connect based on IP address, rather than (just) Steam ID.
+/// - You need low-level control of bandwidth utilization, when to drop packets, etc.
+///
+/// Note that neither of the terms "connection" and "socket" will correspond
+/// one-to-one with an underlying UDP socket. An attempt has been made to
+/// keep the semantics as similar to the standard socket model when appropriate,
+/// but some deviations do exist.
+class ISteamSocketNetworking
+{
+public:
+
+ /// Creates a "server" socket that listens for clients to connect to, either by calling
+ /// ConnectSocketBySteamID or ConnectSocketByIPv4Address.
+ ///
+ /// nSteamConnectVirtualPort specifies how clients can connect to this socket using
+ /// ConnectBySteamID. A negative value indicates that this functionality is
+ /// disabled and clients must connect by IP address. It's very common for applications
+ /// to only have one listening socket; in that case, use zero. If you need to open
+ /// multiple listen sockets and have clients be able to connect to one or the other, then
+ /// nSteamConnectVirtualPort should be a small integer constant unique to each listen socket
+ /// you create.
+ ///
+ /// If you want clients to connect to you by your IPv4 addresses using
+ /// ConnectByIPv4Address, then you must set nPort to be nonzero. Steam will
+ /// bind a UDP socket to the specified local port, and clients will send packets using
+ /// ordinary IP routing. It's up to you to take care of NAT, protecting your server
+ /// from DoS, etc. If you don't need clients to connect to you by IP, then set nPort=0.
+ /// Use nIP if you wish to bind to a particular local interface. Typically you will use 0,
+ /// which means to listen on all interfaces, and accept the default outbound IP address.
+ /// If nPort is zero, then nIP must also be zero.
+ ///
+ /// A SocketStatusCallback_t callback when another client attempts a connection.
+ virtual HSteamListenSocket CreateListenSocket( int nSteamConnectVirtualPort, uint32 nIP, uint16 nPort ) = 0;
+
+ /// Creates a connection and begins talking to a remote destination. The remote host
+ /// must be listening with the appropriate call to CreateListenSocket.
+ ///
+ /// Use ConnectBySteamID to connect using the SteamID (client or game server) as the network address.
+ /// Use ConnectByIPv4Address to connect by IP address.
+ ///
+ /// On success, a SocketStatusCallback_t callback is triggered.
+ /// On failure or timeout, a SocketStatusCallback_t callback with a failure code in m_eSNetSocketState
+ virtual HSteamNetConnection ConnectBySteamID( CSteamID steamIDTarget, int nVirtualPort, int nTimeoutSec ) = 0;
+ virtual HSteamNetConnection ConnectByIPv4Address( uint32 nIP, uint16 nPort, int nTimeoutSec ) = 0;
+
+ /// Accept an incoming connection that has been received on a listen socket.
+ ///
+ /// When a connection attempt is received (perhaps after a few basic handshake
+ /// packets have been exchanged to prevent trivial spoofing), a connection interface
+ /// object is created in the k_ESteamNetworkingConnectionState_Connecting state
+ /// and a SteamNetConnectionStatusChangedCallback_t is posted. At this point, your
+ /// application MUST either accept or close the connection. (It may not ignore it.)
+ /// Accepting the connection will transition it into the connected state.
+ ///
+ /// You should take action within a few seconds, because accepting the connection is
+ /// what actually sends the reply notifying the client that they are connected. If you
+ /// delay taking action, from the client's perspective it is the same as the network
+ /// being unresponsive, and the client may timeout the connection attempt. In other
+ /// words, the client cannot distinguish between a delay caused by network problems
+ /// and a delay caused by the application.
+ ///
+ /// This means that if your application goes for more than a few seconds without
+ /// processing callbacks, then there is a chance that a client may attempt to connect
+ /// in that interval, and timeout.
+ ///
+ /// If the application does not respond to the connection attempt in a timely manner,
+ /// and we stop receiving communication from the client, the connection attempt will
+ /// be timed out locally, transitioning the connection to the
+ /// k_ESteamNetworkingConnectionState_ProblemDetectedLocally state. The client may also
+ /// close the connection before it is accepted and a transition to the
+ /// k_ESteamNetworkingConnectionState_ClosedByPeer is also possible.
+ ///
+ /// Returns k_EResultInvalidParam if the handle is invalid.
+ /// Returns k_EResultInvalidState if the connection is not in the appropriate state.
+ /// (Remember that the connection state could change in between the time that the
+ /// notification being posted to the queue and when it is received by the application.)
+ virtual EResult AcceptConnection( HSteamNetConnection hConn ) = 0;
+
+ /// Disconnects from the remote host and invalidates the connection handle.
+ /// Any unread data on the connection is discarded.
+ ///
+ /// nReason is an application defined code that will be received on the other
+ /// end and recorded (when possible) in backend analytics. The value should
+ /// come from a restricted range. (See ESteamNetConnectionEnd.) If you don't need
+ /// to communicate any information to the remote host, and do not want analytics to
+ /// be able to distinguish "normal" connection terminations from "exceptional" ones,
+ /// You may pass zero, in which case the generic value of
+ /// k_ESteamNetConnectionEnd_App_Generic will be used.
+ ///
+ /// pszDebug is an optional human-readable diagnostic string that will be received
+ /// by the remote host and recorded (when possible) in backend analytics.
+ ///
+ /// If you wish to put the socket into a "linger" state, where an attempt is made to
+ /// flush any remaining sent data, use bEnableLinger=true. Otherwise reliable data
+ /// is not flushed.
+ ///
+ /// If the connection has already ended and you are just freeing up the
+ /// connection interface, the reason code, debug string, and linger flag are
+ /// ignored.
+ virtual bool CloseConnection( HSteamNetConnection hPeer, int nReason, const char *pszDebug, bool bEnableLinger ) = 0;
+
+ /// Destroy a listen socket, and all the client sockets generated by accepting connections
+ /// on the listen socket.
+ ///
+ /// pszNotifyRemoteReason determines what cleanup actions are performed on the client
+ /// sockets being destroyed. (See DestroySocket for more details.)
+ ///
+ /// Note that if cleanup is requested and you have requested the listen socket bound to a
+ /// particular local port to facilitate direct UDP/IPv4 connections, then the underlying UDP
+ /// socket must remain open until all clients have been cleaned up.
+ virtual bool CloseListenSocket( HSteamListenSocket hSocket, const char *pszNotifyRemoteReason ) = 0;
+
+ /// Set connection user data. Returns false if the handle is invalid.
+ virtual bool SetConnectionUserData( HSteamNetConnection hPeer, int64 nUserData ) = 0;
+
+ /// Fetch connection user data. Returns -1 if handle is invalid
+ /// or if you haven't set any userdata on the connection.
+ virtual int64 GetConnectionUserData( HSteamNetConnection hPeer ) = 0;
+
+ /// Set a name for the connection, used mostly for debugging
+ virtual void SetConnectionName( HSteamNetConnection hPeer, const char *pszName ) = 0;
+
+ /// Fetch connection user data. Returns -1 if handle is invalid
+ /// or if you haven't set any userdata on the connection.
+ virtual void GetConnectionName( HSteamNetConnection hPeer, char *ppszName, int nMaxLen ) = 0;
+
+ /// Send a message to the remote host on the connected socket.
+ ///
+ /// eSendType determines the delivery guarantees that will be provided,
+ /// when data should be buffered, etc.
+ ///
+ /// Note that the semantics we use for messages are not precisely
+ /// the same as the semantics of a standard "stream" socket.
+ /// (SOCK_STREAM) For an ordinary stream socket, the boundaries
+ /// between chunks are not considered relevant, and the sizes of
+ /// the chunks of data written will not necessarily match up to
+ /// the sizes of the chunks that are returned by the reads on
+ /// the other end. The remote host might read a partial chunk,
+ /// or chunks might be coalesced. For the message semantics
+ /// used here, however, the sizes WILL match. Each send call
+ /// will match a successful read call on the remote host
+ /// one-for-one. If you are porting existing stream-oriented
+ /// code to the semantics of reliable messages, your code should
+ /// work the same, since reliable message semantics are more
+ /// strict than stream semantics. The only caveat is related to
+ /// performance: there is per-message overhead to retain the
+ /// messages sizes, and so if your code sends many small chunks
+ /// of data, performance will suffer. Any code based on stream
+ /// sockets that does not write excessively small chunks will
+ /// work without any changes.
+ virtual EResult SendMessageToConnection( HSteamNetConnection hConn, const void *pData, uint32 cbData, ESteamNetworkingSendType eSendType ) = 0;
+
+ /// Fetch the next available message(s) from the socket, if any.
+ /// Returns the number of messages returned into your array, up to nMaxMessages.
+ /// If the connection handle is invalid, -1 is returned.
+ ///
+ /// The order of the messages returned in the array is relevant.
+ /// Reliable messages will be received in the order they were sent (and with the
+ /// same sizes --- see SendMessageToConnection for on this subtle difference from a stream socket).
+ ///
+ /// FIXME - We're still debating the exact set of guarantees for unreliable, so this might change.
+ /// Unreliable messages may not be received. The order of delivery of unreliable messages
+ /// is NOT specified. They may be received out of order with respect to each other or
+ /// reliable messages. They may be received multiple times!
+ ///
+ /// If any messages are returned, you MUST call Release() to each of them free up resources
+ /// after you are done. It is safe to keep the object alive for a little while (put it
+ /// into some queue, etc), and you may call Release() from any thread.
+ virtual int ReceiveMessagesOnConnection( HSteamNetConnection hConn, ISteamNetworkingMessage **ppOutMessages, int nMaxMessages ) = 0;
+
+ /// Same as ReceiveMessagesOnConnection, but will return the next message available
+ /// on any client socket that was accepted through the specified listen socket. Use
+ /// ISteamNetworkingMessage::GetConnection to know which client connection.
+ ///
+ /// Delivery order of messages among different clients is not defined. They may
+ /// be returned in an order different from what they were actually received. (Delivery
+ /// order of messages from the same client is well defined, and thus the order of the
+ /// messages is relevant!)
+ virtual int ReceiveMessagesOnListenSocket( HSteamListenSocket hSocket, ISteamNetworkingMessage **ppOutMessages, int nMaxMessages ) = 0;
+
+ /// Returns information about the specified connection.
+ virtual bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) = 0;
+
+ /// Returns brief set of connection status that you might want to display
+ /// to the user in game.
+ virtual bool GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickConnectionStatus *pStats ) = 0;
+
+ /// Returns detailed connection stats in text format. Useful
+ /// for dumping to a log, etc.
+ ///
+ /// Returns:
+ /// -1 failure (bad connection handle)
+ /// 0 OK, your buffer was filled in and '\0'-terminated
+ /// >0 Your buffer was either nullptr, or it was too small and the text got truncated. Try again with a buffer of at least N bytes.
+ virtual int GetDetailedConnectionStatus( HSteamNetConnection hConn, char *pszBuf, int cbBuf ) = 0;
+
+ /// Returns information about the listen socket.
+ ///
+ /// *pnIP and *pnPort will be 0 if the socket is set to listen for connections based
+ /// on SteamID only. If your listen socket accepts connections on IPv4, then both
+ /// fields will return nonzero, even if you originally passed a zero IP. However,
+ /// note that the address returned may be a private address (e.g. 10.0.0.x or 192.168.x.x),
+ /// and may not be reachable by a general host on the Internet.
+ virtual bool GetListenSocketInfo( HSteamListenSocket hSocket, uint32 *pnIP, uint16 *pnPort ) = 0;
+
+ //
+ // Special SDR connections involved with servers hosted in Valve data centers
+ //
+ virtual bool SetHostedDedicatedServerCertificate( const void *pCert, int cbCert, void *pPrivateKey, int cbPrivateKey ) = 0;
+ virtual HSteamListenSocket CreateHostedDedicatedServerListenSocket( uint16 nPort ) = 0;
+ virtual HSteamNetConnection ConnectToHostedDedicatedServer( CSteamID steamIDTarget ) = 0;
+
+ //
+ // Gets some debug text from the connection
+ //
+ virtual bool GetConnectionDebugText( HSteamNetConnection hConn, char *pOut, int nOutCCH ) = 0;
+
+ //
+ // Set and get configuration values, see ESteamNetworkingConfigurationValue for individual descriptions.
+ //
+ // Returns the value or -1 is eConfigValue is invalid
+ virtual int32 GetConfigurationValue( ESteamNetworkingConfigurationValue eConfigValue ) = 0;
+ // Returns true if successfully set
+ virtual bool SetConfigurationValue( ESteamNetworkingConfigurationValue eConfigValue, int32 nValue ) = 0;
+
+ // Return the name of an int configuration value, or NULL if config value isn't known
+ virtual const char *GetConfigurationValueName( ESteamNetworkingConfigurationValue eConfigValue ) = 0;
+
+ //
+ // Set and get configuration strings, see ESteamNetworkingConfigurationString for individual descriptions.
+ //
+ // Get the configuration string, returns length of string needed if pDest is nullpr or destSize is 0
+ // returns -1 if the eConfigValue is invalid
+ virtual int32 GetConfigurationString( ESteamNetworkingConfigurationString eConfigString, char *pDest, int32 destSize ) = 0;
+ virtual bool SetConfigurationString( ESteamNetworkingConfigurationString eConfigString, const char *pString ) = 0;
+
+ // Return the name of a string configuration value, or NULL if config value isn't known
+ virtual const char *GetConfigurationStringName( ESteamNetworkingConfigurationString eConfigString ) = 0;
+
+};
+#define STEAMSOCKETNETWORKING_VERSION "SteamSocketNetworking001"
+
+// Notification struct used to notify when a connection has changed state
+struct SteamNetConnectionStatusChangedCallback_t
+{
+ HSteamNetConnection m_hConn; //< Connection handle
+ SteamNetConnectionInfo_t m_info; //< Full connection info
+ int m_eOldState; //< ESNetSocketState. (Current stats is in m_info)
+};
+
+// Temporary global accessor. This will be moved to steam_api.h
+STEAMDATAGRAMLIB_INTERFACE ISteamSocketNetworking *SteamSocketNetworking();
+
+typedef void * ( S_CALLTYPE *FSteamInternal_CreateInterface )( const char *);
+typedef void ( S_CALLTYPE *FSteamAPI_RegisterCallResult)( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
+typedef void ( S_CALLTYPE *FSteamAPI_UnregisterCallResult)( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
+
+/// !KLUDGE! Glue code that will go away when we move everything into
+/// the ISteamNetwork interfaces
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramClient_Internal_SteamAPIKludge( FSteamAPI_RegisterCallResult fnRegisterCallResult, FSteamAPI_UnregisterCallResult fnUnregisterCallResult );
+STEAMDATAGRAMLIB_INTERFACE bool SteamDatagramClient_Init_Internal( const char *pszCacheDirectory, /* ESteamDatagramPartner */ int ePartner, int iPartnerMask, SteamDatagramErrMsg &errMsg, ISteamClient *pClient, HSteamUser hSteamUser, HSteamPipe hSteamPipe );
+inline bool SteamDatagramClient_Init( const char *pszCacheDirectory, /* ESteamDatagramPartner */ int ePartner, int iPartnerMask, SteamDatagramErrMsg &errMsg )
+{
+ SteamDatagramClient_Internal_SteamAPIKludge( &::SteamAPI_RegisterCallResult, &::SteamAPI_UnregisterCallResult );
+ return SteamDatagramClient_Init_Internal( pszCacheDirectory, ePartner, iPartnerMask, errMsg, ::SteamClient(), ::SteamAPI_GetHSteamUser(), ::SteamAPI_GetHSteamPipe() );
+}
+
+
+/// Shutdown all clients and close all sockets
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramClient_Kill();
+
+/// Initialize the game server interface
+STEAMDATAGRAMLIB_INTERFACE bool SteamDatagramServer_Init_Internal( SteamDatagramErrMsg &errMsg, ISteamClient *pClient, HSteamUser hSteamUser, HSteamPipe hSteamPipe );
+// KLUDGE TF is using an old version of the SDK, which doesn't have this. TF doesn't need this, so just comment it out.
+// We'll need to upgrade the Steamworks SDK if we want to actually use SDR
+//inline bool SteamDatagramServer_Init( SteamDatagramErrMsg &errMsg )
+//{
+// SteamDatagramClient_Internal_SteamAPIKludge( &::SteamAPI_RegisterCallResult, &::SteamAPI_UnregisterCallResult );
+// return SteamDatagramServer_Init_Internal( errMsg, ::SteamGameServerClient(), ::SteamGameServer_GetHSteamUser(), ::SteamGameServer_GetHSteamPipe() );
+//}
+
+/// Shutdown the game server interface
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramServer_Kill( );
+
+// !KLUDGE! Check for connections that have changed status, and post callbacks.
+// This is temporary we can hook this up using the ordinary steam CCallback mechanism
+typedef void (*FSteamNetConnectionStatusChangedCallback)( SteamNetConnectionStatusChangedCallback_t *pInfo );
+STEAMDATAGRAMLIB_INTERFACE void Temp_DispatchsSteamNetConnectionStatusChangedCallbacks( FSteamNetConnectionStatusChangedCallback fnCallback );
+
+enum ESteamDatagramDebugOutputType
+{
+ k_ESteamDatagramDebugOutputType_None,
+ k_ESteamDatagramDebugOutputType_Error,
+ k_ESteamDatagramDebugOutputType_Important, // Nothing is wrong, but this is an important notification
+ k_ESteamDatagramDebugOutputType_Warning,
+ k_ESteamDatagramDebugOutputType_Msg, // Recommended amount
+ k_ESteamDatagramDebugOutputType_Verbose, // Quite a bit
+ k_ESteamDatagramDebugOutputType_Debug, // Practically everything
+};
+
+/// Setup callback for debug output, and the desired verbosity you want.
+typedef void (*FSteamDatagramDebugOutput)( /* ESteamDatagramDebugOutputType */ int nType, const char *pszMsg );
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagram_SetDebugOutputFunction( /* ESteamDatagramDebugOutputType */ int eDetailLevel, FSteamDatagramDebugOutput pfnFunc );
+
+#endif // ISTEAMNETWORKINGSOCKETS
diff --git a/public/steamnetworkingsockets/isteamnetworkingutils.h b/public/steamnetworkingsockets/isteamnetworkingutils.h
new file mode 100644
index 0000000..80190e9
--- /dev/null
+++ b/public/steamnetworkingsockets/isteamnetworkingutils.h
@@ -0,0 +1,125 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Purpose: misc networking utilities
+//
+//=============================================================================
+
+#ifndef ISTEAMNETWORKINGUTILS
+#define ISTEAMNETWORKINGUTILS
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "steamnetworkingtypes.h"
+struct SteamDatagramRelayAuthTicket;
+
+//-----------------------------------------------------------------------------
+/// Misc networking utilities for checking the local networking environment
+/// and estimating pings.
+class ISteamNetworkingUtils
+{
+public:
+
+ /// Fetch current timestamp. These values never go backwards, and
+ /// the initial value is low enough that practically speaking it's
+ /// not necessary to worry about the value wrapping around.
+ virtual SteamNetworkingMicroseconds GetLocalTimestamp() = 0;
+
+ /// Check if the ping data of sufficient recency is available, and if
+ /// it's too old, start refreshing it.
+ ///
+ /// Games that use the ping location information will typically
+ /// want to call this at boot time, to make sure all prerequisites
+ /// are ready. Especially since the first measurement might take
+ /// slightly longer than subsequent measurements.
+ ///
+ /// Returns true if sufficiently recent data is already available.
+ ///
+ /// Returns false if sufficiently recent data is not available. In this
+ /// case, ping measurement is initiated, if it is not already active.
+ /// (You cannot restart a measurement already in progress.)
+ ///
+ /// A FIXME event will be posted when measurement is completed.
+ virtual bool CheckPingDataUpToDate( float flMaxAgeSeconds ) = 0;
+
+ /// Return location info for the current host. Returns the approximate
+ /// age of the data, in seconds, or -1 if no data is available.
+ /// Note that this might return an age older than the age of your game's
+ /// process, if the data was obtained before you game started.
+ ///
+ /// This always return the most up-to-date information we have available
+ /// right now, even if we are in the middle of re-calculating ping times.
+ virtual float GetLocalPingLocation( SteamNetworkPingLocation_t &result ) = 0;
+
+ /// Return true if we are taking ping measurements to update our ping
+ /// location or select optimal routing. Ping measurement typically takes
+ /// a few seconds, perhaps up to 10 seconds.
+ virtual bool IsPingMeasurementInProgress() = 0;
+
+ /// Estimate the round-trip latency between two arbitrary locations, in
+ /// milliseconds. This is a conservative estimate, based on routing through
+ /// the relay network. For most basic connections based on SteamID,
+ /// this ping time will be pretty accurate, since it will be based on the
+ /// route likely to be actually used.
+ ///
+ /// If a direct IP route is used (perhaps via NAT traversal), then the route
+ /// will be different, and the ping time might be better. Or it might actually
+ /// be a bit worse! Standard IP routing is frequently suboptimal!
+ ///
+ /// but even in this case, the estimate obtained using this method is a
+ /// reasonable upper bound on the ping time. (Also it has the advantage
+ /// of returning immediately and not sending any packets.)
+ ///
+ /// In a few cases we might not able to estimate the route. In this case
+ /// a negative value is returned. k_nSteamNetworkingPing_Failed means
+ /// the reason was because of some networking difficulty. (Failure to
+ /// ping, etc) k_nSteamNetworkingPing_Unknown is returned if we cannot
+ /// currently answer the question for some other reason.
+ virtual int EstimatePingTimeBetweenTwoLocations( const SteamNetworkPingLocation_t &location1, const SteamNetworkPingLocation_t &location2 ) = 0;
+
+ /// Same as EstimatePingTime, but assumes that one location is the local host.
+ /// This is a bit faster, especially if you need to calculate a bunch of
+ /// these in a loop to find the fastest one.
+ ///
+ /// In rare cases this might return a slightly different estimate than combining
+ /// GetLocalPingLocation with EstimatePingTimeBetweenTwoLocations. That's because
+ /// this function uses a slightly more complete description
+ virtual int EstimatePingTimeFromLocalHost( const SteamNetworkPingLocation_t &remoteLocation ) = 0;
+
+ // FIXME:
+ //
+ // Check current internet connection status
+
+ //
+ // Low level ticket stuff. I need to get some advice and talk through how this should work
+ // or how best to tuck it away and make it transparent.
+ //
+
+ virtual bool ReceivedTicket( const void *pvTicket, int cbTicket, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0;
+ virtual bool HasTicketForServer( CSteamID steamID ) = 0;
+ virtual uint32 GetIPForServerSteamIDFromTicket( CSteamID steamID ) = 0;
+
+ //
+ // Low level network config stuff I haven't figure out how best to tuck away.
+ // Dota and CSGO use it because we have gameservers in the datacenter, and
+ // we need this information to do region selection. But most games won't
+ // need it.
+ //
+
+ /// Fetch directly measured ping time from local host to a particular network PoP.
+ /// Most games will not need to call this.
+ virtual int GetPingToDataCenter( SteamNetworkingPOPID popID, SteamNetworkingPOPID *pViaRelayPoP ) = 0;
+ virtual int GetDirectPingToPOP( SteamNetworkingPOPID popID ) = 0;
+
+ /// Get number of network PoPs in the config
+ virtual int GetPOPCount() = 0;
+
+ /// Get list of all POP IDs
+ virtual int GetPOPList( SteamNetworkingPOPID *list, int nListSz ) = 0;
+};
+#define STEAMNETWORKINGUTILS_VERSION "SteamNetworkingUtils001"
+
+/// Get ISteamNetworkingUtils object. This will eventually go in Steam_api.h with all the rest of its kin
+STEAMDATAGRAMLIB_INTERFACE ISteamNetworkingUtils *SteamNetworkingUtils();
+
+#endif // ISTEAMNETWORKINGUTILS
diff --git a/public/steamnetworkingsockets/steamdatagram_stats.h b/public/steamnetworkingsockets/steamdatagram_stats.h
new file mode 100644
index 0000000..8f6cb53
--- /dev/null
+++ b/public/steamnetworkingsockets/steamdatagram_stats.h
@@ -0,0 +1,298 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Some public types for communicating detailed connection stats
+//
+//=============================================================================
+
+#ifndef STEAMDATAGRAM_STATS_H
+#define STEAMDATAGRAM_STATS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "steamnetworkingtypes.h"
+
+#pragma pack(push)
+#pragma pack(8)
+
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramLinkInstantaneousStats_Clear( SteamDatagramLinkInstantaneousStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramLinkLifetimeStats_Clear( SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamDatagramLinkLifetimeStats_PingHistogramTotalCount( const SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamDatagramLinkLifetimeStats_QualityHistogramTotalCount( const SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamDatagramLinkLifetimeStats_JitterHistogramTotalCount( const SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamDatagramLinkLifetimeStats_TXSpeedHistogramTotalCount( const SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamDatagramLinkLifetimeStats_RXSpeedHistogramTotalCount( const SteamDatagramLinkLifetimeStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE void SteamDatagramLinkStats_Clear( SteamDatagramLinkStats *pThis );
+STEAMDATAGRAMLIB_INTERFACE void SteamNetworkingDetailedConnectionStatus_Clear( SteamNetworkingDetailedConnectionStatus *pThis );
+STEAMDATAGRAMLIB_INTERFACE int SteamNetworkingDetailedConnectionStatus_Print( const SteamNetworkingDetailedConnectionStatus *pThis, char *pszBuf, int cbBuf );
+
+/// Instantaneous statistics for a link between two hosts.
+struct SteamDatagramLinkInstantaneousStats
+{
+
+ /// Data rates
+ float m_flOutPacketsPerSec;
+ float m_flOutBytesPerSec;
+ float m_flInPacketsPerSec;
+ float m_flInBytesPerSec;
+
+ /// Smoothed ping. This will be -1 if we don't have any idea!
+ int m_nPingMS;
+
+ /// 0...1, estimated number of packets that were sent to us, but we failed to receive.
+ /// <0 if we haven't received any sequenced packets and so we don't have any way to estimate this.
+ float m_flPacketsDroppedPct;
+
+ /// Packets received with a sequence number abnormality, other than basic packet loss. (Duplicated, out of order, lurch.)
+ /// <0 if we haven't received any sequenced packets and so we don't have any way to estimate this.
+ float m_flPacketsWeirdSequenceNumberPct;
+
+ /// Peak jitter
+ int m_usecMaxJitter;
+
+ /// Current sending rate, this can be low at connection start until the slow start
+ /// ramps it up. It's adjusted as packets are lost and congestion is encountered during
+ /// the connection
+ int m_nSendRate;
+
+ /// How many pending bytes are waiting to be sent. This is data that is currently waiting
+ /// to be sent and in outgoing buffers. If this is zero, then the connection is idle
+ /// and all pending data has been sent. Note that in case of packet loss any pending
+ /// reliable data might be re-sent. This does not include data that has been sent and is
+ /// waiting for acknowledgment.
+ int m_nPendingBytes;
+
+ inline void Clear() { SteamDatagramLinkInstantaneousStats_Clear( this ); }
+};
+
+/// Stats for the lifetime of a connection.
+/// Should match CMsgSteamDatagramLinkLifetimeStats
+struct SteamDatagramLinkLifetimeStats
+{
+ /// Reset all values to zero / unknown status
+ inline void Clear() { return SteamDatagramLinkLifetimeStats_Clear( this ); }
+
+ //
+ // Lifetime counters.
+ // NOTE: Average packet loss, etc can be deduced from this.
+ //
+ int64 m_nPacketsSent;
+ int64 m_nBytesSent;
+ int64 m_nPacketsRecv; // total number of packets received, some of which might not have had a sequence number. Don't use this number to try to estimate lifetime packet loss, use m_nPacketsRecvSequenced
+ int64 m_nBytesRecv;
+ int64 m_nPktsRecvSequenced; // packets that we received that had a sequence number.
+ int64 m_nPktsRecvDropped;
+ int64 m_nPktsRecvOutOfOrder;
+ int64 m_nPktsRecvDuplicate;
+ int64 m_nPktsRecvSequenceNumberLurch;
+
+ // SNP message counters
+ int64 m_nMessagesSentReliable;
+ int64 m_nMessagesSentUnreliable;
+ int64 m_nMessagesRecvReliable;
+ int64 m_nMessagesRecvUnreliable;
+
+ //
+ // Ping distribution
+ //
+ int m_nPingHistogram25; // 0..25
+ int m_nPingHistogram50; // 26..50
+ int m_nPingHistogram75; // 51..75
+ int m_nPingHistogram100; // etc
+ int m_nPingHistogram125;
+ int m_nPingHistogram150;
+ int m_nPingHistogram200;
+ int m_nPingHistogram300;
+ int m_nPingHistogramMax; // >300
+ inline int PingHistogramTotalCount() const { return SteamDatagramLinkLifetimeStats_PingHistogramTotalCount( this ); }
+
+ // Distribution.
+ // NOTE: Some of these might be -1 if we didn't have enough data to make a meaningful estimate!
+ // It takes fewer samples to make an estimate of the median than the 98th percentile!
+ short m_nPingNtile5th; // 5% of ping samples were <= Nms
+ short m_nPingNtile50th; // 50% of ping samples were <= Nms
+ short m_nPingNtile75th; // 70% of ping samples were <= Nms
+ short m_nPingNtile95th; // 95% of ping samples were <= Nms
+ short m_nPingNtile98th; // 98% of ping samples were <= Nms
+ short m__pad1;
+
+
+ //
+ // Connection quality distribution
+ //
+ int m_nQualityHistogram100; // This means everything was perfect. If we delivered over 100 packets in the interval and were less than perfect, but greater than 99.5%, we will use 99% instead.
+ int m_nQualityHistogram99; // 99%+
+ int m_nQualityHistogram97;
+ int m_nQualityHistogram95;
+ int m_nQualityHistogram90;
+ int m_nQualityHistogram75;
+ int m_nQualityHistogram50;
+ int m_nQualityHistogram1;
+ int m_nQualityHistogramDead; // we received nothing during the interval; it looks like the connection dropped
+ inline int QualityHistogramTotalCount() const { return SteamDatagramLinkLifetimeStats_QualityHistogramTotalCount( this ); }
+
+ // Distribution. Some might be -1, see above for why.
+ short m_nQualityNtile2nd; // 2% of measurement intervals had quality <= N%
+ short m_nQualityNtile5th; // 5% of measurement intervals had quality <= N%
+ short m_nQualityNtile25th; // 25% of measurement intervals had quality <= N%
+ short m_nQualityNtile50th; // 50% of measurement intervals had quality <= N%
+
+ // Jitter histogram
+ int m_nJitterHistogramNegligible;
+ int m_nJitterHistogram1;
+ int m_nJitterHistogram2;
+ int m_nJitterHistogram5;
+ int m_nJitterHistogram10;
+ int m_nJitterHistogram20;
+ inline int JitterHistogramTotalCount() const { return SteamDatagramLinkLifetimeStats_JitterHistogramTotalCount( this ); }
+
+ //
+ // Connection transmit speed histogram
+ //
+ int m_nTXSpeedMax; // Max speed we hit
+
+ int m_nTXSpeedHistogram16; // Speed at kb/s
+ int m_nTXSpeedHistogram32;
+ int m_nTXSpeedHistogram64;
+ int m_nTXSpeedHistogram128;
+ int m_nTXSpeedHistogram256;
+ int m_nTXSpeedHistogram512;
+ int m_nTXSpeedHistogram1024;
+ int m_nTXSpeedHistogramMax;
+ inline int TXSpeedHistogramTotalCount() const { return SteamDatagramLinkLifetimeStats_TXSpeedHistogramTotalCount( this ); }
+
+ // Distribution. Some might be -1, see above for why.
+ int m_nTXSpeedNtile5th; // 5% of transmit samples were <= N kb/s
+ int m_nTXSpeedNtile50th; // 50% of transmit samples were <= N kb/s
+ int m_nTXSpeedNtile75th; // 75% of transmit samples were <= N kb/s
+ int m_nTXSpeedNtile95th; // 95% of transmit samples were <= N kb/s
+ int m_nTXSpeedNtile98th; // 98% of transmit samples were <= N kb/s
+
+ //
+ // Connection receive speed histogram
+ //
+ int m_nRXSpeedMax; // Max speed we hit that formed the histogram
+
+ int m_nRXSpeedHistogram16; // Speed at kb/s
+ int m_nRXSpeedHistogram32;
+ int m_nRXSpeedHistogram64;
+ int m_nRXSpeedHistogram128;
+ int m_nRXSpeedHistogram256;
+ int m_nRXSpeedHistogram512;
+ int m_nRXSpeedHistogram1024;
+ int m_nRXSpeedHistogramMax;
+ inline int RXSpeedHistogramTotalCount() const { return SteamDatagramLinkLifetimeStats_RXSpeedHistogramTotalCount( this ); }
+
+ // Distribution. Some might be -1, see above for why.
+ int m_nRXSpeedNtile5th; // 5% of transmit samples were <= N kb/s
+ int m_nRXSpeedNtile50th; // 50% of transmit samples were <= N kb/s
+ int m_nRXSpeedNtile75th; // 75% of transmit samples were <= N kb/s
+ int m_nRXSpeedNtile95th; // 95% of transmit samples were <= N kb/s
+ int m_nRXSpeedNtile98th; // 98% of transmit samples were <= N kb/s
+
+};
+
+/// Link stats. Pretty much everything you might possibly want to know about the connection
+struct SteamDatagramLinkStats
+{
+
+ /// Latest instantaneous stats, calculated locally
+ SteamDatagramLinkInstantaneousStats m_latest;
+
+ /// Peak values for each instantaneous stat
+ //SteamDatagramLinkInstantaneousStats m_peak;
+
+ /// Lifetime stats, calculated locally
+ SteamDatagramLinkLifetimeStats m_lifetime;
+
+ /// Latest instantaneous stats received from remote host.
+ /// (E.g. "sent" means they are reporting what they sent.)
+ SteamDatagramLinkInstantaneousStats m_latestRemote;
+
+ /// How many seconds ago did we receive m_latestRemote?
+ /// This will be <0 if the data is not valid!
+ float m_flAgeLatestRemote;
+
+ /// Latest lifetime stats received from remote host.
+ SteamDatagramLinkLifetimeStats m_lifetimeRemote;
+
+ /// How many seconds ago did we receive the lifetime stats?
+ /// This will be <0 if the data is not valid!
+ float m_flAgeLifetimeRemote;
+
+ /// Reset everything to unknown/initial state.
+ inline void Clear() { SteamDatagramLinkStats_Clear( this ); }
+};
+
+/// Status of a particular network resource
+enum ESteamDatagramAvailability
+{
+ k_ESteamDatagramAvailability_CannotTry = -3, // A dependent resource is missing, so this service is unavailable. (E.g. we cannot talk to routers because Internet is down or we don't have the network config.)
+ k_ESteamDatagramAvailability_Failed = -2, // We have tried for enough time that we would expect to have been successful by now. We have never been successful
+ k_ESteamDatagramAvailability_Previously = -1, // We tried and were successful at one time, but now it looks like we have a problem
+ k_ESteamDatagramAvailability_Unknown = 0, // Unknown, or not applicable in this context
+ k_ESteamDatagramAvailability_NeverTried = 1, // We don't know because we haven't ever checked
+ k_ESteamDatagramAvailability_Attempting = 2, // We're trying now, but are not yet successful. This is not an error, but it's not success, either.
+ k_ESteamDatagramAvailability_Current = 3, // Resource is online.
+};
+
+/// Describe detailed state of current connection
+struct SteamNetworkingDetailedConnectionStatus
+{
+ /// Basic connection info
+ SteamNetConnectionInfo_t m_info;
+
+ /// Do we have a valid network configuration? We cannot do anything without this.
+ ESteamDatagramAvailability m_eAvailNetworkConfig;
+
+// /// Does it look like we have a connection to the Internet at all?
+// EAvailability m_eAvailInternet;
+
+ /// Successful communication with a box on the routing network.
+ /// This will be marked as failed if there is a general internet
+ /// connection.
+ ESteamDatagramAvailability m_eAvailAnyRouterCommunication;
+
+ /// End-to-end communication with the remote host.
+ //ESteamDatagramAvailability m_eAvailEndToEnd;
+
+ /// Stats for end-to-end link to the gameserver
+ SteamDatagramLinkStats m_statsEndToEnd;
+
+ /// Currently selected front router, if any.
+ /// Note that PoP ID can be found in the SteamNetConnectionInfo_t
+ char m_szPrimaryRouterName[64];
+ uint32 m_unPrimaryRouterIP;
+ uint16 m_unPrimaryRouterPort;
+
+ /// Stats for "front" link to current router
+ SteamDatagramLinkStats m_statsPrimaryRouter;
+
+ /// Back ping time as reported by primary.
+ /// (The front ping is in m_statsPrimaryRouter,
+ /// and usually the front ping plus the back ping should
+ /// approximately equal the end-to-end ping)
+ int m_nPrimaryRouterBackPing;
+
+ /// Currently selected back router, if any
+ SteamNetworkingPOPID m_idBackupRouterCluster;
+ char m_szBackupRouterName[64];
+ uint32 m_unBackupRouterIP;
+ uint16 m_unBackupRouterPort;
+
+ /// Ping times to backup router, if any
+ int m_nBackupRouterFrontPing, m_nBackupRouterBackPing;
+
+ /// Clear everything to an unknown state
+ inline void Clear() { SteamNetworkingDetailedConnectionStatus_Clear( this ); }
+
+ /// Print into a buffer.
+ /// 0 = OK
+ /// >1 = buffer was null or too small (in which case truncation happened).
+ /// Pass a buffer of at least N bytes.
+ inline int Print( char *pszBuf, int cbBuf ) const { return SteamNetworkingDetailedConnectionStatus_Print( this, pszBuf, cbBuf ); }
+};
+
+#pragma pack(pop)
+
+#endif // STEAMDATAGRAM_STATS_H
diff --git a/public/steamnetworkingsockets/steamdatagram_ticketgen.h b/public/steamnetworkingsockets/steamdatagram_ticketgen.h
new file mode 100644
index 0000000..32e080a
--- /dev/null
+++ b/public/steamnetworkingsockets/steamdatagram_ticketgen.h
@@ -0,0 +1,60 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Backend functions to generate authorization tickets for steam datagram
+//
+//=============================================================================
+
+#ifndef STEAMDATAGRAM_TICKETGEN_H
+#define STEAMDATAGRAM_TICKETGEN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+// Import some common stuff that is useful by both the client
+// and the backend ticket-generating authority.
+#include "steamdatagram_tickets.h"
+
+struct SteamDatagramSignedTicketBlob
+{
+ int m_sz;
+ uint8 m_blob[ k_cbSteamDatagramMaxSerializedTicket ];
+};
+
+/// Initialize ticket generation with an Ed25519 private key.
+/// See: https://ed25519.cr.yp.to/
+///
+/// Input buffer will be securely wiped.
+///
+/// You can generate an Ed25519 key using OpenSSH:
+///
+/// ssh-keygen -t ed25519
+///
+/// The private key should be a PEM-like block of text
+/// ("-----BEGIN OPENSSH PRIVATE KEY-----").
+/// Private keys encrypted with a password are not supported.
+///
+/// In order for signatures using this key to be accepted by the relay network,
+/// you need to send your public key to Valve. This key should be on a single line
+/// of text that begins with "ssh-ed25519". (The format used in the .ssh/authorized_keys
+/// file.)
+STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagram_InitTicketGenerator_Ed25519( void *pvPrivateKey, size_t cbPrivateKey );
+
+/// Serialize the specified auth ticket and attach a signature.
+/// Returns false if you did something stupid like forgot to load a key.
+/// Will also fail if your ticket is too big. (Probably because you
+/// added too many extra fields.)
+STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagram_SerializeAndSignTicket( const SteamDatagramRelayAuthTicket &ticket, SteamDatagramSignedTicketBlob &outBlob );
+
+//
+// Legacy / deprecated
+//
+
+/// Initialize ticket generation with an RSA private key. You can either
+/// pass a PEM block ("-----BEGIN PRIVATE KEY-----"), or binary PKCS#8 DER.
+/// Input buffer will be securely wiped.
+STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagram_InitTicketGenerator_RSA_deprecated( void *pvPrivateKey, size_t cbPrivateKey );
+
+/// Generate a signature for legacy support
+STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagram_SerializeAndSignTicket_deprecated( const SteamDatagramRelayAuthTicket &ticket, SteamDatagramSignedTicketBlob &outBlob );
+
+#endif // STEAMDATAGRAM_TICKETGEN_H
diff --git a/public/steamnetworkingsockets/steamdatagram_tickets.h b/public/steamnetworkingsockets/steamdatagram_tickets.h
new file mode 100644
index 0000000..22191ad
--- /dev/null
+++ b/public/steamnetworkingsockets/steamdatagram_tickets.h
@@ -0,0 +1,151 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Types and utilities for handling steam datagram tickets. These are
+// useful for both the client and the backend ticket generating authority.
+//
+//=============================================================================
+
+#ifndef STEAMDATAGRAM_TICKETS_H
+#define STEAMDATAGRAM_TICKETS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifndef assert
+ #include <assert.h>
+#endif
+
+#include "steamnetworkingtypes.h"
+
+#pragma pack(push)
+#pragma pack(8)
+
+#if defined( STEAMDATAGRAM_TICKETGEN_FOREXPORT ) || defined( STEAMDATAGRAMLIB_FOREXPORT )
+ #define STEAMDATAGRAM_TICKET_INTERFACE DLL_EXPORT
+#elif defined( STEAMDATAGRAMLIB_STATIC_LINK )
+ #define STEAMDATAGRAM_TICKET_INTERFACE extern "C"
+#else
+ #define STEAMDATAGRAM_TICKET_INTERFACE DLL_IMPORT
+#endif
+
+/// Max length of serialized auth ticket. This is important so that we
+/// can ensure that we always fit into a single UDP datagram (along with
+/// other certs and signatures) and kep the implementation simple.
+const size_t k_cbSteamDatagramMaxSerializedTicket = 512;
+
+/// Network-routable identifier for a service. In general, clients should
+/// treat this as an opaque structure. The only thing that is important
+/// is that this contains everything the system needs to route packets to a
+/// service.
+struct SteamDatagramServiceNetID
+{
+ // Just use the private LAN address to identify the service
+ uint32 m_unIP;
+ uint16 m_unPort;
+ uint16 m__nPad1;
+
+ void Clear() { *(uint64 *)this = 0; }
+
+ uint64 ConvertToUint64() const { return ( uint64(m_unIP) << 16U ) | uint64(m_unPort); }
+ void SetFromUint64( uint64 x )
+ {
+ m_unIP = uint32(x >> 16U);
+ m_unPort = uint16(x);
+ m__nPad1 = 0;
+ }
+
+ inline bool operator==( const SteamDatagramServiceNetID &x ) const { return m_unIP == x.m_unIP && m_unPort == x.m_unPort; }
+};
+
+/// Ticket used to gain access to the relay network.
+struct SteamDatagramRelayAuthTicket
+{
+ SteamDatagramRelayAuthTicket() { Clear(); }
+
+ /// Reset all fields
+ void Clear() { memset( this, 0, sizeof(*this) ); }
+
+ /// Steam ID of the gameserver we want to talk to
+ CSteamID m_steamIDGameserver;
+
+ /// Steam ID of the person who was authorized.
+ CSteamID m_steamIDAuthorizedSender;
+
+ /// SteamID is authorized to send from a particular public IP. If this
+ /// is 0, then the sender is not restricted to a particular IP.
+ uint32 m_unPublicIP;
+
+ /// Time when the ticket expires.
+ RTime32 m_rtimeTicketExpiry;
+
+ /// Routing information
+ SteamDatagramServiceNetID m_routing;
+
+ /// App ID this is for
+ uint32 m_nAppID;
+
+ struct ExtraField
+ {
+ enum EType
+ {
+ k_EType_String,
+ k_EType_Int, // For most small integral values. Uses google protobuf sint64, so it's small on the wire. WARNING: In some places this value may be transmitted in JSON, in which case precision may be lost in backend analytics. Don't use this afor an "identifier", use it for a scalar quantity.
+ k_EType_Fixed64, // 64 arbitrary bits. This value is treated as an "identifier". In places where JSON format is used, it will be serialized as a string. No aggregation / analytics can be performed on this value.
+ };
+ int /* EType */ m_eType;
+ char m_szName[28];
+
+ union {
+ char m_szStringValue[128];
+ int64 m_nIntValue;
+ uint64 m_nFixed64Value;
+ };
+ };
+ enum { k_nMaxExtraFields = 16 };
+ int m_nExtraFields;
+ ExtraField m_vecExtraFields[ k_nMaxExtraFields ];
+
+ /// Helper to add an extra field in a single call
+ void AddExtraField_Int( const char *pszName, int64 val )
+ {
+ ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Int );
+ if ( p )
+ p->m_nIntValue = val;
+ }
+ void AddExtraField_Fixed64( const char *pszName, uint64 val )
+ {
+ ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Fixed64 );
+ if ( p )
+ p->m_nFixed64Value = val;
+ }
+ void AddExtraField_String( const char *pszName, const char *val )
+ {
+ ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Fixed64 );
+ if ( p )
+ V_strcpy_safe( p->m_szStringValue, val );
+ }
+
+private:
+ ExtraField *AddExtraField( const char *pszName, ExtraField::EType eType )
+ {
+ if ( m_nExtraFields >= k_nMaxExtraFields )
+ {
+ assert( false );
+ return nullptr;
+ }
+ ExtraField *p = &m_vecExtraFields[ m_nExtraFields++ ];
+ p->m_eType = eType;
+ V_strcpy_safe( p->m_szName, pszName );
+ return p;
+ }
+};
+
+/// Unpack signed ticket. Does not check the signature!
+/// Note that it's assumed that you won't need to link with both the client
+/// lib and the ticket generating lib in any one project, since this symbol
+/// is exposed in both.
+STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagramRelayAuthTicket_Parse( const void *pvTicket, int cbTicket, SteamDatagramRelayAuthTicket *pOutTicket, SteamDatagramErrMsg &errMsg );
+
+#pragma pack(pop)
+
+#endif // STEAMDATAGRAM_TICKETS_H
diff --git a/public/steamnetworkingsockets/steamnetworkingtypes.h b/public/steamnetworkingsockets/steamnetworkingtypes.h
new file mode 100644
index 0000000..2fd1baa
--- /dev/null
+++ b/public/steamnetworkingsockets/steamnetworkingtypes.h
@@ -0,0 +1,641 @@
+//====== Copyright Valve Corporation, All rights reserved. ====================
+//
+// Purpose: misc networking utilities
+//
+//=============================================================================
+
+#ifndef STEAMNETWORKINGTYPES
+#define STEAMNETWORKINGTYPES
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "steam/steamtypes.h"
+#include "steam/steamclientpublic.h"
+#include "tier0/platform.h"
+
+#if defined( STEAMDATAGRAMLIB_STATIC_LINK )
+ #define STEAMDATAGRAMLIB_INTERFACE extern
+#elif defined( STEAMDATAGRAMLIB_FOREXPORT )
+ #define STEAMDATAGRAMLIB_INTERFACE DLL_EXPORT
+#else
+ #define STEAMDATAGRAMLIB_INTERFACE DLL_IMPORT
+#endif
+
+#pragma pack( push, 8 )
+
+struct SteamNetworkPingLocation_t;
+class ISteamNetworkingMessage;
+struct SteamDatagramLinkStats;
+struct SteamDatagramLinkLifetimeStats;
+struct SteamDatagramLinkInstantaneousStats;
+struct SteamNetworkingDetailedConnectionStatus;
+
+/// Handle used to identify a connection to a remote host.
+typedef uint32 HSteamNetConnection;
+const HSteamNetConnection k_HSteamNetConnection_Invalid = 0;
+
+/// Handle used to identify a "listen socket".
+typedef uint32 HSteamListenSocket;
+const HSteamListenSocket k_HSteamListenSocket_Invalid = 0;
+
+/// Configuration values for Steam networking.
+///
+/// Most of these are for controlling extend logging or features
+/// of various subsystems
+enum ESteamNetworkingConfigurationValue
+{
+ // Set to true (non-zero) to use Steam Network Protocol for message
+ // delivery.
+ // SNP is a protocol for sending a mix of reliable and unreliable message
+ // payloads and handles retransmission of reliable messages and also
+ // manages transfer rate congestion control. Defaults to 1 (on).
+ k_ESteamNetworkingConfigurationValue_SNP = 0,
+
+ // 0-100 Randomly discard N pct of unreliable messages instead of sending
+ // Defaults to 0 (no loss).
+ k_ESteamNetworkingConfigurationValue_FakeMessageLoss_Send = 1,
+
+ // 0-100 Randomly discard N pct of unreliable messages upon receive
+ // Defaults to 0 (no loss).
+ k_ESteamNetworkingConfigurationValue_FakeMessageLoss_Recv = 2,
+
+ // 0-100 Randomly discard N pct of packets instead of sending
+ k_ESteamNetworkingConfigurationValue_FakePacketLoss_Send = 3,
+
+ // 0-100 Randomly discard N pct of packets received
+ k_ESteamNetworkingConfigurationValue_FakePacketLoss_Recv = 4,
+
+ // Set to true (non-zero) to open up a seperate debug window showing SNP
+ // state for all current connections. Only works on Windows.
+ // Defaults to 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_DebugWindow = 5,
+
+ // Upper limit of buffered pending bytes to be sent, if this is reached
+ // SendMessage will return k_EResultPending
+ // Default is 512k (524288 bytes)
+ k_ESteamNetworkingConfigurationValue_SNP_SendBufferSize = 6,
+
+ // Maximum send rate clamp, 0 is no limit
+ // This value will control the maximum allowed sending rate that congestion
+ // is allowed to reach. Default is 0 (no-limit)
+ k_ESteamNetworkingConfigurationValue_SNP_MaxRate = 7,
+
+ // Minimum send rate clamp, 0 is no limit
+ // This value will control the minimum allowed sending rate that congestion
+ // is allowed to reach. Default is 0 (no-limit)
+ k_ESteamNetworkingConfigurationValue_SNP_MinRate = 8,
+
+ // Set to true (non-zero) to enable logging of SNP RTT
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_RTT = 9,
+
+ // Set to true (non-zero) to enable logging of SNP Packet
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Packet = 10,
+
+ // Set to true (non-zero) to enable logging of SNP Segments
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Segments = 11,
+
+ // Set to true (non-zero) to enable logging of SNP Feedback
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Feedback = 12,
+
+ // Set to true (non-zero) to enable logging of SNP Relible
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Reliable = 13,
+
+ // Set to true (non-zero) to enable logging of SNP Messages
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Message = 14,
+
+ // Set to true (non-zero) to enable logging of SNP Loss
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_Loss = 15,
+
+ // Set to true (non-zero) to enable logging of SNP Throughput
+ // Default is 0 (off)
+ k_ESteamNetworkingConfigurationValue_SNP_Log_X = 16,
+
+ // If the first N pings to a port all fail, mark that port as unavailable for
+ // a while, and try a different one. Some ISPs and routers may drop the first
+ // packet, so setting this to 1 may greatly disrupt communications.
+ k_ESteamNetworkingConfigurationValue_ClientConsecutitivePingTimeoutsFailInitial = 17,
+
+ // If N consecutive pings to a port fail, after having received successful
+ // communication, mark that port as unavailable for a while, and try a
+ // different one.
+ k_ESteamNetworkingConfigurationValue_ClientConsecutitivePingTimeoutsFail = 18,
+
+ /// Minimum number of lifetime pings we need to send, before we think our estimate
+ /// is solid. The first ping to each cluster is very often delayed because of NAT,
+ /// routers not having the best route, etc. Until we've sent a sufficient number
+ /// of pings, our estimate is often inaccurate. Keep pinging until we get this
+ /// many pings.
+ k_ESteamNetworkingConfigurationValue_ClientMinPingsBeforePingAccurate = 19,
+
+ // Set all steam datagram traffic to originate from the same local port.
+ // By default, we open up a new UDP socket (on a different local port)
+ // for each relay. This is not optimal, but it works around some
+ // routers that don't implement NAT properly. If you have intermittent
+ // problems talking to relays that might be NAT related, try toggling
+ // this flag
+ k_ESteamNetworkingConfigurationValue_ClientSingleSocket = 20,
+
+ // Globally delay all outbound packets by N ms before sending
+ k_ESteamNetworkingConfigurationValue_FakePacketLag_Send = 21,
+
+ // Globally delay all received packets by N ms before processing
+ k_ESteamNetworkingConfigurationValue_FakePacketLag_Recv = 22,
+
+ // Don't automatically fail IP connections that don't have strong auth.
+ // On clients, this means we will attempt the connection even if we don't
+ // know our SteamID or can't get a cert. On the server, it means that we won't
+ // automatically reject a connection due to a failure to authenticate.
+ // (You can examine the incoming connection and decide whether to accept it.)
+ k_ESteamNetworkingConfigurationValue_IP_Allow_Without_Auth = 23,
+
+ // Number of k_ESteamNetworkingConfigurationValue defines
+ k_ESteamNetworkingConfigurationValue_Count,
+};
+
+/// Configuration strings for Steam networking.
+///
+/// Most of these are for controlling extend logging or features
+/// of various subsystems
+enum ESteamNetworkingConfigurationString
+{
+ // Code of relay cluster to use. If not empty, we will only use relays in that cluster. E.g. 'iad'
+ k_ESteamNetworkingConfigurationString_ClientForceRelayCluster = 0,
+
+ // For debugging, generate our own (unsigned) ticket, using the specified
+ // gameserver address. Router must be configured to accept unsigned tickets.
+ k_ESteamNetworkingConfigurationString_ClientDebugTicketAddress = 1,
+
+ // For debugging. Override list of relays from the config with this set
+ // (maybe just one). Comma-separated list.
+ k_ESteamNetworkingConfigurationString_ClientForceProxyAddr = 2,
+
+ // Number of k_ESteamNetworkingConfigurationString defines
+ k_ESteamNetworkingConfigurationString_Count = k_ESteamNetworkingConfigurationString_ClientForceProxyAddr + 1,
+};
+
+/// Basically a duplicate of EP2PSend.
+enum ESteamNetworkingSendType
+{
+ // Send an unreliable message. Can be lost.
+ // The sending API does have some knowledge of the underlying connection, so if there is no NAT-traversal accomplished or
+ // there is a recognized adjustment happening on the connection, the packet will be batched until the connection is open again.
+ k_ESteamNetworkingSendType_Unreliable = 0,
+
+ // Reliable message send. Can send up to 512kb of data in a single message.
+ // Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for efficient sends of large chunks of data.
+ k_ESteamNetworkingSendType_Reliable = 1,
+};
+
+/// High level connection status
+enum ESteamNetworkingConnectionState
+{
+
+ /// Dummy value used to indicate an error condition in the API.
+ /// Specified connection doesn't exist or has already been closed.
+ k_ESteamNetworkingConnectionState_None = 0,
+
+ /// - For connections on the "client" side (initiated locally):
+ /// We're in the process of trying to establish a connection.
+ /// Depending on the socket type, we might not even know who they are.
+ /// Note that it is not possible to tell if we are waiting on the
+ /// network to complete handshake packets, or for the application layer
+ /// to accept the connection.
+ ///
+ /// - For connections on the "server" side (accepted through listen socket):
+ /// We have completed a series of basic handshake packets, and the connection
+ /// is ready to be accepted using AcceptConnection.
+ ///
+ /// In either case, any unreliable packets sent now are almost certain
+ /// to be dropped. Attempts to receive packets are guaranteed to fail.
+ /// You may send messages if the send mode allows for them to be queued.
+ /// but if you close the connection before the connection is actually
+ /// established, any queued messages will be discarded immediately.
+ /// (We will not attempt to flush the queue and confirm delivery to the
+ /// remote host, which ordinarily happens when a connection is closed.)
+ k_ESteamNetworkingConnectionState_Connecting = 1,
+
+ /// We've received communications from our peer (and we know
+ /// who they are) and are all good. If you close the connection now,
+ /// we will make our best effort to flush out any reliable sent data that
+ /// has not been acknowledged by the peer. (But note that this happens
+ /// from within the application process, so unlike a TCP connection, you are
+ /// not totally handing it off to the operating system to deal with it.)
+ k_ESteamNetworkingConnectionState_Connected = 2,
+
+ /// Connection has been closed by our peer, but not closed locally.
+ /// The connection still exists from an API perspective. You must close the
+ /// handle to free up resources. If there are any messages in the inbound queue,
+ /// you may retrieve them. Otherwise, nothing may be done with the connection
+ /// except to close it.
+ ///
+ /// This stats is similar to CLOSE_WAIT in the TCP state machine.
+ k_ESteamNetworkingConnectionState_ClosedByPeer = 3,
+
+ /// A disruption in the connection has been detected locally. (E.g. timeout,
+ /// local internet connection disrupted, etc.)
+ ///
+ /// The connection still exists from an API perspective. You must close the
+ /// handle to free up resources.
+ ///
+ /// Attempts to send further messages will fail. Any remaining received messages
+ /// in the queue are available.
+ k_ESteamNetworkingConnectionState_ProblemDetectedLocally = 4,
+
+//
+// The following values are used internally and will not be returned by any API.
+// We document them here to provide a little insight into the state machine that is used
+// under the hood.
+//
+
+ /// We've disconnected on our side, and from an API perspective the connection is closed.
+ /// No more data may be sent or received. All reliable data has been flushed, or else
+ /// we've given up and discarded it. We do not yet know for sure that the client knows
+ /// the connection has been closed, however, so we're just hanging around so that if we do
+ /// get a packet from them, we can send them the appropriate packets so that they can
+ /// know why the connection was closed (and not have to rely on a timeout, which makes
+ /// it appear as if something is wrong).
+ ///
+ /// Note that, unlike TCP connections, Steam networking sessions have additional
+ /// session identifiers that make the TIME_WAIT state unnecessary. (If another connection
+ /// is established on the same port, and we get packets from an old session, we are able to
+ /// identify this and either ignore those packets, or inform the remote host that the old
+ /// session has been closed, if appropriate).
+ k_ESteamNetworkingConnectionState_FinWait = -1,
+
+ /// We've disconnected on our side, and from an API perspective the connection is closed.
+ /// No more data may be sent or received. From a network perspective, however, on the wire,
+ /// we have not yet given any indication to the peer that the connection is closed.
+ /// We are in the process of flushing out the last bit of reliable data. Once that is done,
+ /// we will inform the peer that the connection has been closed, and transition to the
+ /// FinWait state.
+ ///
+ /// Note that no indication is given to the remote host that we have closed the connection,
+ /// until the data has been flushed. If the remote host attempts to send us data, we will
+ /// do whatever is necessary to keep the connection alive until it can be closed properly.
+ /// But in fact the data will be discarded, since there is no way for the application to
+ /// read it back. Typically this is not a problem, as application protocols that utilize
+ /// the lingering functionality are designed for the remote host to wait for the response
+ /// before sending any more data.
+ k_ESteamNetworkingConnectionState_Linger = -2,
+
+ /// Connection is completely inactive and ready to be destroyed
+ k_ESteamNetworkingConnectionState_Dead = -3,
+};
+
+/// Identifier used for a network location point of presence.
+/// Typically you won't need to directly manipulate these.
+typedef uint32 SteamNetworkingPOPID;
+
+/// Convert 3- or 4-character ID to 32-bit int.
+inline SteamNetworkingPOPID CalculateSteamNetworkingPOPIDFromString( const char *pszCode )
+{
+ // OK we made a bad decision when we decided how to pack 3-character codes into a uint32. We'd like to support
+ // 4-character codes, but we don't want to break compatibility. The migration path has some subtleties that make
+ // this nontrivial, and there are already some IDs stored in SQL. Ug, so the 4 character code "abcd" will
+ // be encoded with the digits like "0xddaabbcc"
+ return
+ ( uint32(pszCode[3]) << 24U )
+ | ( uint32(pszCode[0]) << 16U )
+ | ( uint32(pszCode[1]) << 8U )
+ | uint32(pszCode[2]);
+}
+
+/// Unpack integer to string representation, including terminating '\0'
+template <int N>
+inline void GetSteamNetworkingLocationPOPStringFromID( SteamNetworkingPOPID id, char (&szCode)[N] )
+{
+ COMPILE_TIME_ASSERT( N >= 5 );
+ szCode[0] = ( id >> 16U );
+ szCode[1] = ( id >> 8U );
+ szCode[2] = ( id );
+ szCode[3] = ( id >> 24U ); // See comment above about deep regret and sadness
+ szCode[4] = 0;
+}
+
+/// A local timestamp. You can subtract two timestamps to get the number of elapsed
+/// microseconds. This is guaranteed to increase over time during the lifetime
+/// of a process, but not globally across runs. You don't need to worry about
+/// the value wrapping around. Note that the underlying clock might not actually have
+/// microsecond *resolution*.
+typedef int64 SteamNetworkingMicroseconds;
+
+/// A sequence number. Used to indentify packets and messages
+/// and other segments. Typically this is 64 bit internally and
+/// has the last 16 bits networked
+typedef int64 SteamNetworkingSequenceNumber;
+
+// maximum amount of pending buffered messages allows
+const int k_cbMaxSteamDatagramMessageSize = 512 * 1024;
+
+/// A message that has been received.
+class ISteamNetworkingMessage
+{
+public:
+
+ /// You MUST call this when you're done with the object,
+ /// to free up memory, etc.
+ virtual void Release() = 0;
+
+ /// Get size of the payload.
+ inline uint32 GetSize() const { return m_cbSize; }
+
+ /// Get message payload
+ inline const void *GetData() const { return m_pData; }
+
+ /// Return SteamID that sent this to us.
+ inline CSteamID GetSenderSteamID() const { return m_steamIDSender; }
+
+ /// Return the channel number the message was received on.
+ /// (Not used for messages received on "connections"
+ inline int GetChannel() const { return m_nChannel; }
+
+ /// The socket this came from. (Not used when using the P2P calls)
+ inline HSteamNetConnection GetConnection() const { return m_conn; }
+
+ /// Get the user data associated with the connection.
+ ///
+ /// This is *usually* the same as calling GetConnection() and then
+ /// fetching the user data associated with that connection, but for
+ /// the following subtle differences:
+ ///
+ /// - This user data will match the connection's user data at the time
+ /// is captured at the time the message is returned by the API.
+ /// If you subsequently change the userdata on the connection,
+ /// this won't be updated.
+ /// - This is an inline call, so it's *much* faster.
+ /// - You might have closed the connection, so fetching the user data
+ /// would not be possible.
+ inline int64 GetConnectionUserData() const { return m_nConnUserData; }
+
+ /// Get the time that it was received
+ inline SteamNetworkingMicroseconds GetTimeReceived() const { return m_usecTimeReceived; }
+
+protected:
+ CSteamID m_steamIDSender;
+ void *m_pData;
+ uint32 m_cbSize;
+ int m_nChannel;
+ HSteamNetConnection m_conn;
+ int64 m_nConnUserData;
+ SteamNetworkingMicroseconds m_usecTimeReceived;
+
+ inline ~ISteamNetworkingMessage() {}; // Destructor hidden - use Release()! But make it inline and empty, in case you want to derive your own type that satisfies this interface for use in your code.
+};
+
+/// Object that describes a "location" on the Internet with sufficient
+/// detail that we can reasonably estimate an upper bound on the ping between
+/// the two hosts, even if a direct route between the hosts is not possible,
+/// and the connection must be routed through the Steam Datagram Relay network.
+/// This does not contain any information that identifies the host. Indeed,
+/// if two hosts are in the same building or otherwise have nearly identical
+/// networking characteristics, then it's valid to use the same location
+/// object for both of them.
+///
+/// NOTE: This object should only be used in memory. If you need to persist
+/// it or send it over the wire, convert it to a string representation using
+/// the methods in ISteamNetworkingUtils()
+struct SteamNetworkPingLocation_t
+{
+ uint8 m_data[ 64 ];
+};
+
+/// Special values that are returned by some functions that return a ping.
+const int k_nSteamNetworkingPing_Failed = -1;
+const int k_nSteamNetworkingPing_Unknown = -2;
+
+/// Enumerate various causes of connection termination. These are designed
+/// to work sort of like HTTP error codes, in that the numeric range gives you
+/// a ballpark as to where the problem is.
+enum ESteamNetConnectionEnd
+{
+ // Invalid/sentinel value
+ k_ESteamNetConnectionEnd_Invalid = 0,
+
+ //
+ // Application codes. You can use these codes if you want to
+ // plumb through application-specific error codes. If you don't need this
+ // facility, feel free to always use 0, which is a generic
+ // application-initiated closure.
+ //
+ // The distinction between "normal" and "exceptional" termination is
+ // one you may use if you find useful, but it's not necessary for you
+ // to do so. The only place where we distinguish between normal and
+ // exceptional is in connection analytics. If a significant
+ // proportion of connections terminates in an exceptional manner,
+ // this can trigger an alert.
+ //
+
+ // 1xxx: Application ended the connection in a "usual" manner.
+ // E.g.: user intentionally disconnected from the server,
+ // gameplay ended normally, etc
+ k_ESteamNetConnectionEnd_App_Min = 1000,
+ k_ESteamNetConnectionEnd_App_Generic = k_ESteamNetConnectionEnd_App_Min,
+ // Use codes in this range for "normal" disconnection
+ k_ESteamNetConnectionEnd_App_Max = 1999,
+
+ // 2xxx: Application ended the connection in some sort of exceptional
+ // or unusual manner that might indicate a bug or configuration
+ // issue.
+ //
+ k_ESteamNetConnectionEnd_AppException_Min = 2000,
+ k_ESteamNetConnectionEnd_AppException_Generic = k_ESteamNetConnectionEnd_AppException_Min,
+ // Use codes in this range for "unusual" disconnection
+ k_ESteamNetConnectionEnd_AppException_Max = 2999,
+
+ //
+ // System codes:
+ //
+
+ // 3xxx: Connection failed or ended because of problem with the
+ // local host or their connection to the Internet.
+ k_ESteamNetConnectionEnd_Local_Min = 3000,
+
+ // You cannot do what you want to do because you're running in offline mode.
+ k_ESteamNetConnectionEnd_Local_OfflineMode = 3001,
+
+ // We're having trouble contacting many (perhaps all) relays.
+ // Since it's unlikely that they all went offline at once, the best
+ // explanation is that we have a problem on our end. Note that we don't
+ // bother distinguishing between "many" and "all", because in practice,
+ // it takes time to detect a connection problem, and by the time
+ // the connection has timed out, we might not have been able to
+ // actively probe all of the relay clusters, even if we were able to
+ // contact them at one time. So this code just means that:
+ //
+ // * We don't have any recent successful communication with any relay.
+ // * We have evidence of recent failures to communicate with multiple relays.
+ k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity = 3002,
+
+ // A hosted server is having trouble talking to the relay
+ // that the client was using, so the problem is most likely
+ // on our end
+ k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay = 3003,
+
+ // We're not able to get the network config. This is
+ // *almost* always a local issue, since the network config
+ // comes from the CDN, which is pretty darn reliable.
+ k_ESteamNetConnectionEnd_Local_NetworkConfig = 3004,
+
+ k_ESteamNetConnectionEnd_Local_Max = 3999,
+
+ // 4xxx: Connection failed or ended, and it appears that the
+ // cause does NOT have to do with the local host or their
+ // connection to the Internet. It could be caused by the
+ // remote host, or it could be somewhere in between.
+ k_ESteamNetConnectionEnd_Remote_Min = 4000,
+
+ // The connection was lost, and as far as we can tell our connection
+ // to relevant services (relays) has not been disrupted. This doesn't
+ // mean that the problem is "their fault", it just means that it doesn't
+ // appear that we are having network issues on our end.
+ k_ESteamNetConnectionEnd_Remote_Timeout = 4001,
+
+ // Something was invalid with the cert or crypt handshake
+ // info you gave me, I don't understand or like your key types,
+ // etc.
+ k_ESteamNetConnectionEnd_Remote_BadCrypt = 4002,
+
+ // You presented me with a cert that was technically
+ // valid. But the CA key was missing (and I don't accept
+ // unsigned certs), or the key isn't one that I trust.
+ k_ESteamNetConnectionEnd_Remote_CertNotTrusted = 4003,
+
+ k_ESteamNetConnectionEnd_Remote_Max = 4999,
+
+ // 5xxx: Connection failed for some other reason.
+ k_ESteamNetConnectionEnd_Misc_Min = 5000,
+
+ // A failure that isn't necessarily the result of a software bug,
+ // but that should happen rarely enough that it isn't worth specifically
+ // writing UI or making a localized message for.
+ // The debug string should contain further details.
+ k_ESteamNetConnectionEnd_Misc_Generic = 5001,
+
+ // Generic failure that is most likely a software bug.
+ k_ESteamNetConnectionEnd_Misc_InternalError = 5002,
+
+ // The connection to the remote host timed out, but we
+ // don't know if the problem is on our end, in the middle,
+ // or on their end.
+ k_ESteamNetConnectionEnd_Misc_Timeout = 5003,
+
+ // We're having trouble talking to the relevant relay.
+ // We don't have enough information to say whether the
+ // problem is on our end or not.
+ k_ESteamNetConnectionEnd_Misc_RelayConnectivity = 5004,
+
+ // There's some trouble talking to Steam.
+ k_ESteamNetConnectionEnd_Misc_SteamConnectivity = 5005,
+
+ // A server in a dedicated hosting situation has no relay sessions
+ // active with which to talk back to a client. (It's the client's
+ // job to open and maintain those sessions.)
+ k_ESteamNetConnectionEnd_Misc_NoRelaySessionsToClient = 5006,
+
+ k_ESteamNetConnectionEnd_Misc_Max = 5999,
+};
+
+/// Max length of diagnostic error message
+const int k_cchMaxSteamDatagramErrMsg = 1024;
+
+/// Used to return English-language diagnostic error messages to caller.
+/// (For debugging or spewing to a console, etc. Not intended for UI.)
+typedef char SteamDatagramErrMsg[ k_cchMaxSteamDatagramErrMsg ];
+
+/// Max length, in bytes (including null terminator) of the reason string
+/// when a connection is closed.
+const int k_cchSteamNetworkingMaxConnectionCloseReason = 128;
+
+struct SteamNetConnectionInfo_t
+{
+
+ /// Handle to listen socket this was connected on, or k_HSteamListenSocket_Invalid if we initiated the connection
+ HSteamListenSocket m_hListenSocket;
+
+ /// Who is on the other end. Depending on the connection type and phase of the connection, we might not know
+ CSteamID m_steamIDRemote;
+
+ // FIXME - some sort of connection type enum?
+
+ /// Arbitrary user data set by the local application code
+ int64 m_nUserData;
+
+ /// Remote address. Might be 0 if we don't know it
+ uint32 m_unIPRemote;
+ uint16 m_unPortRemote;
+ uint16 m__pad1;
+
+ /// What data center is the remote host in? (0 if we don't know.)
+ SteamNetworkingPOPID m_idPOPRemote;
+
+ /// What relay are we using to communicate with the remote host?
+ /// (0 if not applicable.)
+ SteamNetworkingPOPID m_idPOPRelay;
+
+ /// Local port that we're bound to for this connection. Might not be applicable
+ /// for all connection types.
+ //uint16 m_unPortLocal;
+
+ /// High level state of the connection
+ int /* ESteamNetworkingConnectionState */ m_eState;
+
+ /// Basic cause of the connection termination or problem.
+ /// One of ESteamNetConnectionEnd
+ int /* ESteamNetConnectionEnd */ m_eEndReason;
+
+ /// Human-readable, but non-localized explanation for connection
+ /// termination or problem. This is intended for debugging /
+ /// diagnostic purposes only, not to display to users. It might
+ /// have some details specific to the issue.
+ char m_szEndDebug[ k_cchSteamNetworkingMaxConnectionCloseReason ];
+};
+
+/// Quick connection state, pared down to something you could call
+/// more frequently without it being too big of a perf hit.
+struct SteamNetworkingQuickConnectionStatus
+{
+
+ /// High level state of the connection
+ int /* ESteamNetworkingConnectionState */ m_eState;
+
+ /// Current ping (ms)
+ int m_nPing;
+
+ /// Connection quality measured locally, 0...1. (Percentage of packets delivered
+ /// end-to-end in order)
+ float m_flConnectionQualityLocal;
+
+ /// Packet delivery success rate as observed from remote host
+ float m_flConnectionQualityRemote;
+
+ /// Actual current data rates
+ float m_flOutPacketsPerSec;
+ float m_flOutBytesPerSec;
+ float m_flInPacketsPerSec;
+ float m_flInBytesPerSec;
+
+ /// Estimate bandwidth of the connection (bytes per second)
+ int m_nSendRate;
+
+ /// Number of bytes pending to be sent
+ int m_nPendingBytes;
+};
+
+#pragma pack( pop )
+
+enum ESteamDatagramPartner
+{
+ k_ESteamDatagramPartner_None = -1,
+ k_ESteamDatagramPartner_Steam = 0,
+ k_ESteamDatagramPartner_China = 1,
+};
+
+#endif // #ifndef STEAMNETWORKINGTYPES