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.

189 lines
4.4 KiB

  1. //===== Copyright � 1996-2009, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "mm_netmgr.h"
  7. #include "proto_oob.h"
  8. #include "protocol.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. //
  12. // Convars
  13. //
  14. ConVar net_allow_multicast( "net_allow_multicast", "1", FCVAR_RELEASE | FCVAR_ARCHIVE );
  15. ConVar net_allow_syslink( "net_allow_syslink", "1", FCVAR_DEVELOPMENTONLY );
  16. //
  17. // CConnectionlessLanMgr
  18. //
  19. CConnectionlessLanMgr::CConnectionlessLanMgr()
  20. {
  21. ;
  22. }
  23. CConnectionlessLanMgr::~CConnectionlessLanMgr()
  24. {
  25. ;
  26. }
  27. static CConnectionlessLanMgr g_ConnectionlessLanMgr;
  28. CConnectionlessLanMgr *g_pConnectionlessLanMgr = &g_ConnectionlessLanMgr;
  29. //
  30. // Implementation of CConnectionlessLanMgr
  31. //
  32. KeyValues * CConnectionlessLanMgr::UnpackPacket( netpacket_t *packet )
  33. {
  34. if ( !packet )
  35. return NULL;
  36. if ( !packet->size || !packet->data )
  37. return NULL;
  38. // Try to unpack the data
  39. if ( packet->message.ReadLong() != 0 )
  40. return NULL;
  41. if ( packet->message.ReadLong() != g_pMatchExtensions->GetINetSupport()->GetEngineBuildNumber() )
  42. return NULL;
  43. MEM_ALLOC_CREDIT();
  44. int nDataLen = packet->message.ReadLong();
  45. m_buffer.Clear();
  46. m_buffer.EnsureCapacity( nDataLen );
  47. packet->message.ReadBytes( m_buffer.Base(), nDataLen );
  48. m_buffer.SeekPut( CUtlBuffer::SEEK_HEAD, nDataLen );
  49. m_buffer.ActivateByteSwapping( !CByteswap::IsMachineBigEndian() );
  50. // Unpack key values
  51. KeyValues *pMsg = new KeyValues( "" );
  52. if ( pMsg->ReadAsBinary( m_buffer ) )
  53. {
  54. // Read binary data as well
  55. if ( int nBinarySize = packet->message.ReadLong() )
  56. {
  57. m_buffer.Clear();
  58. m_buffer.EnsureCapacity( nBinarySize );
  59. packet->message.ReadBytes( m_buffer.Base(), nBinarySize );
  60. m_buffer.SeekPut( CUtlBuffer::SEEK_HEAD, nBinarySize );
  61. // set the ptr to point to our buffer
  62. pMsg->SetPtr( "binary/ptr", m_buffer.Base() );
  63. }
  64. return pMsg; // "pMsg" is deleted by caller
  65. }
  66. pMsg->deleteThis();
  67. return NULL;
  68. }
  69. bool CConnectionlessLanMgr::ProcessConnectionlessPacket( netpacket_t *packet )
  70. {
  71. // Unpack key values
  72. KeyValues *pMsg = UnpackPacket( packet );
  73. if ( !pMsg )
  74. return false;
  75. MEM_ALLOC_CREDIT();
  76. KeyValues *notify = new KeyValues( "OnNetLanConnectionlessPacket" );
  77. notify->SetString( "from", ns_address_render( packet->from ).String() );
  78. notify->AddSubKey( pMsg );
  79. g_pMatchEventsSubscription->BroadcastEvent( notify );
  80. return true; // "pMsg" is deleted as child of "notify"
  81. }
  82. void CConnectionlessLanMgr::Update()
  83. {
  84. #ifdef _X360
  85. if ( !net_allow_syslink.GetBool() )
  86. return;
  87. g_pMatchExtensions->GetINetSupport()->ProcessSocket( INetSupport::NS_SOCK_SYSTEMLINK, this );
  88. #endif
  89. }
  90. void CConnectionlessLanMgr::SendPacket( KeyValues *pMsg, char const *szAddress /*= NULL*/, INetSupport::NetworkSocket_t eSock )
  91. {
  92. char buf[ INetSupport::NC_MAX_ROUTABLE_PAYLOAD ];
  93. bf_write msg( buf, sizeof( buf ) );
  94. msg.WriteLong( CONNECTIONLESS_HEADER );
  95. msg.WriteLong( 0 );
  96. msg.WriteLong( g_pMatchExtensions->GetINetSupport()->GetEngineBuildNumber() );
  97. CUtlBuffer data;
  98. data.ActivateByteSwapping( !CByteswap::IsMachineBigEndian() );
  99. pMsg->WriteAsBinary( data );
  100. msg.WriteLong( data.TellMaxPut() );
  101. msg.WriteBytes( data.Base(), data.TellMaxPut() );
  102. Assert( !msg.IsOverflowed() );
  103. // Special case when encoding binary data
  104. KeyValues *kvPtr = pMsg->FindKey( "binary/ptr" );
  105. KeyValues *kvSize = pMsg->FindKey( "binary/size" );
  106. if ( kvPtr && kvSize )
  107. {
  108. void *pvData = kvPtr->GetPtr();
  109. int nSize = kvSize->GetInt();
  110. if ( pvData && nSize )
  111. {
  112. msg.WriteLong( nSize );
  113. if ( !msg.WriteBytes( pvData, nSize ) )
  114. {
  115. Assert( 0 );
  116. return;
  117. }
  118. }
  119. else
  120. {
  121. msg.WriteLong( 0 );
  122. }
  123. }
  124. else
  125. {
  126. msg.WriteLong( 0 );
  127. }
  128. Assert( !msg.IsOverflowed() );
  129. // Prepare the address
  130. netadr_t inetAddr;
  131. if ( szAddress )
  132. {
  133. if ( szAddress[0] == '*' && szAddress[1] == ':' )
  134. {
  135. inetAddr.SetType( NA_BROADCAST );
  136. inetAddr.SetPort( atoi( szAddress + 2 ) );
  137. }
  138. else
  139. {
  140. inetAddr.SetFromString( szAddress );
  141. }
  142. }
  143. else
  144. {
  145. inetAddr.SetType( NA_BROADCAST );
  146. inetAddr.SetPort( 0 );
  147. }
  148. // Check if broadcasts are allowed
  149. if ( inetAddr.GetType() == NA_BROADCAST &&
  150. !net_allow_multicast.GetBool() )
  151. return;
  152. // Sending the connectionless packet
  153. g_pMatchExtensions->GetINetSupport()->SendPacket( NULL, eSock,
  154. inetAddr, msg.GetData(), msg.GetNumBytesWritten() );
  155. }