From 51b3fa95ed3dda81708e984e55c4fb2328d381ef Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 18 Nov 2020 10:15:24 -0500 Subject: [PATCH] ISteamNetworkingSockets004 --- dll/steam_client.cpp | 4 +- dll/steam_networking_sockets.h | 31 ++ sdk_includes/isteamnetworkingsockets004.h | 463 ++++++++++++++++++++++ sdk_includes/steam_api.h | 1 + 4 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 sdk_includes/isteamnetworkingsockets004.h diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index cb435a5..a3c9f84 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -494,6 +494,8 @@ void *Steam_Client::GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe return (void *)(ISteamNetworkingSockets002 *) steam_networking_sockets_temp; } else if (strcmp(pchVersion, "SteamNetworkingSockets003") == 0) { return (void *)(ISteamNetworkingSockets003 *) steam_networking_sockets_temp; + } else if (strcmp(pchVersion, "SteamNetworkingSockets004") == 0) { + return (void *)(ISteamNetworkingSockets004 *) steam_networking_sockets_temp; } else if (strcmp(pchVersion, "SteamNetworkingSockets006") == 0) { return (void *)(ISteamNetworkingSockets006 *) steam_networking_sockets_temp; } else if (strcmp(pchVersion, "SteamNetworkingSockets008") == 0) { @@ -1572,4 +1574,4 @@ void Steam_Client::RunCallbacks(bool runClientCB, bool runGameserverCB) void Steam_Client::DestroyAllInterfaces() { PRINT_DEBUG("Steam_Client::DestroyAllInterfaces\n"); -} \ No newline at end of file +} diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index 509f1c9..804eed7 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -53,6 +53,7 @@ class Steam_Networking_Sockets : public ISteamNetworkingSockets001, public ISteamNetworkingSockets002, public ISteamNetworkingSockets003, +public ISteamNetworkingSockets004, public ISteamNetworkingSockets006, public ISteamNetworkingSockets008, public ISteamNetworkingSockets @@ -255,6 +256,12 @@ HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddre return k_HSteamListenSocket_Invalid; } +HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr *localAddress ) +{ + PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketIP old1\n"); + return k_HSteamListenSocket_Invalid; +} + HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddress, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketIP\n"); @@ -285,6 +292,12 @@ HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address ) return k_HSteamNetConnection_Invalid; } +HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr *address ) +{ + PRINT_DEBUG("Steam_Networking_Sockets::ConnectByIPAddress old1\n"); + return k_HSteamNetConnection_Invalid; +} + HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) { PRINT_DEBUG("Steam_Networking_Sockets::ConnectByIPAddress\n"); @@ -349,6 +362,12 @@ HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, i return socket; } +HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity *identityRemote, int nVirtualPort ) +{ + PRINT_DEBUG("Steam_Networking_Sockets::ConnectP2P old1\n"); + return ConnectP2P(*identityRemote, nVirtualPort); +} + HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) { PRINT_DEBUG("Steam_Networking_Sockets::ConnectP2P %i\n", nVirtualPort); @@ -1187,6 +1206,12 @@ int FindRelayAuthTicketForServer( CSteamID steamID, int nVirtualPort, SteamDatag /// /// Typically this is useful just to confirm that you have a ticket, before you /// call ConnectToHostedDedicatedServer to connect to the server. +int FindRelayAuthTicketForServer( const SteamNetworkingIdentity *identityGameServer, int nVirtualPort, SteamDatagramRelayAuthTicket *pOutParsedTicket ) +{ + PRINT_DEBUG("Steam_Networking_Sockets::FindRelayAuthTicketForServer old1\n"); + return 0; +} + int FindRelayAuthTicketForServer( const SteamNetworkingIdentity &identityGameServer, int nVirtualPort, SteamDatagramRelayAuthTicket *pOutParsedTicket ) { PRINT_DEBUG("Steam_Networking_Sockets::FindRelayAuthTicketForServer\n"); @@ -1208,6 +1233,12 @@ HSteamNetConnection ConnectToHostedDedicatedServer( const SteamNetworkingIdentit return k_HSteamListenSocket_Invalid; } +HSteamNetConnection ConnectToHostedDedicatedServer( const SteamNetworkingIdentity *identityTarget, int nVirtualPort ) +{ + PRINT_DEBUG("Steam_Networking_Sockets::ConnectToHostedDedicatedServer old1\n"); + return k_HSteamListenSocket_Invalid; +} + /// Client call to connect to a server hosted in a Valve data center, on the specified virtual /// port. You should have received a ticket for this server, or else this connect call will fail! /// diff --git a/sdk_includes/isteamnetworkingsockets004.h b/sdk_includes/isteamnetworkingsockets004.h new file mode 100644 index 0000000..bab1478 --- /dev/null +++ b/sdk_includes/isteamnetworkingsockets004.h @@ -0,0 +1,463 @@ + +#ifndef ISTEAMNETWORKINGSOCKETS004 +#define ISTEAMNETWORKINGSOCKETS004 + + +class ISteamNetworkingSockets004 +{ +public: + + /// Creates a "server" socket that listens for clients to connect to by + /// calling ConnectByIPAddress, over ordinary UDP (IPv4 or IPv6) + /// + /// You must select a specific local port to listen on and set it + /// the port field of the local address. + /// + /// Usually you wil set the IP portion of the address to zero, (SteamNetworkingIPAddr::Clear()). + /// This means that you will not bind to any particular local interface. In addition, + /// if possible the socket will be bound in "dual stack" mode, which means that it can + /// accept both IPv4 and IPv6 clients. If you wish to bind a particular interface, then + /// set the local address to the appropriate IPv4 or IPv6 IP. + /// + /// When a client attempts to connect, a SteamNetConnectionStatusChangedCallback_t + /// will be posted. The connection will be in the connecting state. + virtual HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr *localAddress ) = 0; + + /// Creates a connection and begins talking to a "server" over UDP at the + /// given IPv4 or IPv6 address. The remote host must be listening with a + /// matching call to CreateListenSocketIP on the specified port. + /// + /// A SteamNetConnectionStatusChangedCallback_t callback will be triggered when we start + /// connecting, and then another one on either timeout or successful connection. + /// + /// If the server does not have any identity configured, then their network address + /// will be the only identity in use. Or, the network host may provide a platform-specific + /// identity with or without a valid certificate to authenticate that identity. (These + /// details will be contained in the SteamNetConnectionStatusChangedCallback_t.) It's + /// up to your application to decide whether to allow the connection. + /// + /// By default, all connections will get basic encryption sufficient to prevent + /// casual eavesdropping. But note that without certificates (or a shared secret + /// distributed through some other out-of-band mechanism), you don't have any + /// way of knowing who is actually on the other end, and thus are vulnerable to + /// man-in-the-middle attacks. + virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr *address ) = 0; + +#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR + /// Like CreateListenSocketIP, but clients will connect using ConnectP2P + /// + /// nVirtualPort specifies how clients can connect to this socket using + /// ConnectP2P. 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 nVirtualPort should be a small integer (<1000) + /// unique to each listen socket you create. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes + virtual HSteamListenSocket CreateListenSocketP2P( int nVirtualPort ) = 0; + + /// Begin connecting to a server that is identified using a platform-specific identifier. + /// This requires some sort of third party rendezvous service, and will depend on the + /// platform and what other libraries and services you are integrating with. + /// + /// At the time of this writing, there is only one supported rendezvous service: Steam. + /// Set the SteamID (whether "user" or "gameserver") and Steam will determine if the + /// client is online and facilitate a relay connection. Note that all P2P connections on + /// Steam are currently relayed. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes + virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity *identityRemote, int nVirtualPort ) = 0; +#endif + + /// 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 either into the connected state, + /// or the finding route state, depending on the connection type. + /// + /// You should take action within a second or two, 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 (for example, while loading a map), then there is a chance + /// that a client may attempt to connect in that interval and fail due to 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 depending the exact + /// sequence of events. + /// + /// 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. All the connections that were accepting on the listen + /// socket are closed ungracefully. + virtual bool CloseListenSocket( HSteamListenSocket hSocket ) = 0; + + /// Set connection user data. the data is returned in the following places + /// - You can query it using GetConnectionUserData. + /// - The SteamNetworkingmessage_t structure. + /// - The SteamNetConnectionInfo_t structure. (Which is a member of SteamNetConnectionStatusChangedCallback_t.) + /// + /// 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 name. Returns false if handle is invalid + virtual bool GetConnectionName( HSteamNetConnection hPeer, char *pszName, int nMaxLen ) = 0; + + /// Send a message to the remote host on the specified connection. + /// + /// nSendFlags determines the delivery guarantees that will be provided, + /// when data should be buffered, etc. E.g. k_nSteamNetworkingSend_Unreliable + /// + /// 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 + /// message 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. + /// + /// Returns: + /// - k_EResultInvalidParam: invalid connection handle, or the individual message is too big. + /// (See k_cbMaxSteamNetworkingSocketsMessageSizeSend) + /// - k_EResultInvalidState: connection is in an invalid state + /// - k_EResultNoConnection: connection has ended + /// - k_EResultIgnored: You used k_nSteamNetworkingSend_NoDelay, and the message was dropped because + /// we were not ready to send it. + /// - k_EResultLimitExceeded: there was already too much data queued to be sent. + /// (See k_ESteamNetworkingConfig_SendBufferSize) + virtual EResult SendMessageToConnection( HSteamNetConnection hConn, const void *pData, uint32 cbData, int nSendFlags ) = 0; + + /// Flush any messages waiting on the Nagle timer and send them + /// at the next transmission opportunity (often that means right now). + /// + /// If Nagle is enabled (it's on by default) then when calling + /// SendMessageToConnection the message will be buffered, up to the Nagle time + /// before being sent, to merge small messages into the same packet. + /// (See k_ESteamNetworkingConfig_NagleTime) + /// + /// Returns: + /// k_EResultInvalidParam: invalid connection handle + /// k_EResultInvalidState: connection is in an invalid state + /// k_EResultNoConnection: connection has ended + /// k_EResultIgnored: We weren't (yet) connected, so this operation has no effect. + virtual EResult FlushMessagesOnConnection( HSteamNetConnection hConn ) = 0; + + /// Fetch the next available message(s) from the connection, 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). + /// + /// Unreliable messages may be dropped, or delivered out of order withrespect to + /// each other or with respect to reliable messages. The same unreliable message + /// may be received multiple times. + /// + /// If any messages are returned, you MUST call SteamNetworkingMessage_t::Release() on 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, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + /// Same as ReceiveMessagesOnConnection, but will return the next message available + /// on any connection that was accepted through the specified listen socket. Examine + /// SteamNetworkingMessage_t::m_conn 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, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + /// Returns basic information about the high-level state of the connection. + virtual bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) = 0; + + /// Returns a small set of information about the real-time state of the connection + /// Returns false if the connection handle is invalid, or the connection has ended. + 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 local IP and port that a listen socket created using CreateListenSocketIP is bound to. + /// + /// An IPv6 address of ::0 means "any IPv4 or IPv6" + /// An IPv6 address of ::ffff:0000:0000 means "any IPv4" + virtual bool GetListenSocketAddress( HSteamListenSocket hSocket, SteamNetworkingIPAddr *address ) = 0; + + /// Create a pair of connections that are talking to each other, e.g. a loopback connection. + /// This is very useful for testing, or so that your client/server code can work the same + /// even when you are running a local "server". + /// + /// The two connections will immediately be placed into the connected state, and no callbacks + /// will be posted immediately. After this, if you close either connection, the other connection + /// will receive a callback, exactly as if they were communicating over the network. You must + /// close *both* sides in order to fully clean up the resources! + /// + /// By default, internal buffers are used, completely bypassing the network, the chopping up of + /// messages into packets, encryption, copying the payload, etc. This means that loopback + /// packets, by default, will not simulate lag or loss. Passing true for bUseNetworkLoopback will + /// cause the socket pair to send packets through the local network loopback device (127.0.0.1) + /// on ephemeral ports. Fake lag and loss are supported in this case, and CPU time is expended + /// to encrypt and decrypt. + /// + /// If you wish to assign a specific identity to either connection, you may pass a particular + /// identity. Otherwise, if you pass nullptr, the respective connection will assume a generic + /// "localhost" identity. If you use real network loopback, this might be translated to the + /// actual bound loopback port. Otherwise, the port will be zero. + virtual bool CreateSocketPair( HSteamNetConnection *pOutConnection1, HSteamNetConnection *pOutConnection2, bool bUseNetworkLoopback, const SteamNetworkingIdentity *pIdentity1, const SteamNetworkingIdentity *pIdentity2 ) = 0; + + /// Get the identity assigned to this interface. + /// E.g. on Steam, this is the user's SteamID, or for the gameserver interface, the SteamID assigned + /// to the gameserver. Returns false and sets the result to an invalid identity if we don't know + /// our identity yet. (E.g. GameServer has not logged in. On Steam, the user will know their SteamID + /// even if they are not signed into Steam.) + virtual bool GetIdentity( SteamNetworkingIdentity *pIdentity ) = 0; + + /// Indicate our desire to be ready participate in authenticated communications. + /// If we are currently not ready, then steps will be taken to obtain the necessary + /// certificates. (This includes a certificate for us, as well as any CA certificates + /// needed to authenticate peers.) + /// + /// You can call this at program init time if you know that you are going to + /// be making authenticated connections, so that we will be ready immediately when + /// those connections are attempted. (Note that essentially all connections require + /// authentication, with the exception of ordinary UDP connections with authentication + /// disabled using k_ESteamNetworkingConfig_IP_AllowWithoutAuth.) If you don't call + /// this function, we will wait until a feature is utilized that that necessitates + /// these resources. + /// + /// You can also call this function to force a retry, if failure has occurred. + /// Once we make an attempt and fail, we will not automatically retry. + /// In this respect, the behavior of the system after trying and failing is the same + /// as before the first attempt: attempting authenticated communication or calling + /// this function will call the system to attempt to acquire the necessary resources. + /// + /// You can use GetAuthenticationStatus or listen for SteamNetAuthenticationStatus_t + /// to monitor the status. + /// + /// Returns the current value that would be returned from GetAuthenticationStatus. + virtual ESteamNetworkingAvailability InitAuthentication() = 0; + + /// Query our readiness to participate in authenticated communications. A + /// SteamNetAuthenticationStatus_t callback is posted any time this status changes, + /// but you can use this function to query it at any time. + /// + /// The value of SteamNetAuthenticationStatus_t::m_eAvail is returned. If you only + /// want this high level status, you can pass NULL for pDetails. If you want further + /// details, pass non-NULL to receive them. + virtual ESteamNetworkingAvailability GetAuthenticationStatus( SteamNetAuthenticationStatus_t *pDetails ) = 0; + +/// Certificate provision by the application. (On Steam, Steam will handle all this automatically) +#ifndef STEAMNETWORKINGSOCKETS_STEAM + + /// Get blob that describes a certificate request. You can send this to your game coordinator. + /// Upon entry, *pcbBlob should contain the size of the buffer. On successful exit, it will + /// return the number of bytes that were populated. You can pass pBlob=NULL to query for the required + /// size. (256 bytes is a very conservative estimate.) + /// + /// Pass this blob to your game coordinator and call SteamDatagram_CreateCert. + virtual bool GetCertificateRequest( int *pcbBlob, void *pBlob, SteamNetworkingErrMsg &errMsg ) = 0; + + /// Set the certificate. The certificate blob should be the output of + /// SteamDatagram_CreateCert. + virtual bool SetCertificate( const void *pCertificate, int cbCertificate, SteamNetworkingErrMsg &errMsg ) = 0; + +#endif + +#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR + + // + // Clients connecting to dedicated servers hosted in a data center, + // using central-authority-granted tickets. + // + + /// Call this when you receive a ticket from your backend / matchmaking system. Puts the + /// ticket into a persistent cache, and optionally returns the parsed ticket. + /// + /// See stamdatagram_ticketgen.h for more details. + virtual bool ReceivedRelayAuthTicket( const void *pvTicket, int cbTicket, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0; + + /// Search cache for a ticket to talk to the server on the specified virtual port. + /// If found, returns the number of seconds until the ticket expires, and optionally + /// the complete cracked ticket. Returns 0 if we don't have a ticket. + /// + /// Typically this is useful just to confirm that you have a ticket, before you + /// call ConnectToHostedDedicatedServer to connect to the server. + virtual int FindRelayAuthTicketForServer( const SteamNetworkingIdentity *identityGameServer, int nVirtualPort, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0; + + /// Client call to connect to a server hosted in a Valve data center, on the specified virtual + /// port. You must have placed a ticket for this server into the cache, or else this connect attempt will fail! + /// + /// You may wonder why tickets are stored in a cache, instead of simply being passed as an argument + /// here. The reason is to make reconnection to a gameserver robust, even if the client computer loses + /// connection to Steam or the central backend, or the app is restarted or crashes, etc. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes + virtual HSteamNetConnection ConnectToHostedDedicatedServer( const SteamNetworkingIdentity *identityTarget, int nVirtualPort ) = 0; + + // + // Servers hosted in data centers known to the Valve relay network + // + + /// Returns the value of the SDR_LISTEN_PORT environment variable. This + /// is the UDP server your server will be listening on. This will + /// configured automatically for you in production environments. + /// + /// In development, you'll need to set it yourself. See + /// https://partner.steamgames.com/doc/api/ISteamNetworkingSockets + /// for more information on how to configure dev environments. + virtual uint16 GetHostedDedicatedServerPort() = 0; + + /// Returns 0 if SDR_LISTEN_PORT is not set. Otherwise, returns the data center the server + /// is running in. This will be k_SteamDatagramPOPID_dev in non-production envirionment. + virtual SteamNetworkingPOPID GetHostedDedicatedServerPOPID() = 0; + + /// Return info about the hosted server. This contains the PoPID of the server, + /// and opaque routing information that can be used by the relays to send traffic + /// to your server. + /// + /// You will need to send this information to your backend, and put it in tickets, + /// so that the relays will know how to forward traffic from + /// clients to your server. See SteamDatagramRelayAuthTicket for more info. + /// + /// Also, note that the routing information is contained in SteamDatagramGameCoordinatorServerLogin, + /// so if possible, it's preferred to use GetGameCoordinatorServerLogin to send this info + /// to your game coordinator service, and also login securely at the same time. + /// + /// On a successful exit, k_EResultOK is returned + /// + /// Unsuccessful exit: + /// - Something other than k_EResultOK is returned. + /// - k_EResultInvalidState: We are not configured to listen for SDR (SDR_LISTEN_SOCKET + /// is not set.) + /// - k_EResultPending: we do not (yet) have the authentication information needed. + /// (See GetAuthenticationStatus.) If you use environment variables to pre-fetch + /// the network config, this data should always be available immediately. + /// - A non-localized diagnostic debug message will be placed in m_data that describes + /// the cause of the failure. + /// + /// NOTE: The returned blob is not encrypted. Send it to your backend, but don't + /// directly share it with clients. + virtual EResult GetHostedDedicatedServerAddress( SteamDatagramHostedAddress *pRouting ) = 0; + + /// Create a listen socket on the specified virtual port. The physical UDP port to use + /// will be determined by the SDR_LISTEN_PORT environment variable. If a UDP port is not + /// configured, this call will fail. + /// + /// Note that this call MUST be made through the SteamGameServerNetworkingSockets() interface + virtual HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nVirtualPort ) = 0; + + /// Generate an authentication blob that can be used to securely login with + /// your backend, using SteamDatagram_ParseHostedServerLogin. (See + /// steamdatagram_gamecoordinator.h) + /// + /// Before calling the function: + /// - Populate the app data in pLoginInfo (m_cbAppData and m_appData). You can leave + /// all other fields uninitialized. + /// - *pcbSignedBlob contains the size of the buffer at pBlob. (It should be + /// at least k_cbMaxSteamDatagramGameCoordinatorServerLoginSerialized.) + /// + /// On a successful exit: + /// - k_EResultOK is returned + /// - All of the remaining fields of pLoginInfo will be filled out. + /// - *pcbSignedBlob contains the size of the serialized blob that has been + /// placed into pBlob. + /// + /// Unsuccessful exit: + /// - Something other than k_EResultOK is returned. + /// - k_EResultNotLoggedOn: you are not logged in (yet) + /// - See GetHostedDedicatedServerAddress for more potential failure return values. + /// - A non-localized diagnostic debug message will be placed in pBlob that describes + /// the cause of the failure. + /// + /// This works by signing the contents of the SteamDatagramGameCoordinatorServerLogin + /// with the cert that is issued to this server. In dev environments, it's OK if you do + /// not have a cert. (You will need to enable insecure dev login in SteamDatagram_ParseHostedServerLogin.) + /// Otherwise, you will need a signed cert. + /// + /// NOTE: The routing blob returned here is not encrypted. Send it to your backend + /// and don't share it directly with clients. + virtual EResult GetGameCoordinatorServerLogin( SteamDatagramGameCoordinatorServerLogin *pLoginInfo, int *pcbSignedBlob, void *pBlob ) = 0; + +#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR + + // Invoke all callbacks queued for this interface. + // On Steam, callbacks are dispatched via the ordinary Steamworks callbacks mechanism. + // So if you have code that is also targeting Steam, you should call this at about the + // same time you would call SteamAPI_RunCallbacks and SteamGameServer_RunCallbacks. +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB + virtual void RunCallbacks( ISteamNetworkingSocketsCallbacks *pCallbacks ) = 0; +#endif +protected: +// ~ISteamNetworkingSockets(); // Silence some warnings +}; + +#endif // ISTEAMNETWORKINGSOCKETS004 diff --git a/sdk_includes/steam_api.h b/sdk_includes/steam_api.h index 10d0eac..15c93db 100644 --- a/sdk_includes/steam_api.h +++ b/sdk_includes/steam_api.h @@ -107,6 +107,7 @@ #include "isteamnetworkingsockets001.h" #include "isteamnetworkingsockets002.h" #include "isteamnetworkingsockets003.h" +#include "isteamnetworkingsockets004.h" #include "isteamnetworkingsockets006.h" #include "isteamnetworkingsockets008.h" #include "isteamremotestorage.h"