gbe_fork/sdk_includes/isteamnetworkingmessages.h

187 lines
9.9 KiB
C
Raw Normal View History

2020-09-15 07:53:56 +08:00
//====== Copyright Valve Corporation, All rights reserved. ====================
#ifndef ISTEAMNETWORKINGMESSAGES
#define ISTEAMNETWORKINGMESSAGES
#ifdef STEAM_WIN32
#pragma once
#endif
#include "steamnetworkingtypes.h"
//-----------------------------------------------------------------------------
/// The non-connection-oriented interface to send and receive messages
/// (whether they be "clients" or "servers").
///
/// ISteamNetworkingSockets is connection-oriented (like TCP), meaning you
/// need to listen and connect, and then you send messages using a connection
/// handle. ISteamNetworkingMessages is more like UDP, in that you can just send
/// messages to arbitrary peers at any time. The underlying connections are
/// established implicitly.
///
/// Under the hood ISteamNetworkingMessages works on top of the ISteamNetworkingSockets
/// code, so you get the same routing and messaging efficiency. The difference is
/// mainly in your responsibility to explicitly establish a connection and
/// the type of feedback you get about the state of the connection. Both
/// interfaces can do "P2P" communications, and both support both unreliable
/// and reliable messages, fragmentation and reassembly.
///
/// The primary purpose of this interface is to be "like UDP", so that UDP-based code
/// can be ported easily to take advantage of relayed connections. If you find
/// yourself needing more low level information or control, or to be able to better
/// handle failure, then you probably need to use ISteamNetworkingSockets directly.
/// Also, note that if your main goal is to obtain a connection between two peers
/// without concerning yourself with assigning roles of "client" and "server",
/// you may find the symmetric connection mode of ISteamNetworkingSockets useful.
/// (See k_ESteamNetworkingConfig_SymmetricConnect.)
///
class ISteamNetworkingMessages
{
public:
/// Sends a message to the specified host. If we don't already have a session with that user,
/// a session is implicitly created. There might be some handshaking that needs to happen
/// before we can actually begin sending message data. If this handshaking fails and we can't
/// get through, an error will be posted via the callback SteamNetworkingMessagesSessionFailed_t.
/// There is no notification when the operation succeeds. (You should have the peer send a reply
/// for this purpose.)
///
/// Sending a message to a host will also implicitly accept any incoming connection from that host.
///
/// nSendFlags is a bitmask of k_nSteamNetworkingSend_xxx options
///
/// nRemoteChannel is a routing number you can use to help route message to different systems.
/// You'll have to call ReceiveMessagesOnChannel() with the same channel number in order to retrieve
/// the data on the other end.
///
/// Using different channels to talk to the same user will still use the same underlying
/// connection, saving on resources. If you don't need this feature, use 0.
/// Otherwise, small integers are the most efficient.
///
/// It is guaranteed that reliable messages to the same host on the same channel
/// will be be received by the remote host (if they are received at all) exactly once,
/// and in the same order that they were send.
///
/// NO other order guarantees exist! In particular, unreliable messages may be dropped,
/// received out of order with respect to each other and with respect to reliable data,
/// or may be received multiple times. Messages on different channels are *not* guaranteed
/// to be received in the order they were sent.
///
/// A note for those familiar with TCP/IP ports, or converting an existing codebase that
/// opened multiple sockets: You might notice that there is only one channel, and with
/// TCP/IP each endpoint has a port number. You can think of the channel number as the
/// *destination* port. If you need each message to also include a "source port" (so the
/// recipient can route the reply), then just put that in your message. That is essentially
/// how UDP works!
///
/// Returns:
/// - k_EREsultOK on success.
/// - k_EResultNoConnection will be returned if the session has failed or was closed by the peer,
/// and k_nSteamNetworkingSend_AutoRestartBrokwnSession is not used. (You can use
/// GetSessionConnectionInfo to get the details.) In order to acknowledge the broken session
/// and start a new one, you must call CloseSessionWithUser
/// - See SendMessageToConnection::SendMessageToConnection for more
virtual EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const void *pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ) = 0;
/// Reads the next message that has been sent from another user via SendMessageToUser() on the given channel.
/// Returns number of messages returned into your list. (0 if no message are available on that channel.)
///
/// When you're done with the message object(s), make sure and call Release()!
virtual int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0;
/// AcceptSessionWithUser() should only be called in response to a SteamP2PSessionRequest_t callback
/// SteamP2PSessionRequest_t will be posted if another user tries to send you a message, and you haven't
/// tried to talk to them. If you don't want to talk to them, just ignore the request.
/// If the user continues to send you messages, SteamP2PSessionRequest_t callbacks will continue to
/// be posted periodically. This may be called multiple times for a single user.
///
/// Calling SendMessage() on the other user, this implicitly accepts any pending session request.
virtual bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0;
/// Call this when you're done talking to a user to immediately free up resources under-the-hood.
/// If the remote user tries to send data to you again, another P2PSessionRequest_t callback will
/// be posted.
///
/// Note that sessions that go unused for a few minutes are automatically timed out.
virtual bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0;
/// Call this when you're done talking to a user on a specific channel. Once all
/// open channels to a user have been closed, the open session to the user will be
/// closed, and any new data from this user will trigger a SteamP2PSessionRequest_t
/// callback
virtual bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nLocalChannel ) = 0;
/// Returns information about the latest state of a connection, if any, with the given peer.
/// Primarily intended for debugging purposes, but can also be used to get more detailed
/// failure information. (See SendMessageToUser and k_nSteamNetworkingSend_AutoRestartBrokwnSession.)
///
/// Returns the value of SteamNetConnectionInfo_t::m_eState, or k_ESteamNetworkingConnectionState_None
/// if no connection exists with specified peer. You may pass nullptr for either parameter if
/// you do not need the corresponding details. Note that sessions time out after a while,
/// so if a connection fails, or SendMessageToUser returns SendMessageToUser, you cannot wait
/// indefinitely to obtain the reason for failure.
virtual ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingIdentity &identityRemote, SteamNetConnectionInfo_t *pConnectionInfo, SteamNetworkingQuickConnectionStatus *pQuickStatus ) = 0;
};
#define STEAMNETWORKINGMESSAGES_VERSION "SteamNetworkingMessages002"
//
// Callbacks
//
#pragma pack( push, 1 )
/// Posted when a remote host is sending us a message, and we do not already have a session with them
struct SteamNetworkingMessagesSessionRequest_t
{
enum { k_iCallback = k_iSteamNetworkingMessagesCallbacks + 1 };
SteamNetworkingIdentity m_identityRemote; // user who wants to talk to us
};
/// Posted when we fail to establish a connection, or we detect that communications
/// have been disrupted it an unusual way. There is no notification when a peer proactively
/// closes the session. ("Closed by peer" is not a concept of UDP-style communications, and
/// SteamNetworkingMessages is primarily intended to make porting UDP code easy.)
///
/// Remember: callbacks are asynchronous. See notes on SendMessageToUser,
/// and k_nSteamNetworkingSend_AutoRestartBrokwnSession in particular.
///
/// Also, if a session times out due to inactivity, no callbacks will be posted. The only
/// way to detect that this is happening is that querying the session state may return
/// none, connecting, and findingroute again.
struct SteamNetworkingMessagesSessionFailed_t
{
enum { k_iCallback = k_iSteamNetworkingMessagesCallbacks + 2 };
/// Detailed info about the connection. This will include the
SteamNetConnectionInfo_t m_info;
};
#pragma pack(pop)
//
// Global accessor
//
#if defined( STEAMNETWORKINGSOCKETS_PARTNER )
// Standalone lib. Use different symbol name, so that we can dynamically switch between steamclient.dll
// and the standalone lib
STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages_Lib();
STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamGameServerNetworkingMessages_Lib();
inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_Lib(); }
inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_Lib(); }
#elif defined( STEAMNETWORKINGSOCKETS_OPENSOURCE )
// Opensource GameNetworkingSockets
STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages();
#else
// Steamworks SDK
inline ISteamNetworkingMessages *SteamNetworkingMessages();
STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamNetworkingMessages, STEAMNETWORKINGMESSAGES_VERSION );
inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages();
STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamGameServerNetworkingMessages, STEAMNETWORKINGMESSAGES_VERSION );
#endif
#endif // ISTEAMNETWORKINGMESSAGES