1
This commit is contained in:
391
utils/tfstats/logevent.cpp
Normal file
391
utils/tfstats/logevent.cpp
Normal file
@ -0,0 +1,391 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CLogEvent
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "LogEvent.h"
|
||||
#include "util.h"
|
||||
#include "memdbg.h"
|
||||
|
||||
|
||||
|
||||
//For debugging more than anything
|
||||
const char* CLogEvent::TypeNames[]=
|
||||
{
|
||||
{"No Type/Invalid!"},
|
||||
{"Log File Initialize"},
|
||||
{"Server Spawn"},
|
||||
{"Server Shutdown"},
|
||||
{"Log Closed"},
|
||||
{"Server Misc"},
|
||||
{"Server Name"},
|
||||
{"Team Rename"},
|
||||
{"Level Change"},
|
||||
{"Cvar Assignment"},
|
||||
{"Map CRC"},
|
||||
{"Team Join"},
|
||||
{"Connect"},
|
||||
{"Enter game"},
|
||||
{"Disconnect"},
|
||||
{"Name Change"},
|
||||
{"Frag!"},
|
||||
{"Team frag!"},
|
||||
{"Suicide!"},
|
||||
{"Killed by world!"},
|
||||
{"Build"},
|
||||
{"Match Results Marker"},
|
||||
{"Match Draw"},
|
||||
{"Match Victor"},
|
||||
{"Match Team Results"},
|
||||
{"Talk"},
|
||||
{"Team Talk"},
|
||||
{"Cure"},
|
||||
{"Named Goal Activated"},
|
||||
{"Anon Goal Activated"},
|
||||
{"Named Broadcast"},
|
||||
{"Anon Broadcast"},
|
||||
{"Change Class"},
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::getArgument
|
||||
// Purpose: returns the iWhichArg'th argument
|
||||
// Input: iWhichArg - the desired argument
|
||||
// Output: const CLogEventArgument*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
const CLogEventArgument* CLogEvent::getArgument(int iWhichArg) const
|
||||
{
|
||||
if (iWhichArg < m_args.size())
|
||||
return m_args[iWhichArg];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::parseArgs
|
||||
// Purpose: extracts the arguments out of the event text.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::parseArgs()
|
||||
{
|
||||
|
||||
char temp[512];
|
||||
char* write=temp;
|
||||
const char* read=m_EventMessage;
|
||||
|
||||
int i=0;
|
||||
while (*read)
|
||||
{
|
||||
|
||||
if (*read == '\"')
|
||||
{
|
||||
//parseArgument moves the read pointer to the char after the closing "
|
||||
parseArgument(++read);
|
||||
*(write++)='[';
|
||||
*(write++)=(char)(i++)+48; //convert int to char by adding 48
|
||||
*(write++)=']';
|
||||
}
|
||||
else
|
||||
*write++=*read;
|
||||
|
||||
*read++;
|
||||
}
|
||||
*write=0;
|
||||
|
||||
Util::str2lowercase(temp,temp);
|
||||
|
||||
m_StrippedText=new TRACKED char[strlen(temp)+1];
|
||||
strcpy(m_StrippedText,temp);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::parseArgument
|
||||
// Purpose: helper function for parseArgs, this actually removes the argument
|
||||
// Input: raw - the string from which we want to remove the argument
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::parseArgument(const char*& raw)
|
||||
{
|
||||
|
||||
char* atemp;
|
||||
if (!(atemp=strchr(raw,'\"')))
|
||||
return;
|
||||
|
||||
*atemp=0; //null out the closing "
|
||||
|
||||
CLogEventArgument* newarg=new CLogEventArgument(raw);
|
||||
newarg->init(raw);
|
||||
m_args.push_back(newarg);
|
||||
|
||||
|
||||
*atemp='\"'; //restore it.
|
||||
raw=atemp; //advance the pointer
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::keywordsOccur
|
||||
// Purpose: tests to see if all of the given keywords occur in the text for this event
|
||||
// Input: s1 - first keyword (required)
|
||||
// s2 - second keyword (optional)
|
||||
// s3 - third keyword (optional)
|
||||
// Output: Returns true if the event text contains all of the keywords passed in
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
bool CLogEvent::keywordsOccur(char* s1,char* s2,char* s3)
|
||||
{
|
||||
bool result=(strstr(m_StrippedText,s1)!=NULL);
|
||||
if (s2)
|
||||
{
|
||||
result = result && (strstr(m_StrippedText,s2)!=NULL);
|
||||
if (s3)
|
||||
{
|
||||
result = result && (strstr(m_StrippedText,s3)!=NULL);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::determineType
|
||||
// Purpose: this is a big dumb if statement to determine the type of this event
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
//this is pretty cheesy
|
||||
void CLogEvent::determineType()
|
||||
{
|
||||
|
||||
//for now just do this in a big dumb if statement
|
||||
|
||||
if (keywordsOccur("killed","self","with"))
|
||||
m_EventType=SUICIDE;
|
||||
else if (keywordsOccur("log closed"))
|
||||
m_EventType=LOG_CLOSED;
|
||||
else if (keywordsOccur("server name is"))
|
||||
m_EventType=SERVER_NAME;
|
||||
else if (keywordsOccur("team name of"))
|
||||
m_EventType=TEAM_RENAME;
|
||||
else if (keywordsOccur("killed","by","world"))
|
||||
m_EventType=KILLED_BY_WORLD;
|
||||
else if (keywordsOccur("killed","(teammate)"))
|
||||
m_EventType=TEAM_FRAG;
|
||||
else if (keywordsOccur("killed","with"))
|
||||
m_EventType=FRAG;
|
||||
else if (keywordsOccur("say_team"))
|
||||
m_EventType=SAY_TEAM;
|
||||
else if (keywordsOccur("say"))
|
||||
m_EventType=SAY;
|
||||
else if (keywordsOccur("joined team"))
|
||||
m_EventType=TEAM_JOIN;
|
||||
else if (keywordsOccur("changed to team"))
|
||||
m_EventType=TEAM_JOIN;
|
||||
else if (keywordsOccur("log file started"))
|
||||
m_EventType=LOG_FILE_INIT;
|
||||
else if (keywordsOccur("spawning server"))
|
||||
m_EventType=SERVER_SPAWN;
|
||||
else if (keywordsOccur("connected","address"))
|
||||
m_EventType=CONNECT;
|
||||
else if (keywordsOccur("has entered the game"))
|
||||
m_EventType=ENTER_GAME;
|
||||
else if (keywordsOccur("disconnected"))
|
||||
m_EventType=DISCONNECT;
|
||||
else if (keywordsOccur("changed name to"))
|
||||
m_EventType=NAME_CHANGE;
|
||||
else if (keywordsOccur("built"))
|
||||
m_EventType=BUILD;
|
||||
else if (keywordsOccur("map crc"))
|
||||
m_EventType=MAP_CRC;
|
||||
else if (keywordsOccur("match","results","=------="))
|
||||
m_EventType=MATCH_RESULTS_MARKER;
|
||||
else if (keywordsOccur("activated the goal"))
|
||||
m_EventType=NAMED_GOAL_ACTIVATE;
|
||||
else if (keywordsOccur("goal", "was activated"))
|
||||
m_EventType=ANON_GOAL_ACTIVATE;
|
||||
else if (keywordsOccur("named broadcast"))
|
||||
m_EventType=NAMED_BROADCAST;
|
||||
else if (keywordsOccur("broadcast"))
|
||||
m_EventType=ANON_BROADCAST;
|
||||
else if (keywordsOccur("changed class"))
|
||||
m_EventType=CLASS_CHANGE;
|
||||
else if (keywordsOccur("-> draw <-"))
|
||||
m_EventType=MATCH_DRAW;
|
||||
else if (keywordsOccur("defeated"))
|
||||
m_EventType=MATCH_VICTOR;
|
||||
else if (keywordsOccur("results"))
|
||||
m_EventType=MATCH_TEAM_RESULTS;
|
||||
else if (keywordsOccur("="))
|
||||
m_EventType=CVAR_ASSIGN;
|
||||
else m_EventType=SERVER_MISC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::CLogEvent
|
||||
// Purpose: CLogEvent constructor
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CLogEvent::CLogEvent()
|
||||
:m_EventCode('\0'),m_EventTime(0),m_Valid(false),m_Next(NULL),m_StrippedText(NULL),m_EventType(INVALID),m_EventMessage(NULL)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::~CLogEvent
|
||||
// Purpose: CLogEvent destructor
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CLogEvent::~CLogEvent()
|
||||
{
|
||||
//this errors?!
|
||||
if (m_EventMessage)
|
||||
delete[] m_EventMessage;
|
||||
if (m_StrippedText)
|
||||
delete[] m_StrippedText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::print
|
||||
// Purpose: debugging function, prints this event to a file
|
||||
// Input: f - the file to print to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::print(FILE* f)
|
||||
{
|
||||
fprintf(f,"(%li) Event: %s\n",m_EventTime,m_EventMessage);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::CLogEvent
|
||||
// Purpose: CLogEvent constructor that reads an event from the specified file
|
||||
// Input: f - the file to read from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CLogEvent::CLogEvent(FILE* f)
|
||||
:m_EventCode('\0'),m_EventTime(0),m_Valid(false),m_Next(NULL),m_StrippedText(NULL),m_EventType(INVALID),m_EventMessage(NULL)
|
||||
{
|
||||
readEvent(f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::readEvent
|
||||
// Purpose: reads an event by reading each part, then checking if it was successful
|
||||
// Input: f - the file to read from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::readEvent(FILE* f)
|
||||
{
|
||||
m_Valid=true;
|
||||
if (m_Valid) readEventCode(f);
|
||||
if (m_Valid) readEventTime(f);
|
||||
if (m_Valid) readEventMessage(f);
|
||||
if (m_Valid) parseArgs();
|
||||
if (m_Valid) determineType();
|
||||
if (m_Valid) m_Valid=!feof(f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::readEventCode
|
||||
// Purpose: reads the event code, the first character on the line (should be 'L')
|
||||
// Input: f - the file to read from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::readEventCode(FILE* f)
|
||||
{
|
||||
fscanf(f," %c ",&m_EventCode);
|
||||
if (m_EventCode!='L')
|
||||
m_Valid=false;
|
||||
|
||||
if (feof(f))
|
||||
m_Valid=false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::readEventMessage
|
||||
// Purpose: reads the text of the event message.
|
||||
// Input: f - the file to read from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::readEventMessage(FILE* f)
|
||||
{
|
||||
char temp[512];
|
||||
fgets(temp,512,f);
|
||||
|
||||
//special case hack for broadcasts
|
||||
if (strncmp(temp,"Named Broadcast:",16)==0 || strncmp(temp,"Broadcast:",16)==0)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
fpos_t temp_pos;
|
||||
fgetpos(f,&temp_pos);
|
||||
CLogEvent cle(f);
|
||||
fseek(f,temp_pos,SEEK_SET);
|
||||
if (cle.isValid())
|
||||
{
|
||||
//if the next log event is valid, then this broadcast did not span lines
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp[strlen(temp)-1]=' '; //rid ourselves of newline
|
||||
temp[strlen(temp)]=0; //rid ourselves of newline
|
||||
char buf[512];
|
||||
fgets(buf,512,f);
|
||||
strcat(temp,buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (feof(f))
|
||||
{
|
||||
m_Valid=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp[strlen(temp)-1]=0; //rid ourselves of newline
|
||||
m_EventMessage=new TRACKED char[strlen(temp)+1];
|
||||
strcpy(m_EventMessage,temp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEvent::readEventTime
|
||||
// Purpose: reads and converts the time the event happened into a time_t
|
||||
// Input: f - the file to read from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEvent::readEventTime(FILE* f)
|
||||
{
|
||||
|
||||
int month=-1,day=-1,year=-1;
|
||||
int hour=-1,minute=-1,second=-1;
|
||||
fscanf(f," %d/%d/%d - %d:%d:%d: ",&month,&day,&year,&hour,&minute,&second);
|
||||
if (month==-1 ||day==-1 ||year==-1 || hour==-1 || minute==-1 || second==-1)
|
||||
m_Valid=false;
|
||||
else if (feof(f))
|
||||
m_Valid=false;
|
||||
else
|
||||
{
|
||||
tm t;
|
||||
t.tm_isdst=0;
|
||||
t.tm_hour=hour;
|
||||
t.tm_mday=day;
|
||||
t.tm_min=minute;
|
||||
t.tm_sec=second;
|
||||
t.tm_year=year-1900; //note no y2k prob here, so says the CRT manual
|
||||
//this allows values greater than 99, but it
|
||||
//just wants the input with 1900 subtracted.
|
||||
t.tm_mon=month-1; //jan = 0
|
||||
m_EventTime=mktime(&t);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user