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.

262 lines
8.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implementation of CPlayerReport;
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //------------------------------------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "util.h"
  14. #include "PlayerReport.h"
  15. #include "PlrPersist.h"
  16. map<unsigned long,bool> CPlayerReport::alreadyPersisted;
  17. map<unsigned long,bool> CPlayerReport::alreadyWroteCombStats;
  18. //------------------------------------------------------------------------------------------------------
  19. // Function: CPlayerReport::writeHTML
  20. // Purpose: writes the player's stats out as HTML
  21. // Input: html - the html file to which we're writing
  22. //------------------------------------------------------------------------------------------------------
  23. void CPlayerReport::writeHTML(CHTMLFile& html)
  24. {
  25. //if we're writing the stats for a persistent player, just pass execution off to that function!
  26. if (reportingPersistedPlayer)
  27. {
  28. writePersistHTML(html);
  29. return;
  30. }
  31. pPlayer->totalTimeOn(); //this ensures that the logoff time is correct
  32. if (iWhichTeam==ALL_TEAMS)
  33. pPlayer->merge();
  34. else if (!pPlayer->teams.contains(iWhichTeam))
  35. {
  36. return;
  37. }
  38. int tid=iWhichTeam;
  39. if (tid==ALL_TEAMS)
  40. html.write("<font class=headline>%s</font><br>\n",pPlayer->name.c_str());
  41. else
  42. html.write("<font class=player%s2>%s</font><hr align=left width=60%%>\n",Util::teamcolormap[tid],pPlayer->name.c_str());
  43. if (pPlayer->aliases.size() > 1)
  44. {
  45. map<string,bool> namePrinted;
  46. namePrinted[pPlayer->name.c_str()]=true;
  47. html.write("<font class=whitetext>aliases:</font> <font class=awards2>");
  48. CTimeIndexedList<string>::iterator nmiter=pPlayer->aliases.begin();
  49. bool printed1=false;
  50. for (nmiter;nmiter!=pPlayer->aliases.end();++nmiter)
  51. {
  52. if (namePrinted[nmiter->data]!=true)
  53. {
  54. if (printed1)
  55. html.write(", ");
  56. html.write(nmiter->data.c_str());
  57. namePrinted[nmiter->data]=true;
  58. printed1=true;
  59. }
  60. }
  61. html.write("</font><br>\n");
  62. }
  63. html.write("<font class=whitetext>rank:</font> <font class=awards2> %.2lf </font><br>\n",pPlayer->perteam[tid].rank());
  64. html.write("<font class=whitetext>kills/deaths:</font> <font class=awards2>%li/%li </font><br>\n",pPlayer->perteam[tid].kills,pPlayer->perteam[tid].deaths);
  65. html.write("<font class=whitetext>time:</font> <font class=awards2> %01li:%02li:%02li </font><br>\n",Util::time_t2hours(pPlayer->perteam[tid].timeOn()),Util::time_t2mins(pPlayer->perteam[tid].timeOn()),Util::time_t2secs(pPlayer->perteam[tid].timeOn()));
  66. int numClassesPlayed=pPlayer->perteam[tid].classesplayed.numDifferent();
  67. player_class faveClass=pPlayer->perteam[tid].classesplayed.favourite();
  68. if (numClassesPlayed == 1)
  69. {
  70. if (faveClass!=PC_UNDEFINED)
  71. html.write("<font class=whitetext>class:</font> <font class=awards2> %s </font><br>\n",plrClassNames[faveClass]);
  72. }
  73. else if (numClassesPlayed > 1)
  74. {
  75. if (faveClass!=PC_UNDEFINED)
  76. html.write("<font class=whitetext>favorite class:</font> <font class=awards2> %s </font><br>\n",plrClassNames[faveClass]);
  77. html.write("<font class=whitetext>classes played:</font> <font class=awards2> ");
  78. bool printedone=false;
  79. for(int pc=PC_SCOUT;pc!=PC_OBSERVER;++pc)
  80. {
  81. if (pPlayer->perteam[tid].classesplayed.contains((player_class)pc))
  82. {
  83. if (printedone)
  84. html.write(", ");
  85. html.write(plrClassNames[pc]);
  86. printedone=true;
  87. }
  88. }
  89. html.write(" </font><br>\n");
  90. }
  91. const string weap=pPlayer->perteam[tid].faveWeapon();
  92. const string faveWeap=Util::getFriendlyWeaponName(weap);
  93. if (pPlayer->perteam[tid].kills!=0)
  94. {
  95. char lowerWeapName[50];
  96. Util::str2lowercase(lowerWeapName,faveWeap.c_str());
  97. html.write("<font class=whitetext>favorite weapon:</font> <font class=awards2> %s</font><br>\n",faveWeap.c_str());
  98. html.write("<font class=whitetext>kills with %s:</font> <font class=awards2> %li</font><br>\n",lowerWeapName,pPlayer->perteam[tid].faveWeapKills());
  99. }
  100. int numTeamsPlayed=pPlayer->teams.numDifferent();
  101. if (numTeamsPlayed > 1)
  102. {
  103. if (iWhichTeam==ALL_TEAMS)
  104. html.write("<font class=whitetext>Played on</font> <font class=whitetext> ");
  105. else
  106. html.write("<font class=whitetext>Also played on</font> <font class=whitetext> ");
  107. map<int,bool> alreadyPrinted;
  108. CTimeIndexedList<int>::iterator tmiter=pPlayer->teams.begin();
  109. bool printed1=false;
  110. for (tmiter;tmiter!=pPlayer->teams.end();++tmiter)
  111. {
  112. int team=tmiter->data;
  113. if (team != iWhichTeam && !alreadyPrinted[team])
  114. {
  115. if (printed1)
  116. html.write(" and ");
  117. html.write("<font class=player%s>%s</font>",Util::teamcolormap[team],Util::teamcolormap[team]);//
  118. printed1=true;
  119. alreadyPrinted[team]=true;
  120. }
  121. }
  122. html.write("</font><br>\n");
  123. }
  124. if (numTeamsPlayed > 1 && iWhichTeam != ALL_TEAMS)
  125. {
  126. html.write("<a class=whitetext href=\"%lu.html\"> <u> Combined stats for this match </u> </a> <br> \n",pPlayer->pid);
  127. if (!alreadyWroteCombStats[pPlayer->pid])
  128. {
  129. CPlayerReport cpr(pPlayer,ALL_TEAMS);
  130. char numbuf[200];
  131. char namebuf[200];
  132. sprintf(numbuf,"%lu.html",pPlayer->pid);
  133. sprintf(namebuf,"Combined match statistics for %s",pPlayer->name.c_str());
  134. cpr.makeHTMLPage(numbuf,namebuf);
  135. alreadyWroteCombStats[pPlayer->pid]=true;
  136. }
  137. }
  138. if (g_pApp->cmdLineSwitches["persistplayerstats"]=="yes" && !g_pMatchInfo->isLanGame())
  139. html.write("<a class=whitetext href=\"%s/allplayers.html#%lu\"> <u> Combined stats on this server </u> </a> <br> \n",g_pApp->playerHTTPPath.c_str(),pPlayer->WONID,pPlayer->name.c_str());
  140. if (g_pMatchInfo->isLanGame())
  141. return;
  142. if (alreadyPersisted[pPlayer->WONID] || reportingPersistedPlayer)
  143. return;
  144. alreadyPersisted[pPlayer->WONID]=true;
  145. if (g_pApp->cmdLineSwitches["persistplayerstats"]=="yes")
  146. {
  147. CPlrPersist cpp;
  148. CPlrPersist onDisk;
  149. cpp.generate(*pPlayer);
  150. onDisk.read(pPlayer->WONID);
  151. cpp.merge(onDisk);
  152. cpp.write();
  153. }
  154. }
  155. //------------------------------------------------------------------------------------------------------
  156. // Function: CPlayerReport::writePersistHTML
  157. // Purpose: writes a persistent player's stats out. these look slightly different
  158. // than normal players stats
  159. // Input: html - the html file to write the html to
  160. //------------------------------------------------------------------------------------------------------
  161. void CPlayerReport::writePersistHTML(CHTMLFile& html)
  162. {
  163. html.write("<a name=\"%lu\">\n",pPersist->WONID);
  164. html.write("<font class=headline2>%s</font><hr align=left width=60%%>\n",pPersist->faveName().c_str());
  165. map<string,bool> namePrinted;
  166. namePrinted[pPersist->faveName()]=true;
  167. map<string,int>::iterator nmiter=pPersist->nickmap.begin();
  168. bool printed1=false;
  169. for (nmiter;nmiter!=pPersist->nickmap.end();++nmiter)
  170. {
  171. if (namePrinted[nmiter->first]!=true)
  172. {
  173. if (!printed1)
  174. html.write("<font class=whitetext>other names used:</font> <font class=awards2>");
  175. if (printed1)
  176. html.write(", ");
  177. html.write(nmiter->first.c_str());
  178. namePrinted[nmiter->first]=true;
  179. printed1=true;
  180. }
  181. }
  182. if (printed1)
  183. html.write("</font><br>\n");
  184. html.write("<font class=whitetext>rank:</font> <font class=awards2> %.2lf </font><br>\n",pPersist->rank());
  185. html.write("<font class=whitetext>kills/deaths:</font> <font class=awards2>%li/%li </font><br>\n",pPersist->kills,pPersist->deaths);
  186. html.write("<font class=whitetext>time:</font> <font class=awards2> %01li:%02li:%02li </font><br>\n",Util::time_t2hours(pPersist->timeon),Util::time_t2mins(pPersist->timeon),Util::time_t2secs(pPersist->timeon));
  187. html.write("<font class=whitetext>matches played:</font> <font class=awards2> %li </font><br>\n",pPersist->matches);
  188. string faveClass=pPersist->faveClass();
  189. if (faveClass!="Undefined")
  190. html.write("<font class=whitetext>favorite class:</font> <font class=awards2> %s </font><br>\n",faveClass.c_str());
  191. bool printedone=false;
  192. map<string,int>::iterator classit=pPersist->classmap.begin();
  193. map<string,bool> classPrinted;
  194. classPrinted[pPersist->faveClass()]=true;
  195. for(classit;classit!=pPersist->classmap.end();++classit)
  196. {
  197. if (classPrinted[classit->first]==false)
  198. {
  199. if (!printedone)
  200. html.write("<font class=whitetext>other classes played:</font> <font class=awards2> ");
  201. if (printedone)
  202. html.write(", ");
  203. html.write(classit->first.c_str());
  204. classPrinted[classit->first]=true;
  205. printedone=true;
  206. }
  207. }
  208. if (printedone)
  209. html.write(" </font><br>\n");
  210. const string weap=pPersist->faveWeap();
  211. const string faveWeap=Util::getFriendlyWeaponName(weap);
  212. if (pPersist->kills!=0)
  213. {
  214. char lowerWeapName[50];
  215. Util::str2lowercase(lowerWeapName,faveWeap.c_str());
  216. html.write("<font class=whitetext>favorite weapon:</font> <font class=awards2> %s</font><br>\n",faveWeap.c_str());
  217. html.write("<font class=whitetext>kills with %s:</font> <font class=awards2> %li</font><br>\n",lowerWeapName,pPersist->faveweapkills);
  218. }
  219. }