#ifndef CSTEAMNETWORKINGMESSAGES_H
#define CSTEAMNETWORKINGMESSAGES_H
#pragma once
#include <tier1/utlhashmap.h>
#include <steam/steamnetworkingtypes.h>
#include <steam/isteamnetworkingmessages.h>
#include "steamnetworkingsockets_connections.h"
#ifdef STEAMNETWORKINGSOCKETS_ENABLE_STEAMNETWORKINGMESSAGES
#if defined( STEAMNETWORKINGSOCKETS_STEAMCLIENT ) || defined( STEAMNETWORKINGSOCKETS_STREAMINGCLIENT )
#include <steam/iclientnetworkingmessages.h>
#else
typedef ISteamNetworkingMessages IClientNetworkingMessages;
#endif
class CMsgSteamDatagramConnectRequest;
namespace SteamNetworkingSocketsLib {
class CSteamNetworkingSockets;
class CSteamNetworkingMessage;
class CSteamNetworkingMessages;
class CSteamNetworkConnectionP2P;
class CSteamNetworkListenSocketP2P;
struct SteamNetworkingMessagesSession;
class CMessagesEndPoint
{
public:
CSteamNetworkingSockets &m_steamNetworkingSockets;
const int m_nLocalVirtualPort;
virtual bool BHandleNewIncomingConnection( CSteamNetworkConnectionBase *pConn, ConnectionScopeLock &connectionLock ) = 0;
void DestroyMessagesEndPoint();
CSteamNetworkListenSocketP2P *m_pListenSocket = nullptr;
ConnectionLock m_sharedConnectionLock;
protected:
bool BInit();
bool BCreateListenSocket();
CMessagesEndPoint( CSteamNetworkingSockets &steamNetworkingSockets, int nLocalVirtualPort );
virtual ~CMessagesEndPoint();
virtual void FreeResources();
};
class CMessagesEndPointSession : public ILockableThinker<ConnectionLock>
{
public:
SteamNetworkingIdentity m_identityRemote;
CMessagesEndPoint &m_messageEndPointOwner;
CSteamNetworkConnectionBase *m_pConnection;
vstd::small_vector<CSteamNetworkConnectionBase *, 2> m_vecLinkedConnections;
void SessionConnectionStateChanged( CSteamNetworkConnectionBase *pConn, ESteamNetworkingConnectionState eOldState );
SteamNetworkingMicroseconds m_usecIdleTimeout;
bool m_bAppScheduledTimeout;
bool m_bConnectionWasEverConnected;
bool m_bConnectionStateChanged;
void MarkUsed( SteamNetworkingMicroseconds usecNow );
void ScheduleThink();
virtual void SetActiveConnection( CSteamNetworkConnectionBase *pConn, ConnectionScopeLock &connectionLock );
virtual void ClearActiveConnection();
virtual void ReceivedMessage( CSteamNetworkingMessage *pMsg, CSteamNetworkConnectionBase *pConn ) = 0;
void UnlinkFromInactiveConnections();
void UnlinkConnectionNow( CSteamNetworkConnectionBase *pConn );
protected:
CMessagesEndPointSession( const SteamNetworkingIdentity &identityRemote, CMessagesEndPoint &endPoint );
virtual ~CMessagesEndPointSession();
virtual void ActiveConnectionStateChanged();
};
class CSteamNetworkingMessages final : public CMessagesEndPoint, public IClientNetworkingMessages
{
public:
STEAMNETWORKINGSOCKETS_DECLARE_CLASS_OPERATOR_NEW
CSteamNetworkingMessages( CSteamNetworkingSockets &steamNetworkingSockets );
bool BInit();
virtual EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const void *pubData, uint32 cubData, int nSendFlags, int nChannel ) override;
virtual int ReceiveMessagesOnChannel( int nChannel, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) override;
virtual bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) override;
virtual bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) override;
virtual bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nChannel ) override;
virtual ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingIdentity &identityRemote, SteamNetConnectionInfo_t *pConnectionInfo, SteamNetConnectionRealTimeStatus_t *pQuickStatus ) override;
#ifdef DBGFLAG_VALIDATE
virtual void Validate( CValidator &validator, const char *pchName ) override;
#endif
virtual bool BHandleNewIncomingConnection( CSteamNetworkConnectionBase *pConn, ConnectionScopeLock &connectionLock ) override;
struct Channel
{
Channel();
~Channel();
SteamNetworkingMessageQueue m_queueRecvMessages;
};
Channel *FindOrCreateChannel( int nChannel );
void DestroySession( const SteamNetworkingIdentity &identityRemote );
#ifdef DBGFLAG_VALIDATE
static void ValidateStatics( CValidator &validator );
#endif
private:
SteamNetworkingMessagesSession *FindSession( const SteamNetworkingIdentity &identityRemote, ConnectionScopeLock &scopeLock );
SteamNetworkingMessagesSession *FindOrCreateSession( const SteamNetworkingIdentity &identityRemote, ConnectionScopeLock &scopeLock );
CUtlHashMap< SteamNetworkingIdentity, SteamNetworkingMessagesSession *, std::equal_to<SteamNetworkingIdentity>, SteamNetworkingIdentityHash > m_mapSessions;
CUtlHashMap<int,Channel*,std::equal_to<int>,std::hash<int>> m_mapChannels;
virtual void FreeResources() override;
virtual ~CSteamNetworkingMessages();
};
struct SteamNetworkingMessagesSession final : public CMessagesEndPointSession
{
SteamNetworkingMessagesSession( const SteamNetworkingIdentity &identityRemote, CSteamNetworkingMessages &steamNetworkingP2P );
virtual ~SteamNetworkingMessagesSession();
CSteamNetworkingMessages &MessagesOwner() const { return static_cast<CSteamNetworkingMessages &>( m_messageEndPointOwner ); }
SteamNetworkingMessageQueue m_queueRecvMessages;
CUtlHashMap<int,bool,std::equal_to<int>,std::hash<int>> m_mapOpenChannels;
SteamNetConnectionInfo_t m_lastConnectionInfo;
SteamNetConnectionRealTimeStatus_t m_lastQuickStatus;
virtual void Think( SteamNetworkingMicroseconds usecNow ) override;
virtual void SetActiveConnection( CSteamNetworkConnectionBase *pConn, ConnectionScopeLock &connectionLock ) override;
virtual void ActiveConnectionStateChanged() override;
virtual void ReceivedMessage( CSteamNetworkingMessage *pMsg, CSteamNetworkConnectionBase *pConn ) override;
void CloseConnection( int nReason, const char *pszDebug );
void CheckConnection( SteamNetworkingMicroseconds usecNow );
void UpdateConnectionInfo();
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, const char *pchName );
#endif
};
}
#endif
#endif