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.

1046 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include "CardStats.h"
  11. //-----------------------------------------------------------------------------
  12. // Main stats loop
  13. //-----------------------------------------------------------------------------
  14. int main( int argc, char* argv[] )
  15. {
  16. if ( argc != 3 ) // a unix style usage string
  17. {
  18. printf ( "Usage: <SearchString> <Filename>\n" );
  19. printf ( "Output file will be <filename>.<searchstring>.txt" );
  20. return 0;
  21. }
  22. char* pszCardtype = argv[1]; // video card type we are looking for
  23. char* pszFilename = argv[2]; // file containing the data
  24. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  25. int nFileSize = LoadFileIntoBuffer(buf, pszFilename);
  26. ParseHeader ( buf );
  27. CUtlBuffer output ( 0, 255, CUtlBuffer::TEXT_BUFFER );
  28. int binwidth=100;
  29. // video card stats over time
  30. //TimeSeriesVCard ( buf, output, pszCardtype, nFileSize, binwidth );
  31. // cpu type stats over time
  32. //TimeSeriesCPU ( buf, output, pszCardtype, nFileSize, binwidth );
  33. // CPU vs Videocard
  34. //ParseFile ( buf, output, pszCardtype, nFileSize, binwidth, 0);
  35. // CPU vs Memory
  36. //ParseFile2 ( buf, output, pszCardtype, nFileSize, binwidth );
  37. //CPU vs network speed
  38. //ParseFile3 ( buf, output, pszCardtype, nFileSize, binwidth );
  39. // histogram of video card distribution
  40. HistogramVidCards ( buf, output, pszCardtype, nFileSize, binwidth );
  41. //HistogramNetSpeed ( buf, output, pszCardtype, nFileSize, binwidth );
  42. //HistogramRam ( buf, output, pszCardtype, nFileSize, binwidth );
  43. //HistogramCPU ( buf, output, pszCardtype, nFileSize, binwidth );
  44. WriteOutputToFile ( output, pszFilename, pszCardtype );
  45. return 0;
  46. }
  47. void HistogramCPU( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  48. {
  49. ParseFile ( inbuf, outbuf, "", size, binwidth, 1 );
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Reads entire file contents in to utlbuffer
  53. // input-buffer to load fileinto, filename
  54. // output-filesize
  55. //-----------------------------------------------------------------------------
  56. int LoadFileIntoBuffer(CUtlBuffer &buf, char *pszFilename)
  57. {
  58. // Open the file
  59. FILE *fh = fopen ( pszFilename, "rb" );
  60. if (fh == NULL)
  61. {
  62. printf ("Unable to open datafile. Check path/name.");
  63. exit( 0 );
  64. }
  65. fseek( fh, 0, SEEK_END );
  66. int nFileSize = ftell( fh );
  67. fseek ( fh, 0, SEEK_SET );
  68. // Read the file in one gulp
  69. buf.EnsureCapacity( nFileSize );
  70. int result=fread( buf.Base(), sizeof( char ), nFileSize, fh );
  71. fclose( fh );
  72. buf.SeekPut( CUtlBuffer::SEEK_HEAD, result );
  73. return nFileSize;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Writes the contents of the utlbuffer to file
  77. // datafile name becomes name.card.txt for results
  78. //-----------------------------------------------------------------------------
  79. void WriteOutputToFile( CUtlBuffer &buf, char *pszFilename, char *pszCardtype )
  80. {
  81. char pszOutFilename[500];
  82. strncpy( pszOutFilename, pszFilename, strlen( pszFilename )-3 );
  83. pszOutFilename[strlen(pszFilename)-3]='\0';
  84. strcat ( pszOutFilename, pszCardtype );
  85. strcat ( pszOutFilename, ".txt\0" );
  86. FILE *fh = fopen ( pszOutFilename, "w" );
  87. if ( fh == NULL )
  88. {
  89. printf ( "Unable to open outputfile." );
  90. exit(0);
  91. }
  92. fwrite ( buf.Base(), sizeof( char ), buf.TellPut(), fh );
  93. fclose( fh );
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Strips off header fields from datafile
  97. //-----------------------------------------------------------------------------
  98. void ParseHeader( CUtlBuffer &buf )
  99. {
  100. // remove first line of data (field labels)
  101. char pszTrash[256];
  102. buf.Scanf( "%s ", pszTrash);
  103. buf.Scanf( "%s ", pszTrash);
  104. buf.Scanf( "%s ", pszTrash);
  105. buf.Scanf( "%s ", pszTrash);
  106. buf.Scanf( "%s ", pszTrash);
  107. buf.Scanf( "%s \n", pszTrash);
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Counts number of users that have a given cpu bin speed for videocard string
  111. //
  112. // Parses buffer into fields and puts results into outbuf
  113. // size is size of the file read in
  114. //-----------------------------------------------------------------------------
  115. void ParseFile( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth, int nofilter)
  116. {
  117. // Each bin is how many computers with the given card had cpus > cpubin
  118. // and less than the next bin so cpu 200 covers cpu's from 200 to 299
  119. CUtlVector<int> nCpuList;
  120. CUtlVector<int> nQuantity;
  121. for ( int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range
  122. {
  123. nCpuList.AddToTail(i);
  124. nQuantity.AddToTail(0);
  125. }
  126. int totalUsers=0;
  127. while ( inbuf.TellGet() < size )
  128. {
  129. // Now parse the utlbuffer
  130. // file has fields of version, netspeed, ram, cpu and card type
  131. char pszVersion[300];
  132. int nNetSpeed, nRam, nCpu;
  133. int nRead=inbuf.Scanf( "%s %d %d %d ", pszVersion, &nNetSpeed, &nRam, &nCpu );
  134. char pszCard[300];
  135. char chSentinel = ' ';
  136. int i=0;
  137. while (( chSentinel != '\n' ))
  138. {
  139. chSentinel = inbuf.GetChar();
  140. pszCard[i] = chSentinel;
  141. ++i;
  142. }
  143. pszCard[i] = '\0';
  144. if (nRead != 4)
  145. continue;
  146. // if card is our type
  147. if ( nofilter || Q_stristr ( pszCard, pszSearchString ) != NULL )
  148. {
  149. InsertResult(nCpu, nCpuList, nQuantity);
  150. }
  151. totalUsers++;
  152. }
  153. if (nCpuList.Size()>65000)
  154. {
  155. printf ("Too many points, increase bin width\n");
  156. }
  157. printf("TotalUsers %d\n", totalUsers);
  158. // write results to an output buffer
  159. int total=0;
  160. outbuf.Printf ( "Cpu\tQuantity\n" ); // headers
  161. for ( int i=0; i < nCpuList.Size(); ++i )
  162. {
  163. outbuf.Printf ( "%d\t%d\n", nCpuList[i], nQuantity[i] );
  164. total+=nQuantity[i];
  165. }
  166. printf ("Users in this subset %d\n", total);
  167. printf ("Percent of dataset %.2f", ((float)total/(float)totalUsers)*100);
  168. }
  169. //-----------------------------------------------------------------------------
  170. // given cpu bin, plots number of users in a given memory bin
  171. //
  172. // Parses buffer into fields and puts results into outbuf
  173. // size is size of the file read in
  174. //-----------------------------------------------------------------------------
  175. #define NMEMBINS 6
  176. //#define NCPUBINS 48 // binwidth 50
  177. #define NCPUBINS 24 // binwidth 100
  178. void ParseFile2( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  179. {
  180. binwidth=100;
  181. // Each bin is how many computers with the given card had cpus > cpubin
  182. // and less than the next bin so cpu 200 covers cpu's from 200 to 299
  183. CUtlVector<int> nCpuList;
  184. CUtlVector<int> nMemList;
  185. int nQuantity[NMEMBINS][NCPUBINS];
  186. for (int i=0; i < NMEMBINS; ++i)
  187. {
  188. for (int j=0; j< NCPUBINS; ++j)
  189. nQuantity[i][j]=0;
  190. }
  191. for ( int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range
  192. {
  193. nCpuList.AddToTail(i);
  194. }
  195. nMemList.AddToTail(0);
  196. int basemem=64;
  197. while ( basemem < 2050 )
  198. {
  199. nMemList.AddToTail(basemem);
  200. basemem<<=1;
  201. }
  202. int totalUsers=0;
  203. int maxram=0;
  204. while ( inbuf.TellGet() < size )
  205. {
  206. // Now parse the utlbuffer
  207. // file has fields of version, netspeed, ram, cpu and card type
  208. char pszVersion[256];
  209. int nNetSpeed, nRam, nCpu;
  210. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  211. // scan through the rest of the junk
  212. char chSentinel = ' ';
  213. int i=0;
  214. while (( chSentinel != '\n' ))
  215. {
  216. chSentinel = inbuf.GetChar();
  217. ++i;
  218. }
  219. // determine cpu bin
  220. if (nCpu < 0) // handle corrupt data
  221. continue;
  222. // handle outliers--bin is off the scale
  223. if ( nCpu > nCpuList[nCpuList.Size()-1] )
  224. continue;
  225. i=0;
  226. while ( nCpu > nCpuList[i] )
  227. {
  228. ++i;
  229. }
  230. int cpuIndex = i-1;
  231. assert(i<nCpuList.Size());
  232. // determine memory bin
  233. if (nRam < 0) // handle corrupt data
  234. continue;
  235. // handle outliers--bin is off the scale
  236. if ( nRam > nMemList[nMemList.Size()-1] )
  237. continue;
  238. i=0;
  239. while ( nRam > nMemList[i] )
  240. {
  241. ++i;
  242. }
  243. int memIndex = i-1;
  244. assert(i<nMemList.Size());
  245. // insert data
  246. assert(memIndex<NMEMBINS);
  247. assert(cpuIndex<NCPUBINS);
  248. (nQuantity[memIndex][cpuIndex])++;
  249. totalUsers++;
  250. //printf ("%d\n", totalUsers);
  251. if (nRam> maxram)
  252. maxram=nRam;
  253. }
  254. if (nCpuList.Size()>65000)
  255. {
  256. printf ("Too many points, increase bin width\n");
  257. }
  258. printf("TotalUsers %d\n", totalUsers);
  259. printf("Max ram %d\n", maxram);
  260. // write results to an output buffer
  261. outbuf.Printf ( "Cpu" ); // headers
  262. for (int j=1; j < nMemList.Size(); ++j)
  263. outbuf.Printf ("\tMemoryBin%d", nMemList[j]);
  264. outbuf.Printf ("\n");
  265. for ( int i=0; i < NCPUBINS; ++i )
  266. {
  267. outbuf.Printf ( "%d", nCpuList[i]);
  268. for (int j=0; j < NMEMBINS; ++j)
  269. outbuf.Printf ("\t%d", nQuantity[j][i]);
  270. outbuf.Printf ("\n");
  271. }
  272. }
  273. //-----------------------------------------------------------------------------
  274. // given cpu bin, plots number of users in a given network speed bin
  275. //
  276. // Parses buffer into fields and puts results into outbuf
  277. // size is size of the file read in
  278. //-----------------------------------------------------------------------------
  279. #define NNETBINS 9
  280. void ParseFile3( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  281. {
  282. binwidth=100;
  283. // Each bin is how many computers with the given card had cpus > cpubin
  284. // and less than the next bin so cpu 200 covers cpu's from 200 to 299
  285. CUtlVector<int> nCpuList;
  286. CUtlVector<int> nNetList;
  287. int nQuantity[NNETBINS][NCPUBINS];
  288. for (int i=0; i < NNETBINS; ++i)
  289. {
  290. for (int j=0; j< NCPUBINS; ++j)
  291. nQuantity[i][j]=0;
  292. }
  293. for (int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range
  294. {
  295. nCpuList.AddToTail(i);
  296. }
  297. nNetList.AddToTail(0);
  298. nNetList.AddToTail(28);
  299. nNetList.AddToTail(33);
  300. nNetList.AddToTail(56);
  301. nNetList.AddToTail(112);
  302. nNetList.AddToTail(256);
  303. nNetList.AddToTail(512);
  304. nNetList.AddToTail(1000);
  305. nNetList.AddToTail(2000);
  306. int totalUsers=0;
  307. int maxspeed=0;
  308. while ( inbuf.TellGet() < size )
  309. {
  310. // Now parse the utlbuffer
  311. // file has fields of version, netspeed, ram, cpu and card type
  312. char pszVersion[256];
  313. int nNetSpeed, nRam, nCpu;
  314. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  315. // scan through the rest of the junk
  316. char chSentinel = ' ';
  317. int i=0;
  318. while (( chSentinel != '\n' ))
  319. {
  320. chSentinel = inbuf.GetChar();
  321. ++i;
  322. }
  323. // determine cpu bin
  324. if (nCpu < 0) // handle corrupt data
  325. continue;
  326. // handle outliers--bin is off the scale
  327. if ( nCpu > nCpuList[nCpuList.Size()-1] )
  328. continue;
  329. i=0;
  330. while ( nCpu > nCpuList[i] )
  331. {
  332. ++i;
  333. }
  334. int cpuIndex = i-1;
  335. assert(i<nCpuList.Size());
  336. // determine netspeed bin
  337. if (nNetSpeed < 0) // handle corrupt data
  338. continue;
  339. // handle outliers--bin is off the scale
  340. if ( nNetSpeed > nNetList[nNetList.Size()-1] )
  341. continue;
  342. i=0;
  343. while ( nNetSpeed > nNetList[i] )
  344. {
  345. ++i;
  346. }
  347. int netIndex = i;
  348. assert(i<nNetList.Size());
  349. // insert data
  350. assert(netIndex<NNETBINS);
  351. assert(cpuIndex<NCPUBINS);
  352. (nQuantity[netIndex][cpuIndex])++;
  353. totalUsers++;
  354. //printf ("%d\n", totalUsers);
  355. if (nNetSpeed> maxspeed)
  356. maxspeed=nNetSpeed;
  357. }
  358. if (nCpuList.Size()>65000)
  359. {
  360. printf ("Too many points, increase bin width\n");
  361. }
  362. printf("TotalUsers %d\n", totalUsers);
  363. printf("Max ram %d\n", maxspeed);
  364. // write results to an output buffer
  365. outbuf.Printf ( "Cpu" ); // headers
  366. for (int j=0; j < nNetList.Size()-1; ++j)
  367. outbuf.Printf ("\t%d-%d", nNetList[j], nNetList[j+1]);
  368. outbuf.Printf ("\n");
  369. for (int i=0; i < NCPUBINS; ++i )
  370. {
  371. outbuf.Printf ( "%d", nCpuList[i]);
  372. for (int j=0; j < NNETBINS; ++j)
  373. outbuf.Printf ("\t%d", nQuantity[j][i]);
  374. outbuf.Printf ("\n");
  375. }
  376. }
  377. //-----------------------------------------------------------------------------
  378. // given time bin, plots number of users in a given cpu TYPE over time,
  379. // as the numbers came into the server
  380. //
  381. // Parses buffer into fields and puts results into outbuf
  382. // size is size of the file read in
  383. //-----------------------------------------------------------------------------
  384. #define CPUBINS 3 // 0=AMD, 1=Intel, 2=Unknown
  385. #define MAXUSERS 750000
  386. void TimeSeriesCPU( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  387. {
  388. binwidth=600;
  389. // unequally sized bins
  390. // Each bin is how many computers with the given card had cpus > cpubin
  391. // and less than the next bin so cpu 200 covers cpu's from 200 to 299
  392. CUtlVector<int> nTimeList;
  393. int nQuantity[30][CPUBINS];
  394. for (int i=0; i < 30; ++i)
  395. {
  396. for (int j=0; j< CPUBINS; ++j)
  397. nQuantity[i][j]=0;
  398. }
  399. nTimeList.AddToTail(0);
  400. int bin=10000;
  401. int i=bin;
  402. for (i; i<=MAXUSERS; i=bin)
  403. {
  404. nTimeList.AddToTail(i);
  405. bin<<=1;
  406. }
  407. nTimeList.AddToTail(i);
  408. // for unequal bins
  409. int currentTimeBin=1;
  410. int totalUsers=0;
  411. while ( (inbuf.TellGet() < size) )
  412. {
  413. // Now parse the utlbuffer
  414. // file has fields of version, netspeed, ram, cpu and card type
  415. char pszVersion[256];
  416. int nNetSpeed, nRam, nCpu;
  417. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  418. char pszCard[300];
  419. char chSentinel = ' ';
  420. int i=0;
  421. while (( chSentinel != '\n' ))
  422. {
  423. chSentinel = inbuf.GetChar();
  424. pszCard[i] = chSentinel;
  425. ++i;
  426. if (i >= 300)
  427. break;
  428. }
  429. // check for those blasted hackers
  430. if (i>= 300)
  431. {
  432. // read rest
  433. while (( chSentinel != '\n' ))
  434. {
  435. chSentinel = inbuf.GetChar();
  436. }
  437. continue;
  438. }
  439. pszCard[i] = '\0';
  440. int cpuIndex=2; // default is unknown
  441. if ( Q_stristr ( pszCard, "SSE" ) != NULL )
  442. {
  443. cpuIndex=1; // intel
  444. }
  445. else if ( Q_stristr ( pszCard, "KNI" ) != NULL )
  446. {
  447. cpuIndex=1; // intel
  448. }
  449. else if ( Q_stristr ( pszCard, "3DNOW" ) != NULL )
  450. {
  451. cpuIndex=0;
  452. }
  453. // update nTimeList bin if necessary
  454. if (nTimeList[currentTimeBin] <= totalUsers)
  455. {
  456. currentTimeBin++;
  457. }
  458. nQuantity[currentTimeBin][cpuIndex]++;
  459. assert(nQuantity[currentTimeBin][cpuIndex]>0);
  460. totalUsers++;
  461. }
  462. printf("TotalUsers %d\n", totalUsers);
  463. // write results to an output buffer
  464. outbuf.Printf ( "CPU" ); // headers
  465. for (int j=1; j < nTimeList.Size(); ++j)
  466. outbuf.Printf ("\tUsersSoFar%d", nTimeList[j]);
  467. outbuf.Printf ("\n");
  468. for (int i=0; i < CPUBINS; ++i )
  469. {
  470. outbuf.Printf ( "-");
  471. for (int j=1; j < nTimeList.Size(); ++j) // use NTIMEBINS for equal sized bins
  472. outbuf.Printf ("\t%d", nQuantity[j][i]);
  473. outbuf.Printf ("\n");
  474. }
  475. }
  476. //-----------------------------------------------------------------------------
  477. // given time bin, plots number of users in a given video card TYPE over time,
  478. // as the numbers came into the server
  479. //
  480. // Parses buffer into fields and puts results into outbuf
  481. // size is size of the file read in
  482. //-----------------------------------------------------------------------------
  483. // 0=RIVA TNT
  484. // 1=GeForce2 MX
  485. // 2=Microsoft Corporation GDI Generic
  486. // 3=GeForce2 GTS
  487. // 4=Voodoo 3
  488. // 5=Intel 810
  489. // 6=GeForce3
  490. #define CARDBINS 8
  491. void TimeSeriesVCard( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  492. {
  493. // unequally sized bins
  494. CUtlVector<int> nTimeList;
  495. int nQuantity[30][CARDBINS];
  496. for (int i=0; i < 30; ++i)
  497. {
  498. for (int j=0; j< CARDBINS; ++j)
  499. nQuantity[i][j]=0;
  500. }
  501. nTimeList.AddToTail(0);
  502. int bin=10000;
  503. int i=bin;
  504. for (i; i<=MAXUSERS; i=bin)
  505. {
  506. nTimeList.AddToTail(i);
  507. bin<<=1;
  508. }
  509. nTimeList.AddToTail(i);
  510. //int currentTimeBin=1;
  511. // for unequal bins
  512. int currentTimeBin=1;
  513. int numTimeBins=nTimeList.Size();
  514. int totalUsers=0;
  515. while ( (inbuf.TellGet() < size) )
  516. {
  517. // Now parse the utlbuffer
  518. // file has fields of version, netspeed, ram, cpu and card type
  519. char pszVersion[256];
  520. int nNetSpeed, nRam, nCpu;
  521. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  522. char pszCard[300];
  523. char chSentinel = ' ';
  524. int i=0;
  525. while (( chSentinel != '\n' ))
  526. {
  527. chSentinel = inbuf.GetChar();
  528. pszCard[i] = chSentinel;
  529. ++i;
  530. if (i >= 300)
  531. break;
  532. }
  533. // check for those blasted hackers
  534. if (i>= 300)
  535. {
  536. // read rest
  537. while (( chSentinel != '\n' ))
  538. {
  539. chSentinel = inbuf.GetChar();
  540. }
  541. continue;
  542. }
  543. pszCard[i] = '\0';
  544. // 0=RIVA TNT
  545. // 1=GeForce2 MX
  546. // 2=Microsoft Corporation GDI Generic
  547. // 3=GeForce2 GTS
  548. // 4=Voodoo 3
  549. // 5=Intel 810
  550. // 6=GeForce3
  551. // 7=All others
  552. int cardIndex=7; // default is other
  553. if ( Q_stristr ( pszCard, "RIVA TNT2" ) != NULL )
  554. {
  555. //printf ("%s", pszCard);
  556. cardIndex=0;
  557. }
  558. else if ( Q_stristr ( pszCard, "GeForce2 MX" ) != NULL )
  559. {
  560. cardIndex=1;
  561. }
  562. else if ( Q_stristr ( pszCard, "Microsoft Corporation GDI Generic" ) != NULL )
  563. {
  564. cardIndex=2;
  565. }
  566. else if ( Q_stristr ( pszCard, "GeForce2 GTS" ) != NULL )
  567. {
  568. cardIndex=3;
  569. }
  570. else if ( Q_stristr ( pszCard, "Voodoo3" ) != NULL )
  571. {
  572. cardIndex=4;
  573. }
  574. else if ( Q_stristr ( pszCard, "Intel 810" ) != NULL )
  575. {
  576. cardIndex=5;
  577. }
  578. else if ( Q_stristr ( pszCard, "GeForce3" ) != NULL )
  579. {
  580. cardIndex=6;
  581. }
  582. // update nTimeList bin if necessary
  583. if (nTimeList[currentTimeBin] <= totalUsers)
  584. {
  585. currentTimeBin++;
  586. }
  587. nQuantity[currentTimeBin][cardIndex]++;
  588. totalUsers++;
  589. }
  590. printf("TotalUsers %d\n", totalUsers);
  591. // write results to an output buffer
  592. outbuf.Printf ( "Video Card" ); // headers
  593. for (int j=1; j < nTimeList.Size(); ++j)
  594. outbuf.Printf ("\tUsersSoFar%d", nTimeList[j]);
  595. outbuf.Printf ("\n");
  596. for (int i=0; i < CARDBINS; ++i )
  597. {
  598. outbuf.Printf ( "-");
  599. for (int j=1; j < numTimeBins; ++j) // use NTIMEBINS for equal sized bins
  600. outbuf.Printf ("\t%d", nQuantity[j][i]);
  601. outbuf.Printf ("\n");
  602. }
  603. }
  604. //-----------------------------------------------------------------------------
  605. // Increment the proper bin's counter
  606. //-----------------------------------------------------------------------------
  607. void InsertResult( int nCpu, CUtlVector<int> &nCpuList, CUtlVector<int> &nQuantity )
  608. {
  609. if (nCpu < 0) // handle corrupt data
  610. return;
  611. // handle outliers--bin is off the scale
  612. if ( nCpu > nCpuList[nCpuList.Size()-1] )
  613. {
  614. //nCpuList.AddToTail( nCpu );
  615. //nQuantity.AddToTail( 1 );
  616. return;
  617. }
  618. int i=0;
  619. while ( nCpu > nCpuList[i] )
  620. {
  621. ++i;
  622. }
  623. nQuantity[i-1]++;
  624. }
  625. void HistogramVidCards( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  626. {
  627. #define CARDHISTBINS 15
  628. // unequally sized bins
  629. int nQuantity[CARDHISTBINS];
  630. for (int j=0; j< CARDHISTBINS; ++j)
  631. nQuantity[j]=0;
  632. int totalUsers=0;
  633. while ( (inbuf.TellGet() < size) )
  634. {
  635. // Now parse the utlbuffer
  636. // file has fields of version, netspeed, ram, cpu and card type
  637. char pszVersion[256];
  638. int nNetSpeed, nRam, nCpu;
  639. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  640. char pszCard[300];
  641. char chSentinel = ' ';
  642. int i=0;
  643. while (( chSentinel != '\n' ))
  644. {
  645. chSentinel = inbuf.GetChar();
  646. pszCard[i] = chSentinel;
  647. ++i;
  648. if (i >= 300)
  649. break;
  650. }
  651. // check for those blasted hackers
  652. if (i>= 300)
  653. {
  654. // read rest
  655. while (( chSentinel != '\n' ))
  656. {
  657. chSentinel = inbuf.GetChar();
  658. }
  659. continue;
  660. }
  661. pszCard[i] = '\0';
  662. // 0=RIVA TNT2
  663. // 1=GeForce2 MX
  664. // 2=Microsoft Corporation GDI Generic
  665. // 3=GeForce2 GTS
  666. // 4=Voodoo 3
  667. // 5=Intel 810
  668. // 6=GeForce3
  669. // 7=Riva TNT
  670. // 8=GeForce 256
  671. // 9=Rage 128
  672. // 10=S3 Savage4
  673. // 11=SiS 630
  674. // 12=Radeon DDR
  675. // 13=Rage 128 Pro
  676. // 14=All others
  677. int cardIndex=14; // default is other
  678. if ( Q_stristr ( pszCard, "RIVA TNT2" ) != NULL )
  679. {
  680. //printf ("%s", pszCard);
  681. cardIndex=0;
  682. }
  683. else if ( Q_stristr ( pszCard, "GeForce2 MX" ) != NULL )
  684. {
  685. cardIndex=1;
  686. }
  687. else if ( Q_stristr ( pszCard, "Microsoft Corporation GDI Generic" ) != NULL )
  688. {
  689. cardIndex=2;
  690. }
  691. else if ( Q_stristr ( pszCard, "GeForce2 GTS" ) != NULL )
  692. {
  693. cardIndex=3;
  694. }
  695. else if ( Q_stristr ( pszCard, "Voodoo3" ) != NULL )
  696. {
  697. cardIndex=4;
  698. }
  699. else if ( Q_stristr ( pszCard, "Intel 810" ) != NULL )
  700. {
  701. cardIndex=5;
  702. }
  703. else if ( Q_stristr ( pszCard, "GeForce3" ) != NULL )
  704. {
  705. cardIndex=6;
  706. }
  707. else if ( Q_stristr ( pszCard, "Riva TNT" ) != NULL )
  708. {
  709. cardIndex=7;
  710. }
  711. else if ( Q_stristr ( pszCard, "GeForce 256" ) != NULL )
  712. {
  713. cardIndex=8;
  714. }
  715. else if ( Q_stristr ( pszCard, "Rage 128 Pro" ) != NULL )
  716. {
  717. cardIndex=13;
  718. }
  719. else if ( Q_stristr ( pszCard, "Rage 128" ) != NULL )
  720. {
  721. cardIndex=9;
  722. }
  723. else if ( Q_stristr ( pszCard, "S3 Savage4" ) != NULL )
  724. {
  725. cardIndex=10;
  726. }
  727. else if ( Q_stristr ( pszCard, "SiS 630" ) != NULL )
  728. {
  729. cardIndex=11;
  730. }
  731. else if ( Q_stristr ( pszCard, "Radeon DDR" ) != NULL )
  732. {
  733. cardIndex=12;
  734. }
  735. nQuantity[cardIndex]++;
  736. totalUsers++;
  737. }
  738. printf("TotalUsers %d\n", totalUsers);
  739. // write results to an output buffer
  740. outbuf.Printf ( "Video Card" ); // headers
  741. outbuf.Printf ("\tNumber of Users\n");
  742. outbuf.Printf ("\n");
  743. for ( int i=0; i < CARDHISTBINS; ++i )
  744. {
  745. outbuf.Printf ( "-");
  746. outbuf.Printf ("\t%d", nQuantity[i]);
  747. outbuf.Printf ("\n");
  748. }
  749. }
  750. void HistogramNetSpeed( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  751. {
  752. #define NETHISTBINS 9
  753. // unequally sized bins
  754. int nQuantity[NETHISTBINS];
  755. for (int j=0; j< NETHISTBINS; ++j)
  756. nQuantity[j]=0;
  757. CUtlVector<int> nNetList;
  758. nNetList.AddToTail(0);
  759. nNetList.AddToTail(28);
  760. nNetList.AddToTail(33);
  761. nNetList.AddToTail(56);
  762. nNetList.AddToTail(112);
  763. nNetList.AddToTail(256);
  764. nNetList.AddToTail(512);
  765. nNetList.AddToTail(1100);
  766. nNetList.AddToTail(2000);
  767. int totalUsers=0;
  768. while ( (inbuf.TellGet() < size) )
  769. {
  770. // Now parse the utlbuffer
  771. // file has fields of version, netspeed, ram, cpu and card type
  772. char pszVersion[256];
  773. int nNetSpeed, nRam, nCpu;
  774. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  775. char pszCard[300];
  776. char chSentinel = ' ';
  777. int i=0;
  778. while (( chSentinel != '\n' ))
  779. {
  780. chSentinel = inbuf.GetChar();
  781. pszCard[i] = chSentinel;
  782. ++i;
  783. if (i >= 300)
  784. break;
  785. }
  786. // check for those blasted hackers
  787. if (i>= 300)
  788. {
  789. // read rest
  790. while (( chSentinel != '\n' ))
  791. {
  792. chSentinel = inbuf.GetChar();
  793. }
  794. continue;
  795. }
  796. pszCard[i] = '\0';
  797. if (nNetSpeed < 0) // handle corrupt data
  798. continue;
  799. // handle outliers--bin is off the scale
  800. if ( nNetSpeed > nNetList[nNetList.Size()-1] )
  801. continue;
  802. i=0;
  803. while ( nNetSpeed > nNetList[i] )
  804. {
  805. ++i;
  806. }
  807. int netIndex = i;
  808. nQuantity[netIndex]++;
  809. totalUsers++;
  810. }
  811. printf("TotalUsers %d\n", totalUsers);
  812. // write results to an output buffer
  813. outbuf.Printf ( "Network Speed" ); // headers
  814. for (int j=0; j < nNetList.Size()-1; ++j)
  815. outbuf.Printf ("\t%d-%d", nNetList[j], nNetList[j+1]);
  816. outbuf.Printf ("\n");
  817. for ( int i=0; i < NETHISTBINS; ++i )
  818. {
  819. outbuf.Printf ( "-");
  820. outbuf.Printf ("\t%d", nQuantity[i]);
  821. outbuf.Printf ("\n");
  822. }
  823. }
  824. void HistogramRam( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth)
  825. {
  826. #define RAMHISTBINS 20
  827. // unequally sized bins
  828. int nQuantity[RAMHISTBINS];
  829. for (int j=0; j< RAMHISTBINS; ++j)
  830. nQuantity[j]=0;
  831. CUtlVector<int> nRamList;
  832. nRamList.AddToTail(0);
  833. int basemem=16;
  834. while ( basemem < 2050 )
  835. {
  836. nRamList.AddToTail(basemem);
  837. basemem<<=1;
  838. }
  839. int totalUsers=0;
  840. while ( (inbuf.TellGet() < size) )
  841. {
  842. // Now parse the utlbuffer
  843. // file has fields of version, netspeed, ram, cpu and card type
  844. char pszVersion[256];
  845. int nNetSpeed, nRam, nCpu;
  846. inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu );
  847. char pszCard[300];
  848. char chSentinel = ' ';
  849. int i=0;
  850. while (( chSentinel != '\n' ))
  851. {
  852. chSentinel = inbuf.GetChar();
  853. pszCard[i] = chSentinel;
  854. ++i;
  855. if (i >= 300)
  856. break;
  857. }
  858. // check for those blasted hackers
  859. if (i>= 300)
  860. {
  861. // read rest
  862. while (( chSentinel != '\n' ))
  863. {
  864. chSentinel = inbuf.GetChar();
  865. }
  866. continue;
  867. }
  868. pszCard[i] = '\0';
  869. if (nRam < 0) // handle corrupt data
  870. continue;
  871. // handle outliers--bin is off the scale
  872. if ( nRam > nRamList[nRamList.Size()-1] )
  873. continue;
  874. i=0;
  875. while ( nRam > nRamList[i] )
  876. {
  877. ++i;
  878. }
  879. int ramIndex = i;
  880. nQuantity[ramIndex]++;
  881. totalUsers++;
  882. }
  883. printf("TotalUsers %d\n", totalUsers);
  884. // write results to an output buffer
  885. outbuf.Printf ( "RAM" ); // headers
  886. for (int j=0; j < nRamList.Size()-1; ++j)
  887. outbuf.Printf ("\t%d-%d", nRamList[j], nRamList[j+1]);
  888. outbuf.Printf ("\n");
  889. for ( int i=0; i < nRamList.Size(); ++i )
  890. {
  891. outbuf.Printf ( "-");
  892. outbuf.Printf ("\t%d", nQuantity[i]);
  893. outbuf.Printf ("\n");
  894. }
  895. }