diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/tfstats/tfstatsapplication.cpp | |
| download | archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip | |
Diffstat (limited to 'utils/tfstats/tfstatsapplication.cpp')
| -rw-r--r-- | utils/tfstats/tfstatsapplication.cpp | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/utils/tfstats/tfstatsapplication.cpp b/utils/tfstats/tfstatsapplication.cpp new file mode 100644 index 0000000..f7f441e --- /dev/null +++ b/utils/tfstats/tfstatsapplication.cpp @@ -0,0 +1,467 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#pragma warning (disable:4786) +//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: Implementation of the TFStatsApplication class. +// +// $Workfile: $ +// $Date: $ +// +//------------------------------------------------------------------------------------------------------ +// $Log: $ +// +// $NoKeywords: $ +//============================================================================= + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include "TFStatsApplication.h" +#include "TFStatsReport.h" +#include "LogEvent.h" +#include "ScoreBoard.h" +#include "WhoKilledWho.h" +#include "memdbg.h" +#include "awards.h" +#include "MatchResults.h" +#include "DialogueReadout.h" +#include "cvars.h" +#include "html.h" +#include "TextFile.h" +#include "CustomAward.h" +#include "PlayerSpecifics.h" +#include "util.h" +#include "AllPlayersStats.h" +#include <errno.h> + + + +CTFStatsApplication* g_pApp; //global! + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::printUsage +// Purpose: Prints out how to use the program +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::printUsage() +{ + + printf("TFStats version %li.%li\n",majorVer,minorVer); + printf("\nUSAGE:\n"); +#ifdef WIN32 + printf("TFstatsRT.exe <log file name> <optional switches>\n"); +#else + printf("TFstats_l <log file name> <optional switches>\n"); +#endif + printf("the available switches are detailed in the documentation. (TFStats.htm): \n"); + printf("---\n"); + printf("After TFStats is done, several new HTML files will be in the current directory,\n"); + printf("point your browser to the index.html in this directory and it will do the rest.\n"); +#ifdef WIN32 + printf("(you should just be able to do \"start index.html\")\n"); +#endif + printf("TFStats uses Regex++:\nRegex++ � 1998-9 Dr John Maddock.\n"); + +} + +#include "CustomAwardList.h" + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::DoAwards +// Purpose: This reports all of the awards +// Input: MatchResultsPage - the page on which to write the awards' HTML +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::DoAwards(CHTMLFile& MatchResultsPage) +{ + int chresult=os->chdir(g_pApp->outputDirectory.c_str()); + + MatchResultsPage.p(); + MatchResultsPage.write("<img src=\"%s/awards.gif\">\n",g_pApp->supportHTTPPath.c_str()); + MatchResultsPage.div("awards"); + + //do custom awards first, they're usually the important ones for the match + CCustomAwardList* pCust; + os->chdir(ruleDirectory.c_str()); + pCust=CCustomAwardList::readCustomAwards(g_pMatchInfo->mapName()); + os->chdir(outputDirectory.c_str()); + if(pCust) + { + + CCustomAwardIterator it; + for (it=pCust->begin();it!=pCust->end();++it) + { + (*it)->report(MatchResultsPage); + } + + delete pCust; + MatchResultsPage.hr(450,true); + } + os->chdir(outputDirectory.c_str()); + + //do scout award here. + CSurvivalistAward csrva; csrva.report(MatchResultsPage); + + //sniper award + CSharpshooterAward cssa; cssa.report(MatchResultsPage); + + //soldier award + CRocketryAward cra; cra.report(MatchResultsPage); + + //demoman awards + CGrenadierAward cga; cga.report(MatchResultsPage); + CDemolitionsAward cda; cda.report(MatchResultsPage); + + //medic awards + CCureAward cca;cca.report(MatchResultsPage); + CBiologicalWarfareAward cbwa; cbwa.report(MatchResultsPage); + + //HW award + CAssaultCannonAward caca;caca.report(MatchResultsPage); + + //pyro award + CFlamethrowerAward cfa;cfa.report(MatchResultsPage); + + //spy award + CKnifeAward cka;cka.report(MatchResultsPage); + + //engineer awards + CBestSentryAward cbsa; cbsa.report(MatchResultsPage); + CSentryRebuildAward cba2;cba2.report(MatchResultsPage); + + + MatchResultsPage.hr(450,true); + + //non class specific + CKamikazeAward ckami;ckami.report(MatchResultsPage); + CTalkativeAward cta;cta.report(MatchResultsPage); + CTeamKillAward ctka; ctka.report(MatchResultsPage); + + + + + MatchResultsPage.enddiv(); +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::DoMatchResults +// Purpose: This creates the MatchResults page of the report (the main page) +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::DoMatchResults() +{ + int chresult=os->chdir(g_pApp->outputDirectory.c_str()); + CHTMLFile MatchResultsPage("MatchResults.html","results"); + CMatchResults cmr; + cmr.report(MatchResultsPage); + DoAwards(MatchResultsPage); + + CScoreboard cs; + cs.report(MatchResultsPage); + + + CWhoKilledWho cwkw; cwkw.report(MatchResultsPage); + +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::parseCmdLineArg +// Purpose: This parses variables and values out of passed in commandline args +// Input: in - the full command line argument +// var - the output buffer in which to place the name of the variable +// val - the output buffer in which to place the value of the variable +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::parseCmdLineArg(const char* in, char* var, char* val) +{ + char* pEq=strchr(in,'='); + if (!pEq || pEq==in) + { + var[0]=val[0]=0; + } + else + { + *pEq=0; + strcpy(var,in); + strcpy(val,pEq+1); + Util::str2lowercase(var,var); + Util::str2lowercase(val,val); + *pEq='='; + } + +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::ParseCommandLine +// Purpose: this parses the commandline into the cmdLineSwitches map. Also +// recognizes certain switches and sets variables and creates directories +// accordingly to their values +// Input: argc - count of arguments from commandline +// argv[] - the arguments +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::ParseCommandLine(int argc,const char* argv[]) +{ + char var[100]; + char val[100]; + + //first find if we want to display startup info + bool displayStartupInfo=false; + for(int i=2;i<argc;i++) + { + parseCmdLineArg(argv[i],var,val); + if (!var[0]) + fatalError("Malformed switch, required format is <variable>=<value> with no spaces"); + + cmdLineSwitches[var]=val; + if (stricmp(var,"displaystartupinfo")==0) + if (stricmp(val,"yes")==0) + { + displayStartupInfo=true; + break; + } + } + + + + if (displayStartupInfo) + { + printf("%21s %-21s\n","Command line","Switches"); + printf("-------------------------------------------\n"); + } + for(i=2;i<argc;i++) + { + parseCmdLineArg(argv[i],var,val); + if (!var[0]) + fatalError("Malformed switch, required format is <variable>=<value> with no spaces"); + + if (displayStartupInfo) + printf("%20s = %-20s\n",var,val); + cmdLineSwitches[var]=val; + } + + + + outputDirectory=os->removeDirSlash(cmdLineSwitches["outputdir"]); + makeAndSaveDirectory(outputDirectory); + + ruleDirectory=os->removeDirSlash(cmdLineSwitches["ruledir"]); + makeAndSaveDirectory(ruleDirectory); + + if (cmdLineSwitches["eliminateoldplayers"]=="yes") + { + eliminateOldPlayers=true; + elimDays=atoi(cmdLineSwitches["oldplayercutoff"].c_str()); + } + else + { + eliminateOldPlayers=false; + elimDays=0; + } + + + if (cmdLineSwitches["usesupportdir"]=="yes") + { + supportDirectory=os->removeDirSlash(cmdLineSwitches["supportdir"]); + supportHTTPPath=os->removeDirSlash(cmdLineSwitches["supporthttppath"]); + } + else + { + supportDirectory=g_pApp->outputDirectory+g_pApp->os->pathSeperator(); + supportDirectory+="support"; + supportHTTPPath="support"; + } + makeAndSaveDirectory(supportDirectory); + + + if (cmdLineSwitches["persistplayerstats"]=="yes") + { + playerDirectory=os->removeDirSlash(cmdLineSwitches["playerdir"]); + playerHTTPPath=os->removeDirSlash(cmdLineSwitches["playerhttppath"]); + } + else + { + playerDirectory=g_pApp->outputDirectory+g_pApp->os->pathSeperator(); + playerDirectory+="players"; + playerHTTPPath="players"; + } + makeAndSaveDirectory(playerDirectory); + makeDirectory(playerDirectory+"support"); +} + + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::main +// Purpose: The REAL main of the program +// Input: argc - count of arguments from commandline +// argv[] - the arguments +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::main(int argc,const char* argv[]) +{ + if (argc<=1){printUsage();return;} + g_pApp=this; + + //TODO: move this into OS interface + TFStats_setNewHandler(); + + inputDirectory="."; + makeAndSaveDirectory(inputDirectory); + + //this call also sets up various directories to be used + ParseCommandLine(argc,argv); + + Util::initFriendlyWeaponNameTable(); + + //LogFile is read in here. + //MUST do this before we chdir to the output directory + os->chdir(inputDirectory.c_str()); + CEventList* plogfile=NULL; + plogfile=CEventList::readEventList(argv[1]); + if (!plogfile) + fatalError("No valid data found in logfile %s\n",argv[1]); + + + os->chdir(outputDirectory.c_str()); + //make match information object + g_pMatchInfo= new CMatchInfo(plogfile); + + CTFStatsReport matchreport; + + + + matchreport.genImages(); + + + matchreport.genJavaScript(); + matchreport.genStyleSheet(); + + if (cmdLineSwitches["persistplayerstats"]=="yes") + matchreport.genAllPlayersStyleSheet(); + + matchreport.genIndex(); + + os->chdir(outputDirectory.c_str()); + matchreport.genTopFrame(); + matchreport.genNavFrame(); + + + DoMatchResults(); + + + CCVarList ccvl; + ccvl.makeHTMLPage("cvars.html","Server Settings"); + + CDialogueReadout cdr; + cdr.makeHTMLPage("dialogue.html","Dialogue"); + + CPlayerSpecifics cps; + cps.makeHTMLPage("players.html","Players"); + + + if (cmdLineSwitches["persistplayerstats"]=="yes") + { + if(!g_pMatchInfo->isLanGame()) + { + g_pApp->os->chdir(g_pApp->playerDirectory.c_str()); + CAllPlayersStats caps; + caps.makeHTMLPage("allplayers.html","All Players"); + } + else + { + g_pApp->warning("Lan Game detected, player stats will not be saved"); + } + } + printf("TFStats completed successfully\n\n\n"); +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::makeAndSaveDirectory +// Purpose: Creates a directory and writes the full directory path back into the +// passed in string. In effect, this turns a potentially relative path into an +// absolute path, and ensures the directory exists. +// Input: dir - the string that contains the pathname, and upon return will contain +// the absolute pathname +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::makeAndSaveDirectory(string& dir) +{ + char startpath[500]; + char fullpath[500]; + os->getcwd(startpath,500); + if (!os->makeHier(dir)) + { + fatalError("Failed to make directory \"%s\", aborting. (Reason: %s)",dir.c_str(),strerror(errno)); + } + os->chdir(dir.c_str()); + os->getcwd(fullpath,500); + dir=fullpath; + os->addDirSlash(dir); + os->chdir(startpath); +} + + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::makeDirectory +// Purpose: Creates a directory. +// Input: dir - the directory to create +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::makeDirectory(string& dir) +{ + char startpath[500]; + os->getcwd(startpath,500); + + if (!os->makeHier(dir)) + { + fatalError("Failed to make directory \"%s\". (Reason: %s)",dir.c_str(),strerror(errno)); + } + os->chdir(startpath); +} + + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::fatalError +// Purpose: prints an error message and exits +// Input: fmt - the format string +// ... - optional arguments +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::fatalError(char* fmt,...) +{ + va_list v; + va_start(v,fmt); + fprintf(stderr,"Fatal Error: "); + vfprintf(stderr,fmt,v); + fprintf(stderr,"\n***Aborting. \n"); + exit(-1); +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::warning +// Purpose: prints a warning message and returns. (program doesn't exit) +// Input: fmt - format string +// ... - optional arguments +//------------------------------------------------------------------------------------------------------ +void CTFStatsApplication::warning(char* fmt,...) +{ + va_list v; + va_start(v,fmt); + fprintf(stderr,"Warning: "); + vfprintf(stderr,fmt,v); + fprintf(stderr,"\n"); +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTFStatsApplication::getCutoffSeconds +// Purpose: Turns the number of cutoff days into seconds. Cutoff days are how +// many days players can be absent from the server and still have their stats +// reported in the all-player stats +// Output: time_t the number of cutoff seconds +//------------------------------------------------------------------------------------------------------ +time_t CTFStatsApplication::getCutoffSeconds() +{ + return 60*60*24*elimDays; +}
\ No newline at end of file |