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

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // netadr.h
  9. #ifndef NS_ADDRESS_H
  10. #define NS_ADDRESS_H
  11. #pragma once
  12. #include "tier0/platform.h"
  13. #include "tier0/dbg.h"
  14. #include "tier1/netadr.h"
  15. #include "steam/steamclientpublic.h" // for CSteamID
  16. #include "tier1/strtools.h" // V_memset
  17. #if defined( NO_STEAM )
  18. typedef CSteamID uint64;
  19. #endif
  20. enum PeerToPeerAddressType_t
  21. {
  22. P2P_STEAMID,
  23. };
  24. // Build int subchannel types
  25. // FIXME - these really are game specific. I wish we could standardize!
  26. enum SteamPeerToPeerChannel_t
  27. {
  28. STEAM_P2P_GAME_CLIENT = 0,
  29. STEAM_P2P_GAME_SERVER = 1,
  30. STEAM_P2P_LOBBY = 2,
  31. STEAM_P2P_HLTV = 3,
  32. STEAM_P2P_HLTV1 = 4,
  33. };
  34. class CPeerToPeerAddress
  35. {
  36. public:
  37. CPeerToPeerAddress ( void )
  38. : m_AddrType( P2P_STEAMID )
  39. , m_steamChannel( STEAM_P2P_GAME_CLIENT )
  40. {}
  41. void Clear ( void )
  42. {
  43. m_AddrType = P2P_STEAMID;
  44. m_steamID.Clear();
  45. m_steamChannel = STEAM_P2P_GAME_CLIENT;
  46. }
  47. void SetSteamChannel( int nChannel )
  48. {
  49. m_steamChannel = nChannel;
  50. }
  51. int GetSteamChannel() const
  52. {
  53. return m_steamChannel;
  54. }
  55. const CSteamID &GetSteamID() const
  56. {
  57. return m_steamID;
  58. }
  59. CPeerToPeerAddress ( const CSteamID &steamID, int nSteamChannel )
  60. : m_AddrType ( P2P_STEAMID )
  61. , m_steamID ( steamID )
  62. , m_steamChannel( nSteamChannel )
  63. {
  64. }
  65. private:
  66. // disallow since we can't deal with steamchannel
  67. CPeerToPeerAddress &operator=(const CSteamID &steamID);
  68. public:
  69. // Like operator =
  70. CPeerToPeerAddress &SetFromSteamID( const CSteamID &steamID, int nSteamChannel )
  71. {
  72. m_AddrType = P2P_STEAMID;
  73. m_steamID = steamID;
  74. m_steamChannel = nSteamChannel;
  75. return *this;
  76. }
  77. bool IsValid ( void ) const
  78. {
  79. switch ( m_AddrType )
  80. {
  81. case P2P_STEAMID:
  82. return m_steamID.IsValid ( );
  83. };
  84. return false;
  85. }
  86. const char *ToString ( void ) const
  87. {
  88. switch ( m_AddrType )
  89. {
  90. case P2P_STEAMID:
  91. return m_steamID.Render ( );
  92. };
  93. return "";
  94. }
  95. bool CompareAdr ( const CPeerToPeerAddress &other, bool onlyBase = false ) const
  96. {
  97. if ( m_AddrType != -other.m_AddrType )
  98. return false;
  99. switch ( m_AddrType )
  100. {
  101. case P2P_STEAMID:
  102. return ((m_steamID == other.m_steamID) && (m_steamChannel == other.m_steamChannel));
  103. };
  104. return false;
  105. }
  106. bool operator==(const CPeerToPeerAddress &rhs) const
  107. {
  108. return CompareAdr( rhs, false );
  109. }
  110. PeerToPeerAddressType_t GetAddressType ( void ) const
  111. {
  112. return m_AddrType;
  113. }
  114. template <typename T> bool IsType ( void ) const
  115. {
  116. return false;
  117. }
  118. template <typename T> T *Get ( void ) { return NULL; }
  119. template <typename T> const T *Get ( void ) const { return NULL; }
  120. template <typename T> T &AsType ( void ) { static T dummy; return dummy; }
  121. template <typename T> const T &AsType ( void ) const { static T dummy; return dummy; }
  122. private:
  123. CSteamID m_steamID;
  124. int m_steamChannel; // SteamID channel (like a port number to disambiguate multiple connections)
  125. PeerToPeerAddressType_t m_AddrType;
  126. };
  127. template <>
  128. inline bool CPeerToPeerAddress::IsType<CSteamID> ( void ) const
  129. {
  130. return (m_AddrType == P2P_STEAMID);
  131. }
  132. template <>
  133. inline CSteamID * CPeerToPeerAddress::Get<CSteamID> ( void )
  134. {
  135. return IsType<CSteamID> ( ) ? &m_steamID : NULL;
  136. }
  137. template <>
  138. inline const CSteamID * CPeerToPeerAddress::Get<CSteamID> ( void ) const
  139. {
  140. return IsType<CSteamID> ( ) ? &m_steamID : NULL;
  141. }
  142. template <>
  143. inline CSteamID &CPeerToPeerAddress::AsType<CSteamID> ( void )
  144. {
  145. Assert ( IsType<CSteamID> ( ) );
  146. return m_steamID;
  147. }
  148. template <>
  149. inline const CSteamID &CPeerToPeerAddress::AsType<CSteamID> ( void ) const
  150. {
  151. Assert ( IsType<CSteamID> ( ) );
  152. return m_steamID;
  153. }
  154. enum NetworkSystemAddressType_t
  155. {
  156. NSAT_NETADR,
  157. NSAT_P2P,
  158. NSAT_PROXIED_GAMESERVER, // Client proxied through Steam Datagram Transport
  159. NSAT_PROXIED_CLIENT, // Client proxied through Steam Datagram Transport
  160. };
  161. // Used to represent a remote address which can be a network address or SteamID
  162. // Basically if m_steamID.IsValid() then we send to that otherwise we use the m_adr
  163. struct ns_address
  164. {
  165. netadr_t m_adr; // ip:port and network type (NULL/IP/BROADCAST/etc).
  166. CPeerToPeerAddress m_steamID; // SteamID destination
  167. NetworkSystemAddressType_t m_AddrType;
  168. ns_address() : m_AddrType( NSAT_NETADR ){}
  169. ~ns_address()
  170. {
  171. Clear();
  172. }
  173. void Clear ( )
  174. {
  175. m_AddrType = NSAT_NETADR;
  176. m_adr.Clear ( );
  177. m_steamID.Clear ( );
  178. }
  179. ns_address ( const netadr_t &other )
  180. : m_AddrType ( NSAT_NETADR )
  181. , m_adr ( other )
  182. {
  183. m_steamID.Clear();
  184. }
  185. ns_address& operator=(const netadr_t &other)
  186. {
  187. Clear ( );
  188. m_AddrType = NSAT_NETADR;
  189. m_adr = other;
  190. return *this;
  191. }
  192. ns_address ( const CPeerToPeerAddress &steamID )
  193. : m_AddrType ( NSAT_P2P )
  194. , m_steamID ( steamID )
  195. {
  196. m_adr.Clear ( );
  197. }
  198. ns_address& operator=(const CPeerToPeerAddress &steamID)
  199. {
  200. Clear ( );
  201. m_AddrType = NSAT_P2P;
  202. m_steamID = steamID;
  203. return *this;
  204. }
  205. ns_address &SetFromSteamID ( const CSteamID &steamID, int nSteamChannel )
  206. {
  207. Clear ( );
  208. m_AddrType = NSAT_P2P;
  209. m_steamID.SetFromSteamID( steamID, nSteamChannel );
  210. return *this;
  211. }
  212. bool IsLoopback ( void ) const
  213. {
  214. return (m_AddrType == NSAT_NETADR) && m_adr.IsLoopback ( );
  215. }
  216. bool IsLocalhost ( void ) const
  217. {
  218. return (m_AddrType == NSAT_NETADR) && m_adr.IsLocalhost ( );
  219. }
  220. bool IsBroadcast( void ) const
  221. {
  222. return (m_AddrType == NSAT_NETADR) && m_adr.GetType() == NA_BROADCAST;
  223. }
  224. bool IsReservedAdr( void ) const
  225. {
  226. return (m_AddrType == NSAT_NETADR) && m_adr.IsReservedAdr();
  227. }
  228. bool IsNull ( void ) const
  229. {
  230. switch ( m_AddrType )
  231. {
  232. case NSAT_NETADR:
  233. return m_adr.GetType ( ) == NA_NULL;
  234. case NSAT_P2P:
  235. case NSAT_PROXIED_GAMESERVER:
  236. case NSAT_PROXIED_CLIENT:
  237. return !m_steamID.IsValid ( );
  238. };
  239. return true;
  240. }
  241. bool IsValid ( ) const
  242. {
  243. switch ( m_AddrType )
  244. {
  245. case NSAT_NETADR:
  246. return m_adr.IsValid ( );
  247. case NSAT_P2P:
  248. case NSAT_PROXIED_GAMESERVER:
  249. case NSAT_PROXIED_CLIENT:
  250. return m_steamID.IsValid ( );
  251. };
  252. return false;
  253. }
  254. bool CompareAdr ( const ns_address &other, bool onlyBase = false ) const
  255. {
  256. if ( m_AddrType != other.m_AddrType )
  257. return false;
  258. switch ( m_AddrType )
  259. {
  260. case NSAT_NETADR:
  261. return m_adr.CompareAdr ( other.m_adr, onlyBase );
  262. case NSAT_P2P:
  263. case NSAT_PROXIED_GAMESERVER:
  264. case NSAT_PROXIED_CLIENT:
  265. return m_steamID.CompareAdr( other.m_steamID, onlyBase );
  266. };
  267. return false;
  268. }
  269. bool operator==( const ns_address &rhs ) const
  270. {
  271. return CompareAdr( rhs, false );
  272. }
  273. bool operator!=( const ns_address &rhs ) const
  274. {
  275. return !CompareAdr( rhs, false );
  276. }
  277. NetworkSystemAddressType_t GetAddressType ( void ) const
  278. {
  279. return m_AddrType;
  280. }
  281. void SetAddrType( NetworkSystemAddressType_t type )
  282. {
  283. Clear();
  284. m_AddrType = type;
  285. }
  286. bool SetFromSockadr ( const struct sockaddr * s )
  287. {
  288. m_AddrType = NSAT_NETADR;
  289. m_steamID.Clear ( );
  290. return m_adr.SetFromSockadr ( s );
  291. }
  292. unsigned int GetIP ( void ) const
  293. {
  294. return (m_AddrType == NSAT_NETADR) ? m_adr.GetIPHostByteOrder( ) : 0;
  295. }
  296. unsigned short GetPort ( void ) const
  297. {
  298. return (m_AddrType == NSAT_NETADR) ? m_adr.GetPort ( ) : 0;
  299. }
  300. template <typename T> bool IsType ( void ) const
  301. {
  302. //defer to subtype
  303. switch ( m_AddrType )
  304. {
  305. case NSAT_P2P:
  306. return m_steamID.IsType<T> ( );
  307. };
  308. return false;
  309. }
  310. template <typename T> T *Get ( void )
  311. {
  312. //defer to subtype
  313. switch ( m_AddrType )
  314. {
  315. case NSAT_P2P:
  316. return m_steamID.Get<T> ( );
  317. };
  318. return NULL;
  319. }
  320. template <typename T> const T *Get ( void ) const
  321. {
  322. //defer to subtype
  323. switch ( m_AddrType )
  324. {
  325. case NSAT_P2P:
  326. return m_steamID.Get<T> ( );
  327. };
  328. return NULL;
  329. }
  330. template <typename T> T &AsType ( void )
  331. {
  332. //defer to subtype
  333. switch ( m_AddrType )
  334. {
  335. case NSAT_P2P:
  336. return m_steamID.AsType<T> ( );
  337. };
  338. Assert ( false );
  339. static T dummy;
  340. return dummy;
  341. }
  342. template <typename T> const T &AsType ( void ) const
  343. {
  344. //defer to subtype
  345. switch ( m_AddrType )
  346. {
  347. case NSAT_P2P:
  348. return m_steamID.AsType<T> ( );
  349. };
  350. Assert ( false );
  351. static T dummy;
  352. return dummy;
  353. }
  354. bool SetFromString( const char *s )
  355. {
  356. Clear();
  357. if ( !s )
  358. return false;
  359. bool bProxied = false;
  360. if ( *s == '=' )
  361. {
  362. ++s;
  363. bProxied = true;
  364. }
  365. if ( *s == '[' )
  366. {
  367. CSteamID tempSteamID( s );
  368. if ( !tempSteamID.IsValid() )
  369. return false;
  370. if ( bProxied && tempSteamID.BGameServerAccount() )
  371. {
  372. m_AddrType = NSAT_PROXIED_GAMESERVER;
  373. m_steamID.SetFromSteamID( tempSteamID, STEAM_P2P_GAME_SERVER );
  374. }
  375. else
  376. {
  377. m_AddrType = bProxied ? NSAT_PROXIED_CLIENT : NSAT_P2P;
  378. m_steamID.SetFromSteamID( tempSteamID, STEAM_P2P_GAME_CLIENT );
  379. }
  380. s = strchr( s, ']' );
  381. int nChannel = -1;
  382. if ( s && s[1] == ':' && sscanf( s+2, "%d", &nChannel ) == 1 && nChannel >= 0 )
  383. {
  384. m_steamID.SetSteamChannel( nChannel );
  385. }
  386. return true;
  387. }
  388. if ( !bProxied && m_adr.SetFromString( s, true ) )
  389. {
  390. m_AddrType = NSAT_NETADR;
  391. return true;
  392. }
  393. return false;
  394. }
  395. };
  396. template <>
  397. inline bool ns_address::IsType<netadr_t> ( void ) const
  398. {
  399. return (m_AddrType == NSAT_NETADR);
  400. }
  401. template <>
  402. inline bool ns_address::IsType<CPeerToPeerAddress> ( void ) const
  403. {
  404. return (m_AddrType == NSAT_P2P);
  405. }
  406. template <>
  407. inline netadr_t *ns_address::Get<netadr_t> ( void )
  408. {
  409. return IsType<netadr_t> ( ) ? &m_adr : NULL;
  410. }
  411. template <>
  412. inline const netadr_t *ns_address::Get<netadr_t> ( void ) const
  413. {
  414. return IsType<netadr_t> ( ) ? &m_adr : NULL;
  415. }
  416. template <>
  417. inline CPeerToPeerAddress *ns_address::Get<CPeerToPeerAddress> ( void )
  418. {
  419. return IsType<CPeerToPeerAddress> ( ) ? &m_steamID : NULL;
  420. }
  421. template <>
  422. inline const CPeerToPeerAddress *ns_address::Get<CPeerToPeerAddress> ( void ) const
  423. {
  424. return IsType<CPeerToPeerAddress> ( ) ? &m_steamID : NULL;
  425. }
  426. template <>
  427. inline netadr_t &ns_address::AsType<netadr_t> ( void )
  428. {
  429. Assert ( IsType<netadr_t> ( ) );
  430. return m_adr;
  431. }
  432. template <>
  433. inline const netadr_t &ns_address::AsType<netadr_t> ( void ) const
  434. {
  435. Assert ( IsType<netadr_t> ( ) );
  436. return m_adr;
  437. }
  438. template <>
  439. inline CPeerToPeerAddress &ns_address::AsType<CPeerToPeerAddress> ( void )
  440. {
  441. Assert ( IsType<CPeerToPeerAddress> ( ) );
  442. return m_steamID;
  443. }
  444. template <>
  445. inline const CPeerToPeerAddress &ns_address::AsType<CPeerToPeerAddress> ( void ) const
  446. {
  447. Assert ( IsType<CPeerToPeerAddress> ( ) );
  448. return m_steamID;
  449. }
  450. /// Utility class used to render an address
  451. class ns_address_render
  452. {
  453. char m_buf[64];
  454. public:
  455. ns_address_render( const ns_address &a )
  456. {
  457. switch ( a.m_AddrType )
  458. {
  459. case NSAT_NETADR:
  460. a.m_adr.ToString( m_buf, sizeof( m_buf ) );
  461. break;
  462. case NSAT_P2P:
  463. V_sprintf_safe( m_buf, "%s:%d", a.m_steamID.ToString(), a.m_steamID.GetSteamChannel() );
  464. break;
  465. case NSAT_PROXIED_CLIENT:
  466. case NSAT_PROXIED_GAMESERVER:
  467. V_sprintf_safe( m_buf, "=%s:%d", a.m_steamID.ToString(), a.m_steamID.GetSteamChannel() );
  468. break;
  469. default:
  470. m_buf[0] = '\0';
  471. };
  472. }
  473. const char *String() const { return m_buf; }
  474. };
  475. #endif // NS_ADDRESS_H