summaryrefslogtreecommitdiff
path: root/game/shared/cstrike/cs_urlretrieveprices.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/cstrike/cs_urlretrieveprices.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/shared/cstrike/cs_urlretrieveprices.cpp')
-rw-r--r--game/shared/cstrike/cs_urlretrieveprices.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/game/shared/cstrike/cs_urlretrieveprices.cpp b/game/shared/cstrike/cs_urlretrieveprices.cpp
new file mode 100644
index 0000000..c094263
--- /dev/null
+++ b/game/shared/cstrike/cs_urlretrieveprices.cpp
@@ -0,0 +1,237 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+//#include "stdafx.h"
+#ifdef _WIN32
+#include "winlite.h"
+#include "winsock.h"
+#elif POSIX
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define SOCKET int
+#define LPSOCKADDR struct sockaddr *
+#define SOCKADDR_IN struct sockaddr_in
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#define closesocket close
+#endif
+#include "tier1/strtools.h"
+#include "KeyValues.h"
+#include "utlbuffer.h"
+#include "tier1/checksum_crc.h"
+#include "tier1/convar.h"
+#include "cbase.h"
+#include "cs_gamestats.h"
+#include "cs_gamerules.h"
+#include "cs_urlretrieveprices.h"
+
+#if _DEBUG
+#define WEEKLY_PRICE_URL "http://gamestats/weeklyprices.dat"
+#else
+#define WEEKLY_PRICE_URL "http://www.steampowered.com/stats/csmarket/weeklyprices.dat"
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Purpose: request a URL from connection
+//-----------------------------------------------------------------------------
+bool SendHTTPRequest( const char *pchRequestURL, SOCKET socketHTML )
+{
+ char szHeader[ MED_BUFFER_SIZE ];
+ char szHostName[ SMALL_BUFFER_SIZE ];
+ ::gethostname( szHostName, sizeof(szHostName) );
+
+ Q_snprintf( szHeader, sizeof(szHeader), "GET %s HTTP/1.0\r\n" \
+ "Accept: */*\r\n" \
+ "Accept-Language: en-us\r\n" \
+ "User-Agent: Steam/3.0\r\n" \
+ "Host: %s\r\n" \
+ "\r\n",
+ pchRequestURL, szHostName );
+
+ return ::send( socketHTML, szHeader, Q_strlen(szHeader) + 1, 0 ) != SOCKET_ERROR ;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Given a previous HTTP request parse the response into a key values buffer
+//-----------------------------------------------------------------------------
+bool ParseHTTPResponse( SOCKET socketHTML, uint32 *unPageHash = NULL )
+{
+ char szHeaderBuf[ MED_BUFFER_SIZE ];
+ char szBodyBuf[ MED_BUFFER_SIZE ];
+
+ int dwRet = 0;
+ bool bFinishedHeaderRead = false;
+ int iRecvPosition = 0;
+ int cCharsInLine = 0;
+
+ // scan for the end of the header
+ while ( !bFinishedHeaderRead && iRecvPosition < sizeof(szHeaderBuf) )
+ {
+ dwRet = ::recv( socketHTML, &szHeaderBuf[ iRecvPosition ] , 1, 0);
+ if ( dwRet < 0 )
+ {
+ bFinishedHeaderRead = true;
+ }
+
+ switch( szHeaderBuf[ iRecvPosition ] )
+ {
+ case '\r':
+ break;
+ case '\n':
+ if ( cCharsInLine == 0 )
+ bFinishedHeaderRead = true;
+
+ cCharsInLine = 0;
+ break;
+ default:
+ cCharsInLine++;
+ break;
+ }
+
+ iRecvPosition++;
+ }
+
+ CUtlBuffer buf;
+ buf.SetBufferType( false, false );
+ while( 1 )
+ {
+ dwRet = ::recv( socketHTML, szBodyBuf, sizeof(szBodyBuf)-1, 0);
+ if ( dwRet <= 0 )
+ break;
+
+ buf.Put( szBodyBuf, sizeof(szBodyBuf)-1 );
+ }
+
+ weeklyprice_t weeklyprice;
+ Q_memset( &weeklyprice, 0, sizeof( weeklyprice_t) );
+
+ buf.Get( &weeklyprice, sizeof( weeklyprice_t ) );
+
+ if ( weeklyprice.iVersion != PRICE_BLOB_VERSION )
+ {
+ Msg( "Incorrect price blob version! Update your server!\n" );
+ return false;
+ }
+
+ CSGameRules()->AddPricesToTable( weeklyprice );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Given http url crack it into an address and the request part
+//-----------------------------------------------------------------------------
+bool ProcessURL( const char *pchURL, void *pSockAddrIn, char *pchRequest, int cchRequest )
+{
+ char rgchHost[ MAX_DNS_NAME ];
+ char rgchRequest[ MED_BUFFER_SIZE ];
+ uint16 iPort;
+
+ if ( Q_strnicmp( pchURL, "http://", 7 ) != 0 )
+ {
+ Assert( !"http protocol only supported" );
+ return false;
+ }
+
+ const char *pchColon = strchr( pchURL + 7, ':' );
+ if ( pchColon )
+ {
+ Q_strncpy( rgchHost, pchURL + 7, pchColon - ( pchURL + 7 ) + 1 );
+ const char *pchForwardSlash = strchr( pchColon + 1, '/' );
+ if ( !pchForwardSlash )
+ return false;
+ Q_strncpy( rgchRequest, pchColon + 1, pchForwardSlash - ( pchColon + 1 ) + 1 );
+ iPort = atoi( rgchRequest );
+ Q_strncpy( rgchRequest, pchForwardSlash, ( pchURL + Q_strlen(pchURL) ) - pchForwardSlash + 1 );
+ }
+ else
+ {
+ const char *pchForwardSlash = strchr( pchURL + 7, '/' );
+ if ( !pchForwardSlash )
+ return false;
+
+ Q_strncpy( rgchHost, pchURL + 7, pchForwardSlash - ( pchURL + 7 ) + 1 );
+ iPort = 80;
+ Q_strncpy( rgchRequest, pchForwardSlash, ( pchURL + Q_strlen(pchURL) ) - pchForwardSlash + 1 );
+ }
+
+ struct hostent *hp = NULL;
+ if ( inet_addr( rgchHost ) == INADDR_NONE )
+ {
+ hp = gethostbyname( rgchHost );
+ }
+ else
+ {
+ uint32 addr = inet_addr( rgchHost );
+ hp = gethostbyaddr( ( char* )&addr, sizeof( addr ), AF_INET );
+ }
+
+ if( hp == NULL )
+ {
+ return false;
+ }
+
+ sockaddr_in &sockAddrIn = *((sockaddr_in *)pSockAddrIn);
+ sockAddrIn.sin_addr.s_addr = *( ( unsigned long* )hp->h_addr );
+ sockAddrIn.sin_family = AF_INET;
+ sockAddrIn.sin_port = htons( iPort );
+
+ Q_strncpy( pchRequest, rgchRequest, cchRequest );
+ return true;
+}
+
+//networkstringtable
+
+bool BlackMarket_DownloadPrices( void )
+{
+ char szRequest[ MED_BUFFER_SIZE ];
+ sockaddr_in server;
+ bool bConnected = false;
+
+ if ( ProcessURL( WEEKLY_PRICE_URL, &server, szRequest, sizeof(szRequest) ) )
+ {
+ SOCKET socketHTML = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
+ if ( socketHTML != INVALID_SOCKET)
+ {
+ int iRet = ::connect( socketHTML, (LPSOCKADDR)&server, sizeof(SOCKADDR_IN) );
+
+ if ( !iRet )
+ {
+ bConnected = true;
+ if ( SendHTTPRequest( szRequest, socketHTML ) )
+ {
+ uint32 unHash = 0;
+ bool bRet = ParseHTTPResponse( socketHTML, &unHash );
+
+ closesocket( socketHTML );
+
+ return bRet;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ closesocket( socketHTML );
+ return false;
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}