Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

564 lines
11 KiB

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// netadr.h
#ifndef NS_ADDRESS_H
#define NS_ADDRESS_H
#pragma once
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "tier1/netadr.h"
#include "steam/steamclientpublic.h" // for CSteamID
#include "tier1/strtools.h" // V_memset
#if defined( NO_STEAM )
typedef CSteamID uint64;
#endif
enum PeerToPeerAddressType_t
{
P2P_STEAMID,
};
// Build int subchannel types
// FIXME - these really are game specific. I wish we could standardize!
enum SteamPeerToPeerChannel_t
{
STEAM_P2P_GAME_CLIENT = 0,
STEAM_P2P_GAME_SERVER = 1,
STEAM_P2P_LOBBY = 2,
STEAM_P2P_HLTV = 3,
STEAM_P2P_HLTV1 = 4,
};
class CPeerToPeerAddress
{
public:
CPeerToPeerAddress ( void )
: m_AddrType( P2P_STEAMID )
, m_steamChannel( STEAM_P2P_GAME_CLIENT )
{}
void Clear ( void )
{
m_AddrType = P2P_STEAMID;
m_steamID.Clear();
m_steamChannel = STEAM_P2P_GAME_CLIENT;
}
void SetSteamChannel( int nChannel )
{
m_steamChannel = nChannel;
}
int GetSteamChannel() const
{
return m_steamChannel;
}
const CSteamID &GetSteamID() const
{
return m_steamID;
}
CPeerToPeerAddress ( const CSteamID &steamID, int nSteamChannel )
: m_AddrType ( P2P_STEAMID )
, m_steamID ( steamID )
, m_steamChannel( nSteamChannel )
{
}
private:
// disallow since we can't deal with steamchannel
CPeerToPeerAddress &operator=(const CSteamID &steamID);
public:
// Like operator =
CPeerToPeerAddress &SetFromSteamID( const CSteamID &steamID, int nSteamChannel )
{
m_AddrType = P2P_STEAMID;
m_steamID = steamID;
m_steamChannel = nSteamChannel;
return *this;
}
bool IsValid ( void ) const
{
switch ( m_AddrType )
{
case P2P_STEAMID:
return m_steamID.IsValid ( );
};
return false;
}
const char *ToString ( void ) const
{
switch ( m_AddrType )
{
case P2P_STEAMID:
return m_steamID.Render ( );
};
return "";
}
bool CompareAdr ( const CPeerToPeerAddress &other, bool onlyBase = false ) const
{
if ( m_AddrType != -other.m_AddrType )
return false;
switch ( m_AddrType )
{
case P2P_STEAMID:
return ((m_steamID == other.m_steamID) && (m_steamChannel == other.m_steamChannel));
};
return false;
}
bool operator==(const CPeerToPeerAddress &rhs) const
{
return CompareAdr( rhs, false );
}
PeerToPeerAddressType_t GetAddressType ( void ) const
{
return m_AddrType;
}
template <typename T> bool IsType ( void ) const
{
return false;
}
template <typename T> T *Get ( void ) { return NULL; }
template <typename T> const T *Get ( void ) const { return NULL; }
template <typename T> T &AsType ( void ) { static T dummy; return dummy; }
template <typename T> const T &AsType ( void ) const { static T dummy; return dummy; }
private:
CSteamID m_steamID;
int m_steamChannel; // SteamID channel (like a port number to disambiguate multiple connections)
PeerToPeerAddressType_t m_AddrType;
};
template <>
inline bool CPeerToPeerAddress::IsType<CSteamID> ( void ) const
{
return (m_AddrType == P2P_STEAMID);
}
template <>
inline CSteamID * CPeerToPeerAddress::Get<CSteamID> ( void )
{
return IsType<CSteamID> ( ) ? &m_steamID : NULL;
}
template <>
inline const CSteamID * CPeerToPeerAddress::Get<CSteamID> ( void ) const
{
return IsType<CSteamID> ( ) ? &m_steamID : NULL;
}
template <>
inline CSteamID &CPeerToPeerAddress::AsType<CSteamID> ( void )
{
Assert ( IsType<CSteamID> ( ) );
return m_steamID;
}
template <>
inline const CSteamID &CPeerToPeerAddress::AsType<CSteamID> ( void ) const
{
Assert ( IsType<CSteamID> ( ) );
return m_steamID;
}
enum NetworkSystemAddressType_t
{
NSAT_NETADR,
NSAT_P2P,
NSAT_PROXIED_GAMESERVER, // Client proxied through Steam Datagram Transport
NSAT_PROXIED_CLIENT, // Client proxied through Steam Datagram Transport
};
// Used to represent a remote address which can be a network address or SteamID
// Basically if m_steamID.IsValid() then we send to that otherwise we use the m_adr
struct ns_address
{
netadr_t m_adr; // ip:port and network type (NULL/IP/BROADCAST/etc).
CPeerToPeerAddress m_steamID; // SteamID destination
NetworkSystemAddressType_t m_AddrType;
ns_address() : m_AddrType( NSAT_NETADR ){}
~ns_address()
{
Clear();
}
void Clear ( )
{
m_AddrType = NSAT_NETADR;
m_adr.Clear ( );
m_steamID.Clear ( );
}
ns_address ( const netadr_t &other )
: m_AddrType ( NSAT_NETADR )
, m_adr ( other )
{
m_steamID.Clear();
}
ns_address& operator=(const netadr_t &other)
{
Clear ( );
m_AddrType = NSAT_NETADR;
m_adr = other;
return *this;
}
ns_address ( const CPeerToPeerAddress &steamID )
: m_AddrType ( NSAT_P2P )
, m_steamID ( steamID )
{
m_adr.Clear ( );
}
ns_address& operator=(const CPeerToPeerAddress &steamID)
{
Clear ( );
m_AddrType = NSAT_P2P;
m_steamID = steamID;
return *this;
}
ns_address &SetFromSteamID ( const CSteamID &steamID, int nSteamChannel )
{
Clear ( );
m_AddrType = NSAT_P2P;
m_steamID.SetFromSteamID( steamID, nSteamChannel );
return *this;
}
bool IsLoopback ( void ) const
{
return (m_AddrType == NSAT_NETADR) && m_adr.IsLoopback ( );
}
bool IsLocalhost ( void ) const
{
return (m_AddrType == NSAT_NETADR) && m_adr.IsLocalhost ( );
}
bool IsBroadcast( void ) const
{
return (m_AddrType == NSAT_NETADR) && m_adr.GetType() == NA_BROADCAST;
}
bool IsReservedAdr( void ) const
{
return (m_AddrType == NSAT_NETADR) && m_adr.IsReservedAdr();
}
bool IsNull ( void ) const
{
switch ( m_AddrType )
{
case NSAT_NETADR:
return m_adr.GetType ( ) == NA_NULL;
case NSAT_P2P:
case NSAT_PROXIED_GAMESERVER:
case NSAT_PROXIED_CLIENT:
return !m_steamID.IsValid ( );
};
return true;
}
bool IsValid ( ) const
{
switch ( m_AddrType )
{
case NSAT_NETADR:
return m_adr.IsValid ( );
case NSAT_P2P:
case NSAT_PROXIED_GAMESERVER:
case NSAT_PROXIED_CLIENT:
return m_steamID.IsValid ( );
};
return false;
}
bool CompareAdr ( const ns_address &other, bool onlyBase = false ) const
{
if ( m_AddrType != other.m_AddrType )
return false;
switch ( m_AddrType )
{
case NSAT_NETADR:
return m_adr.CompareAdr ( other.m_adr, onlyBase );
case NSAT_P2P:
case NSAT_PROXIED_GAMESERVER:
case NSAT_PROXIED_CLIENT:
return m_steamID.CompareAdr( other.m_steamID, onlyBase );
};
return false;
}
bool operator==( const ns_address &rhs ) const
{
return CompareAdr( rhs, false );
}
bool operator!=( const ns_address &rhs ) const
{
return !CompareAdr( rhs, false );
}
NetworkSystemAddressType_t GetAddressType ( void ) const
{
return m_AddrType;
}
void SetAddrType( NetworkSystemAddressType_t type )
{
Clear();
m_AddrType = type;
}
bool SetFromSockadr ( const struct sockaddr * s )
{
m_AddrType = NSAT_NETADR;
m_steamID.Clear ( );
return m_adr.SetFromSockadr ( s );
}
unsigned int GetIP ( void ) const
{
return (m_AddrType == NSAT_NETADR) ? m_adr.GetIPHostByteOrder( ) : 0;
}
unsigned short GetPort ( void ) const
{
return (m_AddrType == NSAT_NETADR) ? m_adr.GetPort ( ) : 0;
}
template <typename T> bool IsType ( void ) const
{
//defer to subtype
switch ( m_AddrType )
{
case NSAT_P2P:
return m_steamID.IsType<T> ( );
};
return false;
}
template <typename T> T *Get ( void )
{
//defer to subtype
switch ( m_AddrType )
{
case NSAT_P2P:
return m_steamID.Get<T> ( );
};
return NULL;
}
template <typename T> const T *Get ( void ) const
{
//defer to subtype
switch ( m_AddrType )
{
case NSAT_P2P:
return m_steamID.Get<T> ( );
};
return NULL;
}
template <typename T> T &AsType ( void )
{
//defer to subtype
switch ( m_AddrType )
{
case NSAT_P2P:
return m_steamID.AsType<T> ( );
};
Assert ( false );
static T dummy;
return dummy;
}
template <typename T> const T &AsType ( void ) const
{
//defer to subtype
switch ( m_AddrType )
{
case NSAT_P2P:
return m_steamID.AsType<T> ( );
};
Assert ( false );
static T dummy;
return dummy;
}
bool SetFromString( const char *s )
{
Clear();
if ( !s )
return false;
bool bProxied = false;
if ( *s == '=' )
{
++s;
bProxied = true;
}
if ( *s == '[' )
{
CSteamID tempSteamID( s );
if ( !tempSteamID.IsValid() )
return false;
if ( bProxied && tempSteamID.BGameServerAccount() )
{
m_AddrType = NSAT_PROXIED_GAMESERVER;
m_steamID.SetFromSteamID( tempSteamID, STEAM_P2P_GAME_SERVER );
}
else
{
m_AddrType = bProxied ? NSAT_PROXIED_CLIENT : NSAT_P2P;
m_steamID.SetFromSteamID( tempSteamID, STEAM_P2P_GAME_CLIENT );
}
s = strchr( s, ']' );
int nChannel = -1;
if ( s && s[1] == ':' && sscanf( s+2, "%d", &nChannel ) == 1 && nChannel >= 0 )
{
m_steamID.SetSteamChannel( nChannel );
}
return true;
}
if ( !bProxied && m_adr.SetFromString( s, true ) )
{
m_AddrType = NSAT_NETADR;
return true;
}
return false;
}
};
template <>
inline bool ns_address::IsType<netadr_t> ( void ) const
{
return (m_AddrType == NSAT_NETADR);
}
template <>
inline bool ns_address::IsType<CPeerToPeerAddress> ( void ) const
{
return (m_AddrType == NSAT_P2P);
}
template <>
inline netadr_t *ns_address::Get<netadr_t> ( void )
{
return IsType<netadr_t> ( ) ? &m_adr : NULL;
}
template <>
inline const netadr_t *ns_address::Get<netadr_t> ( void ) const
{
return IsType<netadr_t> ( ) ? &m_adr : NULL;
}
template <>
inline CPeerToPeerAddress *ns_address::Get<CPeerToPeerAddress> ( void )
{
return IsType<CPeerToPeerAddress> ( ) ? &m_steamID : NULL;
}
template <>
inline const CPeerToPeerAddress *ns_address::Get<CPeerToPeerAddress> ( void ) const
{
return IsType<CPeerToPeerAddress> ( ) ? &m_steamID : NULL;
}
template <>
inline netadr_t &ns_address::AsType<netadr_t> ( void )
{
Assert ( IsType<netadr_t> ( ) );
return m_adr;
}
template <>
inline const netadr_t &ns_address::AsType<netadr_t> ( void ) const
{
Assert ( IsType<netadr_t> ( ) );
return m_adr;
}
template <>
inline CPeerToPeerAddress &ns_address::AsType<CPeerToPeerAddress> ( void )
{
Assert ( IsType<CPeerToPeerAddress> ( ) );
return m_steamID;
}
template <>
inline const CPeerToPeerAddress &ns_address::AsType<CPeerToPeerAddress> ( void ) const
{
Assert ( IsType<CPeerToPeerAddress> ( ) );
return m_steamID;
}
/// Utility class used to render an address
class ns_address_render
{
char m_buf[64];
public:
ns_address_render( const ns_address &a )
{
switch ( a.m_AddrType )
{
case NSAT_NETADR:
a.m_adr.ToString( m_buf, sizeof( m_buf ) );
break;
case NSAT_P2P:
V_sprintf_safe( m_buf, "%s:%d", a.m_steamID.ToString(), a.m_steamID.GetSteamChannel() );
break;
case NSAT_PROXIED_CLIENT:
case NSAT_PROXIED_GAMESERVER:
V_sprintf_safe( m_buf, "=%s:%d", a.m_steamID.ToString(), a.m_steamID.GetSteamChannel() );
break;
default:
m_buf[0] = '\0';
};
}
const char *String() const { return m_buf; }
};
#endif // NS_ADDRESS_H