Team Fortress 2 Source Code as on 22/4/2020
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.

179 lines
4.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #if defined(_WIN32) && !defined(_X360)
  9. #include <winsock.h>
  10. #elif POSIX
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #elif !defined(_X360)
  14. #error "define socket.h"
  15. #endif
  16. #include "host.h"
  17. #include "blockingudpsocket.h"
  18. #include "cserserverprotocol_engine.h"
  19. #include "KeyValues.h"
  20. #include "bitbuf.h"
  21. #include "mathlib/IceKey.H"
  22. #include "net.h"
  23. // memdbgon must be the last include file in a .cpp file!!!
  24. #include "tier0/memdbgon.h"
  25. static int CountFields( KeyValues *fields )
  26. {
  27. int c = 0;
  28. KeyValues *kv = fields->GetFirstSubKey();
  29. while ( kv )
  30. {
  31. c++;
  32. kv = kv->GetNextKey();
  33. }
  34. return c;
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Purpose: encrypts an 8-byte sequence
  38. //-----------------------------------------------------------------------------
  39. static inline void Encrypt8ByteSequence( IceKey& cipher, const unsigned char *plainText, unsigned char *cipherText)
  40. {
  41. cipher.encrypt(plainText, cipherText);
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose:
  45. //-----------------------------------------------------------------------------
  46. static void EncryptBuffer( IceKey& cipher, unsigned char *bufData, uint bufferSize)
  47. {
  48. unsigned char *cipherText = bufData;
  49. unsigned char *plainText = bufData;
  50. uint bytesEncrypted = 0;
  51. while (bytesEncrypted < bufferSize)
  52. {
  53. // encrypt 8 byte section
  54. Encrypt8ByteSequence( cipher, plainText, cipherText);
  55. bytesEncrypted += 8;
  56. cipherText += 8;
  57. plainText += 8;
  58. }
  59. }
  60. static void BuildUploadDataMessage( bf_write& buf, char const *tablename, KeyValues *fields )
  61. {
  62. bf_write encrypted;
  63. ALIGN4 byte encrypted_data[ 2048 ] ALIGN4_POST;
  64. buf.WriteByte( C2M_UPLOADDATA );
  65. buf.WriteByte( '\n' );
  66. buf.WriteByte( C2M_UPLOADDATA_PROTOCOL_VERSION );
  67. // encryption object
  68. IceKey cipher(1); /* medium encryption level */
  69. unsigned char ucEncryptionKey[8] = { 54, 175, 165, 5, 76, 251, 29, 113 };
  70. cipher.set( ucEncryptionKey );
  71. encrypted.StartWriting( encrypted_data, sizeof( encrypted_data ) );
  72. byte corruption_identifier = 0x01;
  73. encrypted.WriteByte( corruption_identifier );
  74. // Data version protocol
  75. encrypted.WriteByte( C2M_UPLOADDATA_DATA_VERSION );
  76. encrypted.WriteString( tablename );
  77. int fieldCount = CountFields( fields );
  78. if ( fieldCount > 255 )
  79. {
  80. Host_Error( "Too many fields in uploaddata (%i max = 255)\n", fieldCount );
  81. }
  82. encrypted.WriteByte( (byte)fieldCount );
  83. KeyValues *kv = fields->GetFirstSubKey();
  84. while ( kv )
  85. {
  86. encrypted.WriteString( kv->GetName() );
  87. encrypted.WriteString( kv->GetString() );
  88. kv = kv->GetNextKey();
  89. }
  90. // Round to multiple of 8 for encrypted
  91. while ( encrypted.GetNumBytesWritten() % 8 )
  92. {
  93. encrypted.WriteByte( 0 );
  94. }
  95. EncryptBuffer( cipher, (unsigned char *)encrypted.GetData(), encrypted.GetNumBytesWritten() );
  96. buf.WriteShort( (int)encrypted.GetNumBytesWritten() );
  97. buf.WriteBytes( (unsigned char *)encrypted.GetData(), encrypted.GetNumBytesWritten() );
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. // Input : *cserIP -
  102. // *tablename -
  103. // *fields -
  104. // Output : Returns true on success, false on failure.
  105. //-----------------------------------------------------------------------------
  106. bool UploadData( char const *cserIP, char const *tablename, KeyValues *fields )
  107. {
  108. #ifndef _XBOX
  109. bf_write buf;
  110. ALIGN4 byte data[ 2048 ] ALIGN4_POST;
  111. buf.StartWriting( data, sizeof( data ) );
  112. BuildUploadDataMessage( buf, tablename, fields );
  113. netadr_t cseradr;
  114. if ( NET_StringToAdr( cserIP, &cseradr ) )
  115. {
  116. CBlockingUDPSocket *socket = new CBlockingUDPSocket();
  117. if ( socket )
  118. {
  119. struct sockaddr_in sa;
  120. cseradr.ToSockadr( (struct sockaddr *)&sa );
  121. // Don't bother waiting for response here
  122. socket->SendSocketMessage( sa, (const byte *)buf.GetData(), buf.GetNumBytesWritten() );
  123. delete socket;
  124. return true;
  125. }
  126. }
  127. return false;
  128. #else
  129. return true;
  130. #endif
  131. }
  132. /*
  133. CON_COMMAND( datatest, "" )
  134. {
  135. KeyValues *kv = new KeyValues( "data" );
  136. kv->SetString( "IDHash", "abcdefg" );
  137. kv->SetString( "Time", "DATETIME" );
  138. kv->SetString( "DXDeviceID", "1001" );
  139. kv->SetString( "DXVendorID", "1001" );
  140. kv->SetString( "Framerate", "999" );
  141. kv->SetString( "BuildNumber", va( "%i", build_number() ) );
  142. bool bret = UploadData( "127.0.0.1:27013", "benchmark", kv );
  143. kv->deleteThis();
  144. }
  145. */