1
@@ -0,0 +1,119 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CAllPlayersStats
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "AllPlayersStats.h"
|
||||
#include "PlayerReport.h"
|
||||
#include "TextFile.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAllPlayersStats::init
|
||||
// Purpose: intializes the object
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CAllPlayersStats::init()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAllPlayersStats::generate
|
||||
// Purpose: generates intermediate data from match info
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CAllPlayersStats::generate()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAllPlayersStats::writeHTML
|
||||
// Purpose: writes out html based on the intermediate data generated by generate()
|
||||
// Input: html - the html file to output to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CAllPlayersStats::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
string filename;
|
||||
bool result=g_pApp->os->findfirstfile("*.tfs",filename);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
multimap<double,CPlrPersist,greater<double> > ranksort;
|
||||
|
||||
html.write("<table cols=1 cellspacing=0 border=0 cellpadding=10 bordercolor=black>\n");
|
||||
while(1)
|
||||
{
|
||||
CTextFile f(filename);
|
||||
pair<double,CPlrPersist> insertme;
|
||||
insertme.second.read(f);
|
||||
insertme.first=insertme.second.rank();
|
||||
|
||||
ranksort.insert(insertme);
|
||||
|
||||
if (!g_pApp->os->findnextfile(filename))
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
g_pApp->os->findfileclose();
|
||||
|
||||
multimap<double,CPlrPersist,greater<double> >::iterator rankit=ranksort.begin();
|
||||
|
||||
for (rankit;rankit!=ranksort.end();++rankit)
|
||||
{
|
||||
bool rowstarted=false;
|
||||
//double rank=rankit->first;
|
||||
CPlrPersist* pcpp=&(rankit->second);
|
||||
|
||||
time_t cutoff=g_pMatchInfo->logOpenTime() - g_pApp->getCutoffSeconds();
|
||||
|
||||
if (pcpp->lastplayed >= cutoff || !g_pApp->eliminateOldPlayers)
|
||||
{
|
||||
if (!rowstarted)
|
||||
{
|
||||
rowstarted=true;
|
||||
html.write("<tr>\n");
|
||||
}
|
||||
|
||||
html.write("<td width=300 valign=top>");
|
||||
CPlayerReport pr(pcpp);
|
||||
pr.writeHTML(html);
|
||||
html.write("</td>\n");
|
||||
}
|
||||
if (++rankit==ranksort.end())
|
||||
{
|
||||
if (rowstarted)
|
||||
html.write("</tr>\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//double rank=rankit->first;
|
||||
CPlrPersist* pcpp2=&(rankit->second);
|
||||
if (pcpp->lastplayed >= cutoff || !g_pApp->eliminateOldPlayers)
|
||||
{
|
||||
if (!rowstarted)
|
||||
{
|
||||
rowstarted=true;
|
||||
html.write("<tr>\n");
|
||||
}
|
||||
|
||||
html.write("<td width=300 valign=top>");
|
||||
CPlayerReport pr2(pcpp2);
|
||||
pr2.writeHTML(html);
|
||||
html.write("</td>\n");
|
||||
}
|
||||
if (rowstarted)
|
||||
html.write("</tr>\n");
|
||||
}
|
||||
|
||||
html.write("</table>");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface to CAllPlayersStats
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef ALLPLAYERSSTATS_H
|
||||
#define ALLPLAYERSSTATS_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning (disable: 4786)
|
||||
|
||||
#include "report.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CAllPlayersStats is a whole page report element that reports specific
|
||||
// data about each player that has played on the server. Data such as favourite
|
||||
// weapon, rank, classes played, favourite class, and kills vs deaths.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CAllPlayersStats :public CReport
|
||||
{
|
||||
private:
|
||||
|
||||
void init();
|
||||
|
||||
|
||||
public:
|
||||
explicit CAllPlayersStats(){init();}
|
||||
|
||||
void generate();
|
||||
void writeHTML(CHTMLFile& html);
|
||||
};
|
||||
|
||||
#endif // ALLPLAYERSSTATS_H
|
||||
@@ -0,0 +1,217 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CLogEventArgument
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#pragma warning (disable:4786)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "argument.h"
|
||||
#include "memdbg.h"
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::CLogEventArgument
|
||||
// Purpose: Constructor that builds the object out of the passed in string of text
|
||||
// Input: text - text representing the argument
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CLogEventArgument::CLogEventArgument(const char* text)
|
||||
{
|
||||
init(text);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::CLogEventArgument
|
||||
// Purpose: Default constructor
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CLogEventArgument::CLogEventArgument()
|
||||
:m_ArgText(NULL),m_Valid(false)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::init
|
||||
// Purpose: initializes the argument
|
||||
// Input: text - the text representing the argument
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CLogEventArgument::init(const char* text)
|
||||
{
|
||||
|
||||
int len=strlen(text);
|
||||
m_ArgText=new TRACKED char[len+1];
|
||||
strcpy(m_ArgText,text);
|
||||
m_Valid=true;
|
||||
}
|
||||
|
||||
char* findStartOfSvrID(char* cs)
|
||||
{
|
||||
char* read=&cs[strlen(cs)-1];
|
||||
while (read != cs)
|
||||
{
|
||||
if (*read=='<' && *(read+1) != 'W') // if we've found a svrID
|
||||
break;
|
||||
read--;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::asPlayerGetID
|
||||
// Purpose: treats the argument as a player name, and returns the player ID.
|
||||
// Note: PlayerName args have this form: "name<pid><WON:wonid>"
|
||||
// Output: the ID of the player represented by this argument
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
int CLogEventArgument::asPlayerGetSvrPID() const
|
||||
{
|
||||
char* read=findStartOfSvrID(m_ArgText);
|
||||
if (read==m_ArgText)
|
||||
return -1;
|
||||
|
||||
int retval=-1;
|
||||
sscanf(read,"<%i>",&retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
PID CLogEventArgument::asPlayerGetPID() const
|
||||
{
|
||||
char* openPID=NULL;
|
||||
int svrPID=INVALID_PID;
|
||||
if (openPID=strchr(m_ArgText,'<'))
|
||||
{
|
||||
openPID++;
|
||||
sscanf(openPID,"%i",&svrPID);
|
||||
}
|
||||
unsigned long wonID;
|
||||
if (openPID=strstr(m_ArgText,"<WON:"))
|
||||
{
|
||||
openPID+=5;
|
||||
sscanf(openPID,"%li",&wonID);
|
||||
}
|
||||
|
||||
|
||||
return PID(svrPID,wonID);
|
||||
|
||||
}
|
||||
*/
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::asPlayerGetName
|
||||
// Purpose: treats the argument as a player name, and copies/returns the player name.
|
||||
// Note: PlayerName args have this form: "name<pid><WONID:wonid>"
|
||||
// Input: copybuf - the buffer to copy the name into
|
||||
// Output: char* the pointer to the buffer that the name was copied into
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
char* CLogEventArgument::asPlayerGetName(char* copybuf) const
|
||||
{
|
||||
char* eon=findStartOfSvrID(m_ArgText);
|
||||
bool noPID=(eon==m_ArgText);
|
||||
char old=*eon;
|
||||
if (!noPID)
|
||||
*eon=0;
|
||||
|
||||
strcpy(copybuf,m_ArgText);
|
||||
if (!noPID)
|
||||
*eon=old;
|
||||
return copybuf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::asPlayerGetName
|
||||
// Purpose: an alternate form of the above function that returns the playername
|
||||
// as a C++ string, rather than buffercopying it around
|
||||
// Output: string: the player's name
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
string CLogEventArgument::asPlayerGetName() const
|
||||
{
|
||||
char* eon=findStartOfSvrID(m_ArgText);
|
||||
bool noPID=(eon==m_ArgText);
|
||||
|
||||
char old=*eon;
|
||||
if (!noPID)
|
||||
*eon=0;
|
||||
|
||||
|
||||
string s(m_ArgText);
|
||||
if (!noPID)
|
||||
*eon=old;
|
||||
return s;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::asPlayerGetWONID
|
||||
// Purpose: treats the argument as a player name, and returns the player's wonid
|
||||
// Note: PlayerName args have this form: "name<pid><WON:wonid>"
|
||||
// Output: int: the WONID of the player
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
unsigned long CLogEventArgument::asPlayerGetWONID() const
|
||||
{
|
||||
char* openPID=NULL;
|
||||
unsigned long retval=INVALID_WONID;
|
||||
if (openPID=strstr(m_ArgText,"<WON:"))
|
||||
{
|
||||
openPID+=5; //move past the <WON: string
|
||||
sscanf(openPID,"%lu",&retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
unsigned long CLogEventArgument::asPlayerGetPID() const
|
||||
{
|
||||
int svrPID=asPlayerGetSvrPID();
|
||||
|
||||
if (pidMap[svrPID]==0 || pidMap[svrPID]==-1)
|
||||
pidMap[svrPID]=svrPID;
|
||||
return pidMap[svrPID];
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::getFloatValue
|
||||
// Purpose: treats the argument as a floating point value, and returns it
|
||||
// Output: double
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
double CLogEventArgument::getFloatValue() const
|
||||
{
|
||||
return atof(m_ArgText);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::getStringValue
|
||||
// Purpose: treats the argument as a string and returns a pointer to the argument
|
||||
// text itself. note the pointer is const, so the argument can't be modified by
|
||||
// the caller (unless they perform some nefarious casting on the returned pointer)
|
||||
// Output: const char*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
const char* CLogEventArgument::getStringValue() const
|
||||
{
|
||||
return m_ArgText;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CLogEventArgument::getStringValue
|
||||
// Purpose: an alternate form of the above that copies the string into a caller
|
||||
// supplied buffer then returns a pointer to that buffer
|
||||
// Input: copybuf - the buffer into which the string is to be copied
|
||||
// Output: char* the pointer to the buffer that the caller passed in
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
char* CLogEventArgument::getStringValue(char* copybuf) const
|
||||
{
|
||||
strcpy(copybuf,m_ArgText);
|
||||
return copybuf;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CLogEventArgument
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef ARGUMENT_H
|
||||
#define ARGUMENT_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "pid.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CLogEventArgument represents a variable in the text of an event.
|
||||
// for example, "X" killed "Y" with "Z". X Y and Z are all represented by seperate
|
||||
// instances of this class.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CLogEventArgument
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
INVALID_PID=-1,
|
||||
INVALID_WONID=0,
|
||||
VALUE_WID=64,
|
||||
PLAYER_NAME_WID=VALUE_WID,
|
||||
WONID_WID=(10+6), //<WON:xxxxxxxxxx>
|
||||
PLAYERID_WID=4 // <xx> //only up to 99 players :(
|
||||
};
|
||||
|
||||
private:
|
||||
char* m_ArgText;
|
||||
bool m_Valid;
|
||||
public:
|
||||
explicit CLogEventArgument(const char* text);
|
||||
CLogEventArgument();
|
||||
void init(const char* text);
|
||||
|
||||
//int asPlayerGetID() const;
|
||||
int asPlayerGetSvrPID() const;
|
||||
unsigned long asPlayerGetWONID() const;
|
||||
PID asPlayerGetPID() const;
|
||||
char* asPlayerGetName(char* copybuf) const;
|
||||
std::string asPlayerGetName() const;
|
||||
double getFloatValue() const;
|
||||
const char* getStringValue() const;
|
||||
char* getStringValue(char* copybuf) const;
|
||||
bool isValid() const {return m_Valid;}
|
||||
};
|
||||
|
||||
typedef std::vector<CLogEventArgument*> ArgVector;
|
||||
|
||||
#endif // ARGUMENT_H
|
||||
@@ -0,0 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "Award.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAward::CAward
|
||||
// Purpose: Constructor.
|
||||
// Input: name - the name of the award
|
||||
// pmi - a pointer to the match information
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CAward::CAward(char* name)
|
||||
:awardName(name),fNoWinner(true),winnerID(-1)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAward::generate
|
||||
// Purpose: overrides generate to call the more-semantically correct getWinner()
|
||||
// when dealing with subclasses of awards. Also after getWinner has determined
|
||||
// which PID is the winner, this assigns the correct name to the winnerName field
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CAward::generate()
|
||||
{
|
||||
winnerName="";
|
||||
getWinner();
|
||||
if (winnerID!=-1)
|
||||
winnerName=g_pMatchInfo->playerName(winnerID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CAward::writeHTML
|
||||
// Purpose: writes the award to the given html page
|
||||
// Input: html - the page to output the award to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CAward::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
if (fNoWinner || (winnerID == -1 && winnerName==""))
|
||||
noWinner(html);
|
||||
else
|
||||
{
|
||||
html.write("The <font class=brightawards>%s</font> award goes to %s! ",awardName.c_str(),winnerName.c_str());
|
||||
extendedinfo(html);
|
||||
}
|
||||
html.br();
|
||||
html.write("\n");
|
||||
}
|
||||
CAward::~CAward()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CAward, the base class for all awards
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef AWARD_H
|
||||
#define AWARD_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning(disable :4786)
|
||||
#include "Report.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CAward is the base class for all awards, it is in turn a subclass of
|
||||
// CReport. This class handles all the boring details of writing out the awards
|
||||
// and things, so that the subclasses need only specify the name of the award
|
||||
// and who won it, then this class will take care of the rest
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CAward: public CReport
|
||||
{
|
||||
//from CReport:
|
||||
protected:
|
||||
virtual void generate();
|
||||
protected:
|
||||
std::string awardName;
|
||||
std::string winnerName;
|
||||
PID winnerID;
|
||||
bool fNoWinner;
|
||||
|
||||
CAward(char* name);
|
||||
|
||||
|
||||
virtual void extendedinfo(CHTMLFile& html){};
|
||||
virtual void noWinner(CHTMLFile& html){};
|
||||
|
||||
|
||||
public:
|
||||
virtual void getWinner(){}
|
||||
virtual void writeHTML(CHTMLFile& html);
|
||||
|
||||
virtual ~CAward();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // AWARD_H
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Includes all of the awards' header files, to save on typing. :)
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef AWARDS_H
|
||||
#define AWARDS_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "SentryRebuildAward.h"
|
||||
#include "CureAward.h"
|
||||
#include "KamikazeAward.h"
|
||||
#include "TalkativeAward.h"
|
||||
#include "WeaponAwards.h"
|
||||
#include "SharpshooterAward.h"
|
||||
#include "TeamkillAward.h"
|
||||
#include "SurvivalistAward.h"
|
||||
|
||||
#endif // AWARDS_H
|
||||
@@ -0,0 +1,48 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef BINARYRESOURCE_H
|
||||
#define BINARYRESOURCE_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include "util.h"
|
||||
|
||||
class CBinaryResource
|
||||
{
|
||||
private:
|
||||
std::string filename;
|
||||
size_t numBytes;
|
||||
unsigned char* pData;
|
||||
public:
|
||||
CBinaryResource(char* name, size_t bytes,unsigned char* data)
|
||||
:filename(name),numBytes(bytes),pData(data)
|
||||
{}
|
||||
|
||||
bool writeOut()
|
||||
{
|
||||
FILE* f=fopen(filename.c_str(),"wb");
|
||||
if (!f)
|
||||
return false;
|
||||
fwrite(pData,1,numBytes,f);
|
||||
fclose(f);
|
||||
#ifndef WIN32
|
||||
chmod(filename.c_str(),PERMIT);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BINARYRESOURCE_H
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CCureAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "CureAward.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCureAward::getWinner
|
||||
// Purpose: determines who cured the most people during the match
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCureAward::getWinner()
|
||||
{
|
||||
CEventListIterator it;
|
||||
for (it=g_pMatchInfo->eventList()->begin(); it != g_pMatchInfo->eventList()->end(); ++it)
|
||||
{
|
||||
if ((*it)->getType()==CLogEvent::CURE)
|
||||
{
|
||||
PID doc=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
numcures[doc]++;
|
||||
winnerID=doc;
|
||||
fNoWinner=false;
|
||||
}
|
||||
}
|
||||
|
||||
map<PID,int>::iterator cureiter;
|
||||
|
||||
|
||||
for (cureiter=numcures.begin();cureiter!=numcures.end();++cureiter)
|
||||
{
|
||||
PID currID=(*cureiter).first;
|
||||
if (numcures[currID]>numcures[winnerID])
|
||||
winnerID=currID;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCureAward::noWinner
|
||||
// Purpose: writes html indicating that no one was cured during this match
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCureAward::noWinner(CHTMLFile& html)
|
||||
{
|
||||
html.write("No one was cured during this match.");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCureAward::extendedinfo
|
||||
// Purpose: reports how many people the winner cured
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCureAward::extendedinfo(CHTMLFile& html)
|
||||
{
|
||||
if (numcures[winnerID]==1)
|
||||
html.write("%s cured 1 sick person!",winnerName.c_str());
|
||||
else
|
||||
html.write("%s healed cured %li sick people!",winnerName.c_str(),numcures[winnerID]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "Award.h"
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
class CCureAward: public CAward
|
||||
{
|
||||
protected:
|
||||
map <PID,int> numcures;
|
||||
void noWinner(CHTMLFile& html);
|
||||
void extendedinfo(CHTMLFile& html);
|
||||
public:
|
||||
explicit CCureAward():CAward("Life-Saver"){}
|
||||
void getWinner();
|
||||
};
|
||||
@@ -0,0 +1,269 @@
|
||||
//========= 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 CCustomAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include <string.h>
|
||||
#include "TFStatsApplication.h"
|
||||
#include "CustomAward.h"
|
||||
#include "TextFile.h"
|
||||
#include "memdbg.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAward::extendedinfo
|
||||
// Purpose: writes extra info about the award winner, like their score or something.
|
||||
// The extra info string is defined by the user in the configuration file like the
|
||||
//rest of a custom award's properties.
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCustomAward::extendedinfo(CHTMLFile& html)
|
||||
{
|
||||
if (extraInfoMsg.empty())
|
||||
return;
|
||||
|
||||
char str[500];
|
||||
char outputstring[2000]={0};
|
||||
|
||||
strcpy(str,extraInfoMsg.c_str());
|
||||
|
||||
char delims[]={" \n\t"};
|
||||
char* temp=NULL;
|
||||
|
||||
temp=strtok(str,delims);
|
||||
while(temp!=NULL)
|
||||
{
|
||||
char word[500];
|
||||
|
||||
if (strnicmp(temp,"%player",strlen("%player"))==0)
|
||||
{
|
||||
char* more=&temp[strlen("%player")];
|
||||
sprintf(word,"%s%s",winnerName.c_str(),more);
|
||||
}
|
||||
else if (strnicmp(temp,"%winner",strlen("%winner"))==0)
|
||||
{
|
||||
char* more=&temp[strlen("%winner")];
|
||||
sprintf(word,"%s%s",winnerName.c_str(),more);
|
||||
}
|
||||
else if (strnicmp(temp,"%score",strlen("%score"))==0)
|
||||
{
|
||||
char* more=&temp[strlen("%score")];
|
||||
if (!namemode)
|
||||
sprintf(word,"%li%s",plrscores[winnerID],more);
|
||||
else
|
||||
sprintf(word,"%li%s",stringscores[winnerName],more);
|
||||
}
|
||||
else if (strnicmp(temp,"%number",strlen("%number"))==0)
|
||||
{
|
||||
//right now this is just the score
|
||||
char* more=&temp[strlen("%number")];
|
||||
if (!namemode)
|
||||
sprintf(word,"%li%s",plrnums[winnerID],more);
|
||||
else
|
||||
sprintf(word,"%li%s",stringscores[winnerName],more);
|
||||
}
|
||||
else
|
||||
strcpy(word,temp);
|
||||
|
||||
strcat(outputstring," ");
|
||||
strcat(outputstring,word);
|
||||
|
||||
temp=strtok(NULL,delims);
|
||||
}
|
||||
|
||||
html.write(outputstring);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAward::noWinner
|
||||
// Purpose: writes some html saying that no one won this award. The noWinnerMsg
|
||||
// is defined by the user in the configuration file like all other custom
|
||||
// award properties
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCustomAward::noWinner(CHTMLFile& html)
|
||||
{
|
||||
if (noWinnerMsg.empty())
|
||||
return;
|
||||
|
||||
html.write(noWinnerMsg.c_str());}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAward::readCustomAward
|
||||
// Purpose: Factory method to read an award from a config file and return an
|
||||
// instance of the CCustomAward class
|
||||
// Input: f - the configuration file to read from
|
||||
// g_pMatchInfo - a pointer to a matchinfo object to give to the new award
|
||||
// Output: CCustomAward*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CCustomAward* CCustomAward::readCustomAward(CTextFile& f)
|
||||
{
|
||||
|
||||
const char* token=f.getToken();
|
||||
while (token)
|
||||
{
|
||||
|
||||
if (!stricmp(token,"Award"))
|
||||
break;
|
||||
else if (!stricmp(token,"{"))
|
||||
f.discardBlock();
|
||||
|
||||
token=f.getToken();
|
||||
}
|
||||
if (!token)
|
||||
return NULL;
|
||||
|
||||
f.discard("{");
|
||||
token=f.getToken();
|
||||
|
||||
CCustomAward* pCustAward=new TRACKED CCustomAward(g_pMatchInfo);
|
||||
while (token)
|
||||
{
|
||||
if (stricmp(token,"trigger")==0)
|
||||
{
|
||||
|
||||
CCustomAwardTrigger* ptrig=CCustomAwardTrigger::readTrigger(f);
|
||||
pCustAward->triggers.push_back(ptrig);
|
||||
|
||||
}
|
||||
else if (stricmp(token,"extraInfo")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
pCustAward->extraInfoMsg=f.readString();
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"noWinnerMessage")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
pCustAward->noWinnerMsg=f.readString();
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"name")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
pCustAward->awardName=f.readString();
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"}")==0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
g_pApp->fatalError("Unrecognized Award property name while parsing %s: \"%s\" is not a property of an Award!",f.fileName().c_str(),token);
|
||||
|
||||
token = f.getToken();
|
||||
}
|
||||
|
||||
|
||||
return pCustAward;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAward::getWinner
|
||||
// Purpose: generates the winner of this custom award.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCustomAward::getWinner()
|
||||
{
|
||||
fNoWinner=true;
|
||||
|
||||
CEventListIterator it;
|
||||
for (it=g_pMatchInfo->eventList()->begin();it!=g_pMatchInfo->eventList()->end();it++)
|
||||
{
|
||||
list<CCustomAwardTrigger*>::iterator tli;
|
||||
for (tli=triggers.begin();tli!=triggers.end();++tli)
|
||||
{
|
||||
if ((*tli)->matches(*it))
|
||||
{
|
||||
//increase the players count by X score.
|
||||
//scan for best at the end
|
||||
|
||||
//different triggers have the player name/id placed differently. :(
|
||||
//if this returns -1, store based on name. (this way we can give awards to things other than player names
|
||||
//while remaining in this award/trigger hierarchy structure)
|
||||
PID ID =(*tli)->plrIDFromEvent(*it);
|
||||
if (ID==-1)
|
||||
{
|
||||
string ws=(*tli)->getTrackString(*it);
|
||||
stringscores[ws]+=(*tli)->plrValue;
|
||||
stringnums[ws]++;
|
||||
fNoWinner=false;
|
||||
namemode=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
plrscores[ID]+=(*tli)->plrValue;
|
||||
plrnums[ID]++;
|
||||
fNoWinner=false;
|
||||
namemode=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fNoWinner)
|
||||
return;
|
||||
|
||||
|
||||
if (!namemode)
|
||||
{
|
||||
//now scan and find highest score.
|
||||
map<PID,int>::iterator scores_it;
|
||||
scores_it=plrscores.begin();
|
||||
winnerID=(*scores_it).first;
|
||||
int winnerScore=(*scores_it).second;
|
||||
|
||||
for (scores_it=plrscores.begin();scores_it!=plrscores.end();++scores_it)
|
||||
{
|
||||
int ID=(*scores_it).first;
|
||||
int score=(*scores_it).second;
|
||||
if (score > winnerScore)
|
||||
{
|
||||
winnerScore=score;
|
||||
winnerID=ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//now scan and find highest score.
|
||||
map<string,int>::iterator scores_it;
|
||||
scores_it=stringscores.begin();
|
||||
winnerID=-1;
|
||||
winnerName=(*scores_it).first;
|
||||
int winnerScore=(*scores_it).second;
|
||||
|
||||
for (scores_it=stringscores.begin();scores_it!=stringscores.end();++scores_it)
|
||||
{
|
||||
string name=(*scores_it).first;
|
||||
int score=(*scores_it).second;
|
||||
if (score > winnerScore)
|
||||
{
|
||||
winnerScore=score;
|
||||
winnerName=name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface to CCustomAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef CUSTOMAWARD_H
|
||||
#define CUSTOMAWARD_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning(disable :4786)
|
||||
#include "Award.h"
|
||||
#include "TextFile.h"
|
||||
#include "CustomAwardTriggers.h"
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CCustomAward represents an award that is user-definable via
|
||||
// a configuration file. Other than their runtime definitions, Custom awards
|
||||
// act just like other static awards.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CCustomAward: public CAward
|
||||
{
|
||||
public:
|
||||
//factory method.
|
||||
static CCustomAward* readCustomAward(CTextFile& f);
|
||||
protected:
|
||||
list<CCustomAwardTrigger*> triggers;
|
||||
bool namemode;
|
||||
|
||||
map<string,string> extraProps;
|
||||
|
||||
map<PID,int> plrscores; //this is wrt to the current award. score in this sense is not related to game score
|
||||
// but simply a score that is relative to other contenders for the award.
|
||||
map<PID,int> plrnums; //this is the number of times any of the triggers was activated
|
||||
|
||||
map<string,int> stringscores; //this is wrt to the current award. score in this sense is not related to game score
|
||||
// but simply a score that is relative to other contenders for the award.
|
||||
map<string,int> stringnums; //this is the number of times any of the triggers was activated
|
||||
|
||||
string noWinnerMsg;
|
||||
string extraInfoMsg;
|
||||
virtual void extendedinfo(CHTMLFile& html);
|
||||
virtual void noWinner(CHTMLFile& html);
|
||||
|
||||
public:
|
||||
explicit CCustomAward(CMatchInfo* pmi):CAward("custom_temp"){}
|
||||
|
||||
void getWinner();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // CUSTOMAWARD_H
|
||||
@@ -0,0 +1,80 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CCustomAwardList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "CustomAwardList.h"
|
||||
#include "memdbg.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAwardList::readCustomAwards
|
||||
// Purpose: Factory method to read from a file and return a list of custom awards
|
||||
// Input: mapname - the name of the map determines the rule file to read the awards from
|
||||
// pmi - a pointer to the Match Info which will be passed to each custom award
|
||||
// Output: CCustomAwardList*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CCustomAwardList* CCustomAwardList::readCustomAwards(string mapname)
|
||||
{
|
||||
char filename[255];
|
||||
|
||||
g_pApp->os->chdir(g_pApp->ruleDirectory.c_str());
|
||||
sprintf(filename,"tfc.%s.rul",mapname.c_str());
|
||||
|
||||
CTextFile ctf1(filename);
|
||||
CTextFile ctf2("tfc.rul");
|
||||
|
||||
if (!ctf1.isValid() && ctf2.isValid())
|
||||
{
|
||||
if (stricmp(filename,"tfc..rul")==0)
|
||||
g_pApp->warning("Could not find mapname in the log file, map-specific custom rules will not be used");
|
||||
else
|
||||
g_pApp->warning("Could not find %s, map-specific custom rules will not be used",filename);
|
||||
}
|
||||
if (!ctf2.isValid() && ctf1.isValid())
|
||||
{
|
||||
g_pApp->warning("tfc.rul could not be found. Only map-specific rules will be used");
|
||||
}
|
||||
if (!ctf2.isValid() && !ctf1.isValid())
|
||||
{
|
||||
g_pApp->warning("Neither tfc.rul nor %s could be found. No custom rules will be used");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CCustomAwardList* newList=new TRACKED CCustomAwardList;
|
||||
bool foundAward=false;
|
||||
|
||||
CCustomAward* pcca=CCustomAward::readCustomAward(ctf1);
|
||||
while (pcca)
|
||||
{
|
||||
foundAward=true;
|
||||
newList->theList.push_back(pcca);
|
||||
pcca=CCustomAward::readCustomAward(ctf1);
|
||||
}
|
||||
|
||||
pcca=CCustomAward::readCustomAward(ctf2);
|
||||
while (pcca)
|
||||
{
|
||||
foundAward=true;
|
||||
newList->theList.push_back(pcca);
|
||||
pcca=CCustomAward::readCustomAward(ctf2);
|
||||
}
|
||||
|
||||
if (!foundAward)
|
||||
{
|
||||
delete newList;
|
||||
g_pApp->warning("Could not find any custom rules in either tfc.rul or %s. No custom rules will be used.\n",filename);
|
||||
newList=NULL;
|
||||
}
|
||||
|
||||
return newList;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CCustomAwardList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef CUSTOMAWARDLIST_H
|
||||
#define CUSTOMAWARDLIST_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "CustomAward.h"
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
typedef list<CCustomAward*>::iterator CCustomAwardIterator;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: this is just a thin wrapper around a list of CCustomAward*s
|
||||
// also provided is a static factory method to read a list of custom awards
|
||||
// out of a configuration file
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CCustomAwardList
|
||||
{
|
||||
public:
|
||||
list<CCustomAward*> theList;
|
||||
|
||||
//factory method
|
||||
static CCustomAwardList* readCustomAwards(string mapname);
|
||||
|
||||
CCustomAwardIterator begin(){return theList.begin();}
|
||||
CCustomAwardIterator end(){return theList.end();}
|
||||
};
|
||||
#endif // CUSTOMAWARDLIST_H
|
||||
@@ -0,0 +1,399 @@
|
||||
//========= 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 all the custom award trigger classes
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "TFStatsApplication.h"
|
||||
#include "CustomAwardTriggers.h"
|
||||
#include "memdbg.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace std;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCustomAwardTrigger::readTrigger
|
||||
// Purpose: reads a trigger definition from the given rule file and returns a new trigger
|
||||
// Input: f - a pointer to the TextFile object that represents the rule file to read from
|
||||
// Output: CCustomAwardTrigger*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CCustomAwardTrigger* CCustomAwardTrigger::readTrigger(CTextFile& f)
|
||||
{
|
||||
CCustomAwardTrigger* retval=NULL;
|
||||
|
||||
string type="fullsearch";
|
||||
vector<string> keys;
|
||||
int value = 1 ;
|
||||
int teamValue = 1;
|
||||
|
||||
|
||||
f.discard("{");
|
||||
map<string,string> extraProps;
|
||||
const char* token=f.getToken();
|
||||
|
||||
while (token)
|
||||
{
|
||||
if (stricmp(token,"value")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
value=atoi(f.readString());
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"teamvalue")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
teamValue=atoi(f.readString());
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"type")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
type=f.readString();
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"key")==0)
|
||||
{
|
||||
f.discard("=");
|
||||
char lowerbuf[500];
|
||||
Util::str2lowercase(lowerbuf,f.readString());
|
||||
keys.push_back(lowerbuf);
|
||||
f.discard(";");
|
||||
}
|
||||
else if (stricmp(token,"}")==0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.discard("=");
|
||||
char lowerbuf[500];
|
||||
char lowerbuf2[500];
|
||||
//oops, have to do this first. CTextfile uses a static buffer to return strings
|
||||
Util::str2lowercase(lowerbuf2,token);
|
||||
Util::str2lowercase(lowerbuf,f.readString());
|
||||
extraProps[lowerbuf2]=lowerbuf;
|
||||
f.discard(";");
|
||||
}
|
||||
|
||||
token=f.getToken();
|
||||
}
|
||||
|
||||
if (type=="broadcast")
|
||||
retval= new TRACKED CBroadcastTrigger(value,teamValue,keys,extraProps);
|
||||
else if (type=="goal")
|
||||
retval = new TRACKED CGoalTrigger(value,teamValue,keys,extraProps);
|
||||
else if (type=="fullsearch")
|
||||
retval = new TRACKED CFullSearchTrigger(value,teamValue,keys,extraProps);
|
||||
else
|
||||
g_pApp->fatalError("Invalid trigger type while parsing %s:\n\"%s\" is not a valid trigger type, please use \"broadcast\", \"goal\" or \"fullsearch\"",f.fileName().c_str(),type);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CBroadcastTrigger::CBroadcastTrigger
|
||||
// Purpose: Constructor for CBroadcastTrigger
|
||||
// Input: value - the value of the trigger relative to other triggers
|
||||
// teamValue - the teamValue of the trigger (not used)
|
||||
// keys - strings to search for in the text of any broadcast event
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CBroadcastTrigger::CBroadcastTrigger (int value, int teamValue, vector<string>& keys,map<string,string> extras)
|
||||
:CCustomAwardTrigger(value,teamValue,extras)
|
||||
{
|
||||
//this line works in win32, but not in G++... g++ doesn't seem to have vector::assign
|
||||
//broadcastStrings.assign(keys.begin(),keys.end());
|
||||
|
||||
//make a new temp object, and assign it to broadcastStrings
|
||||
broadcastStrings=vector<string>(keys);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CBroadcastTrigger::matches
|
||||
// Purpose: Determines if a given event is a broadcast and matches any of the keys
|
||||
// Input: le - the event we're testing
|
||||
// Output: Returns true if the given event triggers this trigger
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
bool CBroadcastTrigger::matches(const CLogEvent* le)
|
||||
{
|
||||
if (le->getType() == CLogEvent::NAMED_BROADCAST)// || le->getType() == CLogEvent::ANON_BROADCAST)
|
||||
{
|
||||
//broadcastID is arg0
|
||||
string BroadID=le->getArgument(0)->getStringValue();
|
||||
vector<string>::iterator it;
|
||||
|
||||
for (it=broadcastStrings.begin();it!=broadcastStrings.end();++it)
|
||||
{
|
||||
string s=*it;
|
||||
if (BroadID==*it)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CGoalTrigger::CGoalTrigger
|
||||
// Purpose: Constructor for CGoalTrigger
|
||||
// Input: value - the value of the trigger relative to other triggers
|
||||
// teamValue - the teamValue of the trigger (not used)
|
||||
// keys - the names of goals that will cause this trigger to trigger
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CGoalTrigger::CGoalTrigger(int value, int teamValue, vector<string>& keys,map<string,string> extras)
|
||||
:CCustomAwardTrigger(value,teamValue,extras)
|
||||
{
|
||||
//this line works in win32, but not in G++... g++ doesn't seem to have vector::assign
|
||||
//goalNames.assign(keys.begin(),keys.end());
|
||||
|
||||
//make a new temp object, and assign it to broadcastStrings
|
||||
//does this introduce a memory leak?
|
||||
|
||||
goalNames=vector<string>(keys);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CGoalTrigger::matches
|
||||
// Purpose: Determines if a given event is a goal activation and matches any of the keys
|
||||
// Input: le - the event we're testing
|
||||
// Output: Returns true if the given event triggers this trigger
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
bool CGoalTrigger::matches(const CLogEvent* le)
|
||||
{
|
||||
|
||||
if (le->getType() == CLogEvent::NAMED_GOAL_ACTIVATE)
|
||||
{
|
||||
string n=le->getArgument(1)->getStringValue();
|
||||
vector<string>::iterator it;
|
||||
|
||||
for (it=goalNames.begin();it!=goalNames.end();++it)
|
||||
{
|
||||
int diff=strnicmp(n.c_str(),(*it).c_str(),(*it).length());
|
||||
if (diff==0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CFullSearchTrigger::CFullSearchTrigger
|
||||
// Purpose: Constructor for CFullSearchTrigger
|
||||
// Input: value - the value of the trigger relative to other triggers
|
||||
// teamValue - the teamValue of the trigger (not used)
|
||||
// ks - the names of FullSearchs that will cause this trigger to trigger
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CFullSearchTrigger::CFullSearchTrigger(int value, int teamValue, vector<string>& ks,map<string,string> extras)
|
||||
:CCustomAwardTrigger(value,teamValue,extras)
|
||||
{
|
||||
//this line works in win32, but not in G++... g++ doesn't seem to have vector::assign
|
||||
//FullSearchNames.assign(keys.begin(),keys.end());
|
||||
|
||||
//make a new temp object, and assign it to broadcastStrings
|
||||
winnerVar=extraProps["winnervar"];
|
||||
|
||||
keys=vector<string>(ks);
|
||||
}
|
||||
|
||||
bool killws(const char*& cs)
|
||||
{
|
||||
bool retval=false;
|
||||
while(isspace(*cs))
|
||||
{
|
||||
retval=true;
|
||||
cs++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#include <regex>
|
||||
int regExprCompare(string sexpr,string scmp)
|
||||
{
|
||||
regex expression(sexpr);
|
||||
cmatch what;
|
||||
if(query_match(scmp.c_str(), scmp.c_str() + strlen(scmp.c_str()), what, expression))
|
||||
{
|
||||
//matched!
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool CFullSearchTrigger::compare(string str_msg,string str_key,map<string,string>& varmatches)
|
||||
{
|
||||
const char* msg=str_msg.c_str();
|
||||
const char* key=str_key.c_str();
|
||||
|
||||
bool match=true;
|
||||
char varbuf[100];
|
||||
char cmpbuf[100];
|
||||
while (1)
|
||||
{
|
||||
if (!*msg) break;
|
||||
if (!*key) break;
|
||||
//get a variable.
|
||||
if (*key=='%')
|
||||
{
|
||||
int i=0;
|
||||
while(*key && *key!=' ')
|
||||
{
|
||||
varbuf[i++]=*(key++);
|
||||
}
|
||||
varbuf[i]=0;
|
||||
if (winnerVar=="")
|
||||
winnerVar=varbuf;
|
||||
|
||||
killws(msg);
|
||||
if (*msg=='\"')
|
||||
{
|
||||
msg++;
|
||||
int i=0;
|
||||
while (*msg && *msg!='\"')
|
||||
{
|
||||
cmpbuf[i++]=*msg++;
|
||||
}
|
||||
cmpbuf[i]=0;
|
||||
msg++; //skip past last "
|
||||
}
|
||||
else
|
||||
{
|
||||
int i=0;
|
||||
while (*msg!=' ')
|
||||
{
|
||||
cmpbuf[i++]=*msg++;
|
||||
}
|
||||
cmpbuf[i]=0;
|
||||
}
|
||||
|
||||
string matchexpr=extraProps[varbuf];
|
||||
if (matchexpr=="")
|
||||
{
|
||||
//if blank, match any quote delimited string or space delimited word
|
||||
|
||||
varmatches.insert(pair<string,string>(varbuf,cmpbuf));
|
||||
}
|
||||
else if (matchexpr.at(0)!='!' && matchexpr.at(1)!='!')
|
||||
{
|
||||
//do a normal string compare
|
||||
if (stricmp(matchexpr.c_str(),cmpbuf)==0)
|
||||
varmatches.insert(pair<string,string>(varbuf,cmpbuf));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//in tfstats, reg expressions start with !! so skip past that
|
||||
const char* rexpr=matchexpr.c_str()+2;
|
||||
string test=rexpr;
|
||||
if (regExprCompare(rexpr,cmpbuf)==0)
|
||||
varmatches.insert(pair<string,string>(varbuf,cmpbuf));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool movedptr1 = killws(msg);
|
||||
bool movedptr2 = killws(key);
|
||||
|
||||
if (!movedptr1 && !movedptr2)
|
||||
{
|
||||
if (!*msg) break;
|
||||
|
||||
if (*msg!=*key)
|
||||
{
|
||||
match=false;
|
||||
break;
|
||||
}
|
||||
msg++;
|
||||
key++;
|
||||
}
|
||||
if (!*msg) break;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CFullSearchTrigger::matches
|
||||
// Purpose:
|
||||
// Input: le - the event we're testing
|
||||
// Output: Returns true if the given event triggers this trigger
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
bool CFullSearchTrigger::matches(const CLogEvent* le)
|
||||
{
|
||||
//test against full text
|
||||
//clear out the state from the last match attempt
|
||||
map<string,string> varmatches;
|
||||
bool match=compare(le->getFullMessage(),keys[0],varmatches);
|
||||
|
||||
#ifdef _CUSTOMDEBUG
|
||||
#ifdef _DEBUG
|
||||
if (match)
|
||||
{
|
||||
map<string,string>::iterator it=varmatches.begin();
|
||||
for (it;it!=varmatches.end();++it)
|
||||
{
|
||||
debug_printf("matched %s with %s\n",it->first.c_str(),it->second.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return match;
|
||||
}
|
||||
|
||||
#include "pid.h"
|
||||
PID CFullSearchTrigger::plrIDFromEvent(const CLogEvent* ple)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (winnerVar.compare(0,5,"%plr_")==0)
|
||||
#else
|
||||
if (winnerVar.at(0)=='%' &&
|
||||
winnerVar.at(1)=='p' &&
|
||||
winnerVar.at(2)=='l' &&
|
||||
winnerVar.at(3)=='r' &&
|
||||
winnerVar.at(4)=='_')
|
||||
#endif
|
||||
{
|
||||
map<string,string> varmatches;
|
||||
compare(ple->getFullMessage(),keys[0],varmatches);
|
||||
string name=varmatches[winnerVar];
|
||||
int svrID=Util::string2svrID(name);
|
||||
return pidMap[svrID];
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
//this class does
|
||||
string CFullSearchTrigger::getTrackString(const CLogEvent* ple)
|
||||
{
|
||||
map<string,string> varmatches;
|
||||
compare(ple->getFullMessage(),keys[0],varmatches);
|
||||
return varmatches[winnerVar];
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interfaces of the CustomAwardTrigger tree. Both types of
|
||||
// Custom award triggers and their base class
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef CUSTOMAWARDTRIGGERS_H
|
||||
#define CUSTOMAWARDTRIGGERS_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning(disable :4786)
|
||||
#include "TextFile.h"
|
||||
#include "LogEvent.h"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
using std::map;
|
||||
using std::list;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CCustomAwardTrigger is the base class for both types of award
|
||||
// triggers. An award trigger is an object that recognizes a certain type of event
|
||||
// in the log file, and if it matches that event, then it "triggers" and the custom
|
||||
// award which owns it increments the counter for the player who triggered the
|
||||
// trigger.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CCustomAwardTrigger
|
||||
{
|
||||
public:
|
||||
static CCustomAwardTrigger* readTrigger(CTextFile& f);
|
||||
int plrValue;
|
||||
int teamValue;
|
||||
|
||||
map<string,string> extraProps;
|
||||
|
||||
virtual bool matches(const CLogEvent* le)=0;
|
||||
|
||||
virtual PID plrIDFromEvent(const CLogEvent* ple){return -1;}
|
||||
virtual string getTrackString(const CLogEvent* ple){return "";}
|
||||
CCustomAwardTrigger(int value, int tmVal, map<string,string> extras){plrValue=value;teamValue=tmVal;extraProps=extras;}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CBroadcastTrigger scans broadcast events for matching data
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CBroadcastTrigger: public CCustomAwardTrigger
|
||||
{
|
||||
public:
|
||||
CBroadcastTrigger(int value, int teamValue, vector<string>& keys,map<string,string> extras);
|
||||
vector<string> broadcastStrings;
|
||||
virtual bool matches(const CLogEvent* le);
|
||||
virtual PID plrIDFromEvent(const CLogEvent* ple){return ple->getArgument(1)->asPlayerGetPID();}
|
||||
|
||||
//this class doesn't need this function
|
||||
//virtual string getTrackString(const CLogEvent* ple){return "";}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CGoalTrigger scans goal activations for matching data
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CGoalTrigger: public CCustomAwardTrigger
|
||||
{
|
||||
public:
|
||||
CGoalTrigger(int value, int teamValue, vector<string>& keys,map<string,string> extras);
|
||||
vector<string> goalNames;
|
||||
virtual bool matches(const CLogEvent* le);
|
||||
virtual PID plrIDFromEvent(const CLogEvent* ple){return ple->getArgument(0)->asPlayerGetPID();}
|
||||
|
||||
//this class doesn't need this function
|
||||
//virtual string getTrackString(const CLogEvent* ple){return "";}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CFullSearchTrigger scans FullSearch activations for matching data
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CFullSearchTrigger: public CCustomAwardTrigger
|
||||
{
|
||||
public:
|
||||
int regExpCompare(string exp,string cmp);
|
||||
|
||||
map<string,string> varexpressions;
|
||||
|
||||
CFullSearchTrigger(int value, int teamValue, vector<string>& ks,map<string,string> extras);
|
||||
|
||||
vector<string> keys;
|
||||
|
||||
string winnerVar;
|
||||
|
||||
bool compare(string str_msg,string str_key,map<string,string>& varmatches);
|
||||
virtual bool matches(const CLogEvent* le);
|
||||
virtual PID plrIDFromEvent(const CLogEvent* ple);
|
||||
|
||||
//this class does
|
||||
virtual string getTrackString(const CLogEvent* ple);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CUSTOMAWARDTRIGGERS_H
|
||||
@@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CCVarList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cvars.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CCVarList::writeHTML
|
||||
// Purpose: generates and writes the report. generate() is not used in this object
|
||||
// because there is no real intermediate data. Really data is just taken from the
|
||||
// event list, massaged abit, and written out to the html file. There is no calculation
|
||||
// of stats or figures so no intermedidate data creation is needed.
|
||||
// Input: html - the html file that we want to write to.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CCVarList::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
CEventListIterator it;
|
||||
html.write("<table border=0 width=100%% cols=%li><tr>\n",HTML_TABLE_NUM_COLS);
|
||||
bool startOfRow=true;
|
||||
for (it=g_pMatchInfo->eventList()->begin(); it != g_pMatchInfo->eventList()->end(); ++it)
|
||||
{
|
||||
if ((*it)->getType()==CLogEvent::CVAR_ASSIGN)
|
||||
{
|
||||
char var[100];
|
||||
char val[100];
|
||||
|
||||
if (!(*it)->getArgument(0) || !(*it)->getArgument(1))
|
||||
return;
|
||||
|
||||
(*it)->getArgument(0)->getStringValue(var);
|
||||
(*it)->getArgument(1)->getStringValue(val);
|
||||
|
||||
|
||||
//mask off any passwords that the server op may not want to be displayed
|
||||
if (stricmp(var,"rcon_password")==0 || stricmp(var,"sv_password")==0 || stricmp(var,"password")==0)
|
||||
{
|
||||
html.write("<!-- %s not shown! -->\n",var);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startOfRow)
|
||||
{
|
||||
html.write("</tr>\n<tr>");
|
||||
startOfRow=false;
|
||||
}
|
||||
else
|
||||
startOfRow=true;
|
||||
|
||||
html.write("\t<td><font class=cvar> %s = %s </font> </td>\n",var,val);
|
||||
|
||||
}
|
||||
}
|
||||
html.write("</tr></table>");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CCVarList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef CVARS_H
|
||||
#define CVARS_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "report.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CCVarList is a report element that outputs a two column table with
|
||||
// the cvars that were in effect while the match was running. Cvars that contain
|
||||
// various passwords are omitted from the listing.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CCVarList :public CReport
|
||||
{
|
||||
private:
|
||||
enum Consts
|
||||
{
|
||||
HTML_TABLE_WIDTH=500,
|
||||
HTML_TABLE_NUM_COLS=2,
|
||||
};
|
||||
public:
|
||||
explicit CCVarList(){}
|
||||
|
||||
void writeHTML(CHTMLFile& html);
|
||||
|
||||
};
|
||||
#endif // CVARS_H
|
||||
@@ -0,0 +1,159 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CDialogueReadout
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "DialogueReadout.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CDialogueReadout::writeHTML
|
||||
// Purpose: generates and writes the report. generate() is not used in this object
|
||||
// because there is no real intermediate data. Really data is just taken from the
|
||||
// event list, massaged abit, and written out to the html file. There is no calculation
|
||||
// of stats or figures so no intermedidate data creation is needed.
|
||||
// Input: html - the html file that we want to write to.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CDialogueReadout::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
html.write("<img src=\"%s/game.dialog.on.gif\">\n",g_pApp->supportHTTPPath.c_str());
|
||||
html.div("dialog");
|
||||
CEventListIterator it;
|
||||
bool MM2Messages=false;
|
||||
|
||||
if (g_pApp->cmdLineSwitches["displaymm2"]=="on" ||
|
||||
g_pApp->cmdLineSwitches["displaymm2"]=="yes" ||
|
||||
g_pApp->cmdLineSwitches["displaymm2"]=="true" ||
|
||||
g_pApp->cmdLineSwitches["displaymm2"]=="1")
|
||||
MM2Messages=true;
|
||||
|
||||
|
||||
for (it=g_pMatchInfo->eventList()->begin(); it != g_pMatchInfo->eventList()->end(); ++it)
|
||||
{
|
||||
if ((*it)->getType()==CLogEvent::SAY || (MM2Messages && ((*it)->getType()==CLogEvent::SAY_TEAM)))
|
||||
{
|
||||
char talked[512]={0};
|
||||
PID talkerPID=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string talkerName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
|
||||
for (int i=1;(*it)->getArgument(i);i++)
|
||||
{
|
||||
char temp[512];
|
||||
(*it)->getArgument(i)->getStringValue(temp);
|
||||
strcat(talked,"\"");
|
||||
strcat(talked,temp);
|
||||
strcat(talked,"\"");
|
||||
}
|
||||
|
||||
bool isTeamMsg= (*it)->getType()==CLogEvent::SAY_TEAM;
|
||||
int teamID=g_pMatchInfo->playerList()[talkerPID].teams.atTime((*it)->getTime());
|
||||
|
||||
const char* aa;
|
||||
const char* bb;
|
||||
|
||||
if (teamID<4 && teamID >= 0)
|
||||
{
|
||||
aa="player";
|
||||
bb=Util::teamcolormap[teamID];
|
||||
}
|
||||
else
|
||||
{
|
||||
aa="whitetext";
|
||||
bb="";
|
||||
}
|
||||
|
||||
html.write("<tr><td><font class=%s%s>%s%s:</font><font color=white> %s</font></tr></td>\n",aa,bb,talkerName.c_str(),isTeamMsg?" (Team)":"",talked);
|
||||
html.br();
|
||||
}
|
||||
else if ( (*it)->getType()==CLogEvent::KILLED_BY_WORLD)
|
||||
{
|
||||
PID plr=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string plrName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
int teamID=g_pMatchInfo->playerList()[plr].teams.atTime((*it)->getTime());
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> died.</font></tr></td>\n",Util::teamcolormap[teamID],plrName.c_str());
|
||||
html.br();
|
||||
}
|
||||
else if ((*it)->getType()==CLogEvent::SUICIDE)
|
||||
{
|
||||
PID plr=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string plrName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
int teamID=g_pMatchInfo->playerList()[plr].teams.atTime((*it)->getTime());
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> committed suicide.</font></tr></td>\n",Util::teamcolormap[teamID],plrName.c_str());
|
||||
html.br();
|
||||
}
|
||||
else if ((*it)->getType()==CLogEvent::TEAM_JOIN)
|
||||
{
|
||||
PID plr=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string plrName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
time_t eventtime=(*it)->getTime();
|
||||
bool firstJoin=!g_pMatchInfo->playerList()[plr].teams.anythingAtTime(eventtime-1);
|
||||
int oldTeamID=g_pMatchInfo->playerList()[plr].teams.atTime(eventtime-1);
|
||||
int teamID=g_pMatchInfo->playerList()[plr].teams.atTime(eventtime);
|
||||
string teamName=g_pMatchInfo->teamName(teamID);
|
||||
if (firstJoin)
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> joined team <font class=player%s>%s</font>.</font></tr></td>\n",Util::teamcolormap[teamID],plrName.c_str(),Util::teamcolormap[teamID],teamName.c_str());
|
||||
else
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> changed teams to <font class=player%s>%s</font>.</font></tr></td>\n",Util::teamcolormap[oldTeamID],plrName.c_str(),Util::teamcolormap[teamID],teamName.c_str());
|
||||
html.br();
|
||||
}
|
||||
else if ((*it)->getType()==CLogEvent::FRAG)
|
||||
{
|
||||
PID killer=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string killerName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
PID killee=(*it)->getArgument(1)->asPlayerGetPID();
|
||||
string killeeName=(*it)->getArgument(1)->asPlayerGetName();
|
||||
string weaponName = (*it)->getArgument(2)->getStringValue();
|
||||
|
||||
int killerTeamID=g_pMatchInfo->playerList()[killer].teams.atTime((*it)->getTime());
|
||||
int killeeTeamID=g_pMatchInfo->playerList()[killee].teams.atTime((*it)->getTime());
|
||||
|
||||
bool countKill=true;
|
||||
|
||||
//gotta account for timer/infection double kills for medics!
|
||||
if (weaponName=="infection")
|
||||
{
|
||||
//test to see if the previous event was a timer from the same player, and a kill, and with the timer.
|
||||
CEventListIterator it2=it;
|
||||
if ((--it2)!=g_pMatchInfo->eventList()->begin())
|
||||
{
|
||||
if ((*it2)->getType() == CLogEvent::FRAG)
|
||||
if ((*it2)->getArgument(2)->getStringValue()=="timer")
|
||||
if ((*it2)->getArgument(0)->asPlayerGetPID()==killer)
|
||||
countKill=false;
|
||||
}
|
||||
}
|
||||
if (countKill)
|
||||
{
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> killed </font><font class=player%s>%s</font><font color=white> with %s. </font></tr></td>\n",
|
||||
Util::teamcolormap[killerTeamID],killerName.c_str(),Util::teamcolormap[killeeTeamID],killeeName.c_str(),weaponName.c_str());
|
||||
html.br();
|
||||
}
|
||||
|
||||
}
|
||||
else if ((*it)->getType()==CLogEvent::TEAM_FRAG)
|
||||
{
|
||||
PID killer=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
string killerName=(*it)->getArgument(0)->asPlayerGetName();
|
||||
PID killee=(*it)->getArgument(1)->asPlayerGetPID();
|
||||
string killeeName=(*it)->getArgument(1)->asPlayerGetName();
|
||||
|
||||
int killerTeamID=g_pMatchInfo->playerList()[killer].teams.atTime((*it)->getTime());
|
||||
int killeeTeamID=g_pMatchInfo->playerList()[killee].teams.atTime((*it)->getTime());
|
||||
html.write("<tr><td><font class=player%s>%s</font><font color=white> teamkilled </font><font class=player%s>%s.</font></tr></td>\n",
|
||||
Util::teamcolormap[killerTeamID],killerName.c_str(),Util::teamcolormap[killeeTeamID],killeeName.c_str());
|
||||
html.br();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html.enddiv();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CDialogueReadout
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef DIALOGUEREADOUT_H
|
||||
#define DIALOGUEREADOUT_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "Report.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CDialogueReadout is a full page report element that outputs a listing
|
||||
// of all the dialogue in the match. It also reports deaths, and suicides since those
|
||||
// usually beget lots of smack talking.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CDialogueReadout : public CReport
|
||||
{
|
||||
private:
|
||||
public:
|
||||
explicit CDialogueReadout(){}
|
||||
void writeHTML(CHTMLFile& html);
|
||||
};
|
||||
#endif // DIALOGUEREADOUT_H
|
||||
@@ -0,0 +1,61 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CEventList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include <stdlib.h>
|
||||
#include "TFStatsApplication.h"
|
||||
#include "EventList.h"
|
||||
#include "memdbg.h"
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CEventList::readEventList
|
||||
// Purpose: reads and returns a CEventList from a logfile
|
||||
// Input: filename - the logfile to read from
|
||||
// Output: CEventList*
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CEventList* CEventList::readEventList(const char* filename)
|
||||
{
|
||||
|
||||
// ifstream ifs(filename);
|
||||
CEventList* plogfile=new TRACKED CEventList();
|
||||
if (!plogfile)
|
||||
{
|
||||
printf("TFStats ran out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FILE* f=fopen(filename,"rt");
|
||||
if (!f)
|
||||
g_pApp->fatalError("Error opening %s, please make sure that the file exists and is not being accessed by other processes",filename);
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
CLogEvent* curr=NULL;
|
||||
curr=new TRACKED CLogEvent(f);
|
||||
|
||||
if (!curr->isValid())
|
||||
{
|
||||
delete curr;
|
||||
break;//eof reached
|
||||
}
|
||||
plogfile->insert(plogfile->end(),curr);
|
||||
}
|
||||
fclose(f);
|
||||
#ifndef WIN32
|
||||
chmod(filename,PERMIT);
|
||||
#endif
|
||||
|
||||
return plogfile;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CEventList
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef EVENTLIST_H
|
||||
#define EVENTLIST_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning(disable :4786)
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "LogEvent.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
typedef std::list<const CLogEvent*> event_list;
|
||||
typedef std::list<const CLogEvent*>::iterator CEventListIterator;
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CEventList is just a thin wrapper around a list of CLogEvent objects
|
||||
// It also provides a factory method to read and return a CEventList from a
|
||||
// log file
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CEventList
|
||||
{
|
||||
public:
|
||||
static CEventList* readEventList(const char* filename);
|
||||
void insert(CEventListIterator cli, const CLogEvent* cle){m_List.insert(cli,cle);}
|
||||
CEventListIterator begin(){return m_List.begin();}
|
||||
CEventListIterator end(){return m_List.end();}
|
||||
bool empty(){return m_List.empty();}
|
||||
|
||||
private:
|
||||
event_list m_List;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // EVENTLIST_H
|
||||
@@ -0,0 +1,131 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CHTMLFile. see HTML.h for details
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#pragma warning (disable:4786)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "TFStatsApplication.h"
|
||||
#include "util.h"
|
||||
#include "html.h"
|
||||
|
||||
//readability aids used when calling constructor
|
||||
const bool CHTMLFile::printBody=true;
|
||||
const bool CHTMLFile::dontPrintBody=false;
|
||||
const bool CHTMLFile::linkStyle=true;
|
||||
const bool CHTMLFile::dontLinkStyle=false;
|
||||
|
||||
using namespace std;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CHTMLFile::CHTMLFile
|
||||
// Purpose:
|
||||
// Input: filename - name of the html file that will be written
|
||||
// title - title of the html document
|
||||
// fPrintBody - true if the <body> tag is to be written.
|
||||
// bgimage - name of a background image, if desired
|
||||
// leftmarg - pixels on the left margin (if desired)
|
||||
// topmarg - pixels on the top margin (if desired)
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CHTMLFile::CHTMLFile(const char* filenm,const char* title,bool fPrintBody,const char* bgimage,int leftmarg, int topmarg)
|
||||
{
|
||||
strcpy(filename,filenm);
|
||||
open(filename);
|
||||
|
||||
|
||||
write("<HEAD>\n");
|
||||
write("<TITLE> %s </TITLE>\n",title);
|
||||
string csshttppath(g_pApp->supportHTTPPath);
|
||||
csshttppath+="/style.css";
|
||||
|
||||
write("<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\">\n",csshttppath.c_str());
|
||||
write("</HEAD>\n");
|
||||
|
||||
fBody=fPrintBody;
|
||||
if (fBody)
|
||||
{
|
||||
write("<BODY leftmargin=%li topmargin=%li ",leftmarg,topmarg);
|
||||
if (bgimage)
|
||||
write("background=%s",bgimage);
|
||||
else
|
||||
write("bgcolor = black");
|
||||
write(">\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CHTMLFile::open
|
||||
// Purpose: opens the html file, and writes <html>
|
||||
// Input: filename - the name of the file to open
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CHTMLFile::open(const char* filename)
|
||||
{
|
||||
out=fopen(filename,"wt");
|
||||
if (!out)
|
||||
g_pApp->fatalError("Can't open output file \"%s\"!\nPlease make sure that the file does not exist OR\nif the file does exit, make sure it is not read-only",filename);
|
||||
|
||||
write("<HTML>\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CHTMLFile::write
|
||||
// Purpose: writes a string to the html file
|
||||
// Input: fmt - format string, like printf suite of functions
|
||||
// ... - list of arguments
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CHTMLFile::write(const char* fmt,...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va,fmt);
|
||||
vfprintf(out,fmt,va);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CHTMLFile::close
|
||||
// Purpose: closes the html file, closing <body> and <html> tags if needed
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CHTMLFile::close()
|
||||
{
|
||||
if (!out)
|
||||
return;
|
||||
if (fBody)
|
||||
write("</BODY>\n");
|
||||
|
||||
write("</HTML>\n\n");
|
||||
#ifndef WIN32
|
||||
chmod(filename,PERMIT);
|
||||
#endif
|
||||
fclose(out);
|
||||
out=NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CHTMLFile::~CHTMLFile
|
||||
// Purpose: Destructor. closes the file
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CHTMLFile::~CHTMLFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CHTMLFile::hr(int len,bool alignleft)
|
||||
{
|
||||
write("<hr %s width=%li>\n",alignleft?"align=left":"",len);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CHTMLFile.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HTML_H
|
||||
#define HTML_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CHTMLFile represents an HTML text file that is being created. It has
|
||||
// some misc helper stuff, like writing the body tag for you, and linking to the style
|
||||
// sheet. Also some little helper functions to do <br>s and <p>s
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CHTMLFile
|
||||
{
|
||||
public:
|
||||
static const bool printBody;
|
||||
static const bool dontPrintBody;
|
||||
static const bool linkStyle;
|
||||
static const bool dontLinkStyle;
|
||||
|
||||
private:
|
||||
FILE* out;
|
||||
char filename[100];
|
||||
bool fBody;
|
||||
public:
|
||||
CHTMLFile():out(NULL),fBody(false){}
|
||||
|
||||
CHTMLFile(const char*filenm ,const char* title,bool fPrintBody=true,const char* bgimage=NULL,int leftmarg=0,int topmarg=20);
|
||||
void open(const char*);
|
||||
|
||||
void write(PRINTF_FORMAT_STRING const char*,...);
|
||||
|
||||
void hr(int len=0,bool alignleft=false);
|
||||
void br(){write("<br>\n");}
|
||||
void p(){write("<p>\n");};
|
||||
void img(const char* i){write("<img src=%s>\n",i);}
|
||||
|
||||
void div(const char* cls){write("<div class=%s>\n",cls);}
|
||||
void div(){write("<div>\n");}
|
||||
void enddiv(){write("</div>");}
|
||||
|
||||
void close();
|
||||
~CHTMLFile();
|
||||
};
|
||||
#endif // HTML_H
|
||||
@@ -0,0 +1,66 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CKamikazeAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "KamikazeAward.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CKamikazeAward::getWinner
|
||||
// Purpose: determines the winner of the award
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CKamikazeAward::getWinner()
|
||||
{
|
||||
CEventListIterator it;
|
||||
|
||||
for (it=g_pMatchInfo->eventList()->begin(); it != g_pMatchInfo->eventList()->end(); ++it)
|
||||
{
|
||||
if ((*it)->getType()==CLogEvent::SUICIDE || (*it)->getType()==CLogEvent::KILLED_BY_WORLD)
|
||||
{
|
||||
PID kami=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
numdeaths[kami]++;
|
||||
winnerID=kami;
|
||||
fNoWinner=false;
|
||||
}
|
||||
}
|
||||
|
||||
map<PID,int>::iterator kamiter;
|
||||
|
||||
for (kamiter=numdeaths.begin();kamiter!=numdeaths.end();++kamiter)
|
||||
{
|
||||
int currID=(*kamiter).first;
|
||||
if (numdeaths[currID]>numdeaths[winnerID])
|
||||
winnerID=currID;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CKamikazeAward::noWinner
|
||||
// Purpose: writes html indicating that no one won this award
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CKamikazeAward::noWinner(CHTMLFile& html)
|
||||
{
|
||||
html.write("No one killed themselves during this match! Good work!");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CKamikazeAward::extendedinfo
|
||||
// Purpose: reports how many times the winner killed him/herself
|
||||
// Input: html - the html file to write to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CKamikazeAward::extendedinfo(CHTMLFile& html)
|
||||
{
|
||||
if (numdeaths[winnerID]==1)
|
||||
html.write("%s suicided once.",winnerName.c_str());
|
||||
else
|
||||
html.write("%s was self-victimized %li times.",winnerName.c_str(),numdeaths[winnerID]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CKamikazeAward
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef KAMIKAZEAWARD_H
|
||||
#define KAMIKAZEAWARD_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "Award.h"
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CKamikazeAward is an award given to the player who kills him/herself
|
||||
// the most often.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CKamikazeAward: public CAward
|
||||
{
|
||||
protected:
|
||||
map<PID,int> numdeaths;
|
||||
void noWinner(CHTMLFile& html);
|
||||
void extendedinfo(CHTMLFile& html);
|
||||
public:
|
||||
explicit CKamikazeAward():CAward("Kamikaze"){}
|
||||
void getWinner();
|
||||
};
|
||||
#endif // KAMIKAZEAWARD_H
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CLogEvent
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef LOGEVENT_H
|
||||
#define LOGEVENT_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning(disable :4786)
|
||||
|
||||
|
||||
#include "Argument.h"
|
||||
|
||||
#ifdef WIN32
|
||||
//#include <strstrea.h>
|
||||
#else
|
||||
//#include <strstream.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
//#include <iostream.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CLogEvent represents an event in the log file. e.g. one line.
|
||||
// It can have one of several types (enumerated below) and a list of arguments
|
||||
// is attached as well.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CLogEvent
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
NOTYPE =0,
|
||||
INVALID = 0,
|
||||
LOG_FILE_INIT,
|
||||
SERVER_SPAWN,
|
||||
SERVER_SHUTDOWN,
|
||||
LOG_CLOSED,
|
||||
SERVER_MISC,
|
||||
SERVER_NAME,
|
||||
TEAM_RENAME,
|
||||
LEVEL_CHANGE,
|
||||
CVAR_ASSIGN,
|
||||
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,
|
||||
SAY,
|
||||
SAY_TEAM,
|
||||
CURE,
|
||||
NAMED_GOAL_ACTIVATE,
|
||||
ANON_GOAL_ACTIVATE,
|
||||
NAMED_BROADCAST,
|
||||
ANON_BROADCAST,
|
||||
CLASS_CHANGE,
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
char* m_StrippedText;
|
||||
private:
|
||||
ArgVector m_args;
|
||||
|
||||
char m_EventCode;
|
||||
|
||||
time_t m_EventTime;
|
||||
|
||||
bool m_Valid;
|
||||
char* m_EventMessage;
|
||||
Type m_EventType;
|
||||
|
||||
|
||||
bool keywordsOccur(char* s1,char* s2=NULL,char* s3=NULL);
|
||||
void parseArgs();
|
||||
// void readEventTime(istream& is);
|
||||
// void readEventCode(istream& is);
|
||||
// void readEventMessage(istream& is);
|
||||
void parseArgument(const char*& raw); //ref to pointer to constant char, gotta love it.
|
||||
void determineType();
|
||||
|
||||
public:
|
||||
CLogEvent* m_Next;
|
||||
|
||||
CLogEvent();
|
||||
~CLogEvent();
|
||||
bool isValid(){return m_Valid;}
|
||||
|
||||
// explicit CLogEvent(istream& is);
|
||||
// virtual void readEvent(istream& is);
|
||||
// virtual void print(ostream& os);
|
||||
|
||||
|
||||
|
||||
|
||||
CLogEvent::Type getType() const {return m_EventType;}
|
||||
time_t getTime() const {return m_EventTime;}
|
||||
const CLogEventArgument* getArgument(int i) const;
|
||||
|
||||
const char* getFullMessage() const {return m_EventMessage;}
|
||||
|
||||
|
||||
|
||||
|
||||
static const char* TypeNames[];
|
||||
|
||||
|
||||
//unused stuff
|
||||
protected:
|
||||
void readEventTime(FILE* f);
|
||||
void readEventCode(FILE* f);
|
||||
void readEventMessage(FILE* f);
|
||||
|
||||
public:
|
||||
explicit CLogEvent(FILE* f);
|
||||
virtual void readEvent(FILE* f);
|
||||
virtual void print(FILE* f=stdout);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // LOGEVENT_H
|
||||
@@ -0,0 +1,116 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#if 0
|
||||
//=========== (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 CLogEvent's C++ IO Stream stuff. this isn't used currently
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "LogEvent.h"
|
||||
#include <string.h>
|
||||
|
||||
//none of this is used. I opted for the FILE* implementation instead, this one was giving some weird results, and not working right.
|
||||
CLogEvent::CLogEvent(istream& is)
|
||||
:m_EventCode('\0'),m_EventTime(0),m_Valid(false),m_Next(NULL),m_StrippedText(NULL),m_EventType(INVALID)
|
||||
{
|
||||
readEvent(is);
|
||||
}
|
||||
|
||||
void CLogEvent::print(ostream& os)
|
||||
{
|
||||
os << "(" <<m_EventTime<<") Event Type: "<<TypeNames[m_EventType]<<endl;
|
||||
os << "Args: ";
|
||||
|
||||
for(int i=0;i<m_args.size();i++)
|
||||
cout<< "\t"<<m_args[i]->getStringValue()<<endl;
|
||||
|
||||
}
|
||||
|
||||
void CLogEvent::readEvent(istream& is)
|
||||
{
|
||||
readEventCode(is);
|
||||
readEventTime(is);
|
||||
readEventMessage(is);
|
||||
determineType();
|
||||
|
||||
if(is)
|
||||
m_Valid=true;
|
||||
else
|
||||
m_Valid=false;
|
||||
|
||||
}
|
||||
|
||||
//note this function assumes you're at the start of a line
|
||||
|
||||
void CLogEvent::readEventCode(istream& is)
|
||||
{
|
||||
is>>m_EventCode;
|
||||
}
|
||||
|
||||
|
||||
void CLogEvent::readEventMessage(istream& is)
|
||||
{
|
||||
char temp[512]={0,0,0,0};
|
||||
is.getline(temp,512,'\n');
|
||||
|
||||
m_EventMessage=new char[strlen(temp)];
|
||||
strcpy(m_EventMessage,temp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CLogEvent::readEventTime(istream& is)
|
||||
{
|
||||
|
||||
int month,day,year;
|
||||
int hour,minute,second;
|
||||
// fscanf(f," %i/%i/%i - %i:%i:%i: ",&month,&day,&year,&hour,&minute,&second);
|
||||
|
||||
is >> month;
|
||||
is.ignore(); //'/'
|
||||
is >> day;
|
||||
is.ignore(); //'/'
|
||||
is >> year;
|
||||
is.ignore(3); //' - '
|
||||
is >> hour;
|
||||
is.ignore(); //':'
|
||||
is >> minute;
|
||||
is.ignore(); //':'
|
||||
is >> second;
|
||||
is.ignore(); //':'
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
m_EventTime=mktime(&t);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: dummy main.cpp
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "TFStatsApplication.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: main
|
||||
// Purpose: dummy main. passes off execution to TFstats main
|
||||
// Input: argc - argument count
|
||||
// argv[] - argument list
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
void main(int argc, const char* argv[])
|
||||
{
|
||||
//make OS application object, and operating system interface
|
||||
g_pApp=new CTFStatsApplication;
|
||||
g_pApp->majorVer=1;
|
||||
g_pApp->minorVer=5;
|
||||
|
||||
#ifdef WIN32
|
||||
g_pApp->os=new CTFStatsWin32Interface();
|
||||
#else
|
||||
g_pApp->os=new CTFStatsLinuxInterface();
|
||||
#endif
|
||||
//hand off execution to real main
|
||||
g_pApp->main(argc,argv);
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
#
|
||||
# TF Stats Makefile for Linux 2.0
|
||||
#
|
||||
# Jul '99 by Mike Harrington <mike@valvesoftware.com>
|
||||
# (modified by Wes Cumberland <wesc@valvesoftware.com>)
|
||||
#
|
||||
#
|
||||
|
||||
VERSION=1.0.0.0
|
||||
VERSION_FN=$(VERSION)$(GLIBC)
|
||||
RPM_RELEASE=0
|
||||
|
||||
ifneq (,$(findstring libc6,$(shell if [ -e /lib/libc.so.6* ];then echo libc6;fi)))
|
||||
GLIBC=-glibc
|
||||
else
|
||||
GLIBC=
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring alpha,$(shell uname -m)))
|
||||
ARCH=axp
|
||||
RPMARCH=alpha
|
||||
else
|
||||
ARCH=i386
|
||||
RPMARCH=i386
|
||||
endif
|
||||
|
||||
MOUNT_DIR=/momma
|
||||
|
||||
BUILD_DEBUG_DIR=$(MOUNT_DIR)/tfstats/debug
|
||||
BUILD_RELEASE_DIR=$(MOUNT_DIR)/tfstats/release
|
||||
TFSTATS_DIR=$(MOUNT_DIR)/tfstats
|
||||
|
||||
CC=/usr/bin/g++
|
||||
STDCPP_INC= #/usr/local/lib/gcc-lib/H-libstdc++/include/g++-v3
|
||||
STDCPP_LIB= #/usr/local/lib/gcc-lib/H-libstdc++/lib
|
||||
BASE_CFLAGS=-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -Iregexp/include
|
||||
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -m486 -O1
|
||||
RELEASE_NOOP_CFLAGS=$(BASE_CFLAGS) -m486
|
||||
|
||||
DEBUG_CFLAGS=$(BASE_CFLAGS) -g -D_DEBUG -DDEBUG -Wall
|
||||
|
||||
LDFLAGS= -static /momma/tfstats/regexp/lib/libregex++.a -ldl -lm \
|
||||
-lstdc++
|
||||
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
|
||||
DO_CC_NOOPT=$(CC) -DNO_NAMESPACE -D_WONCRYPT_NOEXCEPTIONS -w $(CFLAGS_NOOPT) -o $@ -c $<
|
||||
DO_CC=$(CC) -DNO_NAMESPACE -D_WONCRYPT_NOEXCEPTIONS -w $(CFLAGS) -o $@ -c $<
|
||||
DO_W_CC=$(CC) -DNO_NAMESPACE -D_WONCRYPT_NOEXCEPTIONS $(CFLAGS) -Wall -o $@ -c $<
|
||||
DO_CRYPT_CC=$(CC) -x c++ -DNO_NAMESPACE -D_WONCRYPT_NOEXCEPTIONS $(CFLAGS) -I$(WON_INC) -o $@ -c $<
|
||||
|
||||
#############################################################################
|
||||
# SETUP AND BUILD
|
||||
#############################################################################
|
||||
|
||||
default: build_debug
|
||||
|
||||
TARGETS=\
|
||||
$(BUILDDIR)/tfstats_l
|
||||
|
||||
|
||||
make_build_dir:
|
||||
for x in $(BUILDDIR) \
|
||||
$(BUILDDIR)/tfstats ; do \
|
||||
if [ ! -d $$x ];then mkdir $$x;fi;done
|
||||
|
||||
build_debug:
|
||||
$(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" CFLAGS_NOOPT="$(DEBUG_CFLAGS)"
|
||||
|
||||
build_release:
|
||||
$(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" CFLAGS_NOOPT="$(RELEASE_NOOP_CFLAGS)"
|
||||
|
||||
all: build_debug build_release
|
||||
|
||||
targets: $(TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f $(BUILD_DEBUG_DIR)/*.o
|
||||
|
||||
#############################################################################
|
||||
# TF Stats Program
|
||||
#############################################################################
|
||||
|
||||
TFSTATS_OBJS = \
|
||||
$(BUILDDIR)/Argument.o \
|
||||
$(BUILDDIR)/EventList.o \
|
||||
$(BUILDDIR)/LogEvent.o \
|
||||
$(BUILDDIR)/LogEventIOStreams.o \
|
||||
$(BUILDDIR)/CureAward.o \
|
||||
$(BUILDDIR)/KamikazeAward.o \
|
||||
$(BUILDDIR)/SentryRebuildAward.o \
|
||||
$(BUILDDIR)/SharpshooterAward.o \
|
||||
$(BUILDDIR)/SurvivalistAward.o \
|
||||
$(BUILDDIR)/TalkativeAward.o \
|
||||
$(BUILDDIR)/TeamKillAward.o \
|
||||
$(BUILDDIR)/WeaponAwards.o \
|
||||
$(BUILDDIR)/CustomAward.o \
|
||||
$(BUILDDIR)/CustomAwardList.o \
|
||||
$(BUILDDIR)/CustomAwardTriggers.o \
|
||||
$(BUILDDIR)/Award.o \
|
||||
$(BUILDDIR)/CVars.o \
|
||||
$(BUILDDIR)/DialogueReadout.o \
|
||||
$(BUILDDIR)/MatchResults.o \
|
||||
$(BUILDDIR)/scoreboard.o \
|
||||
$(BUILDDIR)/WhoKilledWho.o \
|
||||
$(BUILDDIR)/Report.o \
|
||||
$(BUILDDIR)/HTML.o \
|
||||
$(BUILDDIR)/main.o \
|
||||
$(BUILDDIR)/TextFile.o \
|
||||
$(BUILDDIR)/util.o \
|
||||
$(BUILDDIR)/PlayerSpecifics.o \
|
||||
$(BUILDDIR)/StaticOutputFiles.o \
|
||||
$(BUILDDIR)/TFStatsReport.o \
|
||||
$(BUILDDIR)/Player.o \
|
||||
$(BUILDDIR)/MatchInfo.o \
|
||||
$(BUILDDIR)/memdbg.o \
|
||||
$(BUILDDIR)/pid.o \
|
||||
$(BUILDDIR)/binresources.o \
|
||||
$(BUILDDIR)/tfstatsapplication.o \
|
||||
$(BUILDDIR)/plrpersist.o \
|
||||
$(BUILDDIR)/tfstatsosinterface.o \
|
||||
$(BUILDDIR)/allplayersstats.o \
|
||||
$(BUILDDIR)/playerreport.o
|
||||
|
||||
|
||||
|
||||
$(BUILDDIR)/tfstats_l : $(TFSTATS_OBJS)
|
||||
$(CC) $(CFLAGS) -L/usr/local/lib -o $@ $(TFSTATS_OBJS) $(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/buildnum.o : $(TFSTATS_DIR)/buildnum.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/Argument.o : $(TFSTATS_DIR)/Argument.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/EventList.o : $(TFSTATS_DIR)/EventList.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/LogEvent.o : $(TFSTATS_DIR)/LogEvent.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/Player.o : $(TFSTATS_DIR)/Player.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/MatchInfo.o : $(TFSTATS_DIR)/MatchInfo.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/LogEventIOStreams.o : $(TFSTATS_DIR)/LogEventIOStreams.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/CureAward.o : $(TFSTATS_DIR)/CureAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/KamikazeAward.o : $(TFSTATS_DIR)/KamikazeAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/SentryRebuildAward.o : $(TFSTATS_DIR)/SentryRebuildAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/SharpshooterAward.o : $(TFSTATS_DIR)/SharpshooterAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/SurvivalistAward.o : $(TFSTATS_DIR)/SurvivalistAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/TalkativeAward.o : $(TFSTATS_DIR)/TalkativeAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/TeamKillAward.o : $(TFSTATS_DIR)/TeamKillAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/WeaponAwards.o : $(TFSTATS_DIR)/WeaponAwards.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/CustomAward.o : $(TFSTATS_DIR)/CustomAward.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/CustomAwardList.o : $(TFSTATS_DIR)/CustomAwardList.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/CustomAwardTriggers.o : $(TFSTATS_DIR)/CustomAwardTriggers.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/Award.o : $(TFSTATS_DIR)/Award.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/CVars.o : $(TFSTATS_DIR)/CVars.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/DialogueReadout.o : $(TFSTATS_DIR)/DialogueReadout.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/MatchResults.o : $(TFSTATS_DIR)/MatchResults.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/scoreboard.o : $(TFSTATS_DIR)/scoreboard.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/WhoKilledWho.o : $(TFSTATS_DIR)/WhoKilledWho.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/Report.o : $(TFSTATS_DIR)/Report.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/HTML.o : $(TFSTATS_DIR)/HTML.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/main.o : $(TFSTATS_DIR)/main.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/TextFile.o : $(TFSTATS_DIR)/TextFile.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/util.o : $(TFSTATS_DIR)/util.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/binresources.o : $(TFSTATS_DIR)/binresources.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/PlayerSpecifics.o : $(TFSTATS_DIR)/PlayerSpecifics.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/StaticOutputFiles.o : $(TFSTATS_DIR)/StaticOutputFiles.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/TFStatsReport.o : $(TFSTATS_DIR)/TFStatsReport.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/memdbg.o : $(TFSTATS_DIR)/memdbg.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/pid.o : $(TFSTATS_DIR)/pid.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/tfstatsapplication.o : $(TFSTATS_DIR)/tfstatsapplication.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/playerreport.o : $(TFSTATS_DIR)/playerreport.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/plrpersist.o : $(TFSTATS_DIR)/plrpersist.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/tfstatsosinterface.o : $(TFSTATS_DIR)/tfstatsosinterface.cpp
|
||||
$(DO_CC)
|
||||
|
||||
$(BUILDDIR)/allplayersstats.o : $(TFSTATS_DIR)/allplayersstats.cpp
|
||||
$(DO_CC)
|
||||
|
||||
@@ -0,0 +1,460 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implemenatation of CMatchInfo
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "MatchInfo.h"
|
||||
|
||||
CMatchInfo* g_pMatchInfo=NULL; //global information about the match.
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CMatchInfo::generate
|
||||
// Purpose: generates the match info structure from the log file
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CMatchInfo::generate()
|
||||
{
|
||||
if (plogfile->empty())
|
||||
g_pApp->fatalError("No data in log file!\nPlease ensure that you are running TFstats on a valid log file!");
|
||||
|
||||
CEventListIterator it=plogfile->begin();
|
||||
logopentime=(*it)->getTime();
|
||||
for (it;it!=plogfile->end();++it)
|
||||
{
|
||||
const CLogEvent* curr=(*it);
|
||||
switch(curr->getType())
|
||||
{
|
||||
case CLogEvent::CONNECT:
|
||||
{
|
||||
int sid=curr->getArgument(0)->asPlayerGetSvrPID();
|
||||
unsigned long WONid=curr->getArgument(0)->asPlayerGetWONID();
|
||||
string plrName=curr->getArgument(0)->asPlayerGetName();
|
||||
string ipAddress=curr->getArgument(1)->getStringValue();
|
||||
PID pid;
|
||||
PID foundpid=-1;
|
||||
if (WONid!=-1)
|
||||
{
|
||||
bLanGame=false;
|
||||
pid=pidMap[sid]=WONid;
|
||||
}
|
||||
else
|
||||
{
|
||||
bLanGame=true;
|
||||
|
||||
CPlayerList::iterator it=players.begin();
|
||||
for (it;it!=players.end();++it)
|
||||
{
|
||||
PID currpid=it->first;
|
||||
CPlayer& cp=it->second;
|
||||
if (cp.ipAddress==ipAddress)
|
||||
{
|
||||
foundpid=currpid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it==players.end()) //if no ip addresses matched match by name
|
||||
{
|
||||
it = players.begin();
|
||||
for (it;it!=players.end();++it)
|
||||
{
|
||||
PID currpid=it->first;
|
||||
CPlayer& cp=it->second;
|
||||
if (cp.aliases.contains(plrName))
|
||||
{
|
||||
foundpid=currpid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundpid != -1)
|
||||
{
|
||||
pid=pidMap[sid]=foundpid;
|
||||
}
|
||||
else
|
||||
{
|
||||
pid=pidMap[sid]=sid;
|
||||
}
|
||||
//printf("Checkpoint %lu\n",__LINE__);
|
||||
//printf("pid=%lu\n",pid);
|
||||
if (players[pid].pid==-1)
|
||||
players[pid].pid=pid;
|
||||
|
||||
players[pid].ipAddress=ipAddress;
|
||||
players[pid].svrPID=sid;
|
||||
players[pid].WONID=WONid;
|
||||
//keep the pseudonym list updated
|
||||
players[pid].nameFound(curr->getTime(),plrName);
|
||||
|
||||
}
|
||||
break;
|
||||
case CLogEvent::ENTER_GAME:
|
||||
{
|
||||
int sid=curr->getArgument(0)->asPlayerGetSvrPID();
|
||||
//PID pid=curr->getArgument(0)->asPlayerGetFullPID();
|
||||
unsigned long WONid=curr->getArgument(0)->asPlayerGetWONID();
|
||||
|
||||
PID pid;
|
||||
if (WONid!=-1)
|
||||
{
|
||||
bLanGame=false;
|
||||
pid=pidMap[sid]=WONid;
|
||||
}
|
||||
else
|
||||
{
|
||||
bLanGame=true;
|
||||
|
||||
//they may have matched based on IP or name.
|
||||
//so check if the player structure pointed to by
|
||||
//the sid is valid, if so, don't reassign pid
|
||||
pid=pidMap[sid];
|
||||
if (players[pid].ipAddress=="")
|
||||
pid=pidMap[sid]=sid;
|
||||
}
|
||||
|
||||
players[pid].svrPID=sid;
|
||||
players[pid].WONID=WONid;
|
||||
players[pid].pid=pid;
|
||||
string nm=curr->getArgument(0)->asPlayerGetName();
|
||||
|
||||
//keep the pseudonym list updated
|
||||
players[pid].nameFound(curr->getTime(),nm);
|
||||
}
|
||||
break;
|
||||
case CLogEvent::CLASS_CHANGE:
|
||||
{
|
||||
PID pid=curr->getArgument(0)->asPlayerGetPID();
|
||||
time_t changetime=curr->getTime();
|
||||
|
||||
player_class newpc=playerClassNameToClassID(curr->getArgument(1)->getStringValue());
|
||||
|
||||
//keep the pseudonym list updated
|
||||
players[pid].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
string plrname=curr->getArgument(0)->asPlayerGetName();
|
||||
|
||||
players[pid].allclassesplayed.add(changetime,newpc);
|
||||
|
||||
int currTeam=players[pid].teams.atTime(changetime);
|
||||
players[pid].perteam[currTeam].classesplayed.add(changetime,newpc);
|
||||
|
||||
}
|
||||
break;
|
||||
case CLogEvent::NAME_CHANGE:
|
||||
{
|
||||
//keep the pseudonym list updated
|
||||
players[curr->getArgument(0)->asPlayerGetPID()].nameFound(curr->getTime(),curr->getArgument(1)->asPlayerGetName());
|
||||
}
|
||||
break;
|
||||
case CLogEvent::SUICIDE:
|
||||
{
|
||||
PID pid=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
int team=players[pid].teams.atTime((*it)->getTime());
|
||||
|
||||
// players[pid].perteam[team].kills++;
|
||||
players[pid].perteam[team].deaths++;
|
||||
players[pid].perteam[team].suicides++;
|
||||
|
||||
//keep the pseudonym list updated
|
||||
players[pid].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
}
|
||||
break;
|
||||
case CLogEvent::FRAG:
|
||||
case CLogEvent::TEAM_FRAG:
|
||||
{
|
||||
PID killerid=(*it)->getArgument(0)->asPlayerGetPID();
|
||||
PID killedid=(*it)->getArgument(1)->asPlayerGetPID();
|
||||
int killerTeam=players[killerid].teams.atTime((*it)->getTime());
|
||||
int killedTeam=players[killedid].teams.atTime((*it)->getTime());
|
||||
|
||||
|
||||
CPlayer& p1=players[killerid];
|
||||
CPlayer& p2=players[killedid];
|
||||
|
||||
|
||||
if (curr->getType() == CLogEvent::TEAM_FRAG)
|
||||
{
|
||||
players[killerid].perteam[killerTeam].teamkills++;
|
||||
players[killedid].perteam[killedTeam].teamkilled++;
|
||||
}
|
||||
else if (curr->getType() == CLogEvent::FRAG)
|
||||
{
|
||||
string weapName=(*it)->getArgument(2)->getStringValue();
|
||||
|
||||
bool countKill=true;
|
||||
|
||||
//gotta account for timer/infection double kills for medics!
|
||||
if (weapName=="infection")
|
||||
{
|
||||
//test to see if the previous event was a timer from the same player, and a kill, and with the timer.
|
||||
CEventListIterator it2=it;
|
||||
if ((--it2)!=plogfile->begin())
|
||||
{
|
||||
if ((*it2)->getType() == CLogEvent::FRAG)
|
||||
if ((*it2)->getArgument(2)->getStringValue()=="timer")
|
||||
if ((*it2)->getArgument(0)->asPlayerGetPID()==killerid)
|
||||
countKill=false;
|
||||
}
|
||||
}
|
||||
if (countKill)
|
||||
{
|
||||
|
||||
players[killerid].perteam[killerTeam].weaponKills[weapName]++;
|
||||
players[killerid].perteam[killerTeam].kills++;
|
||||
players[killedid].perteam[killedTeam].deaths++;
|
||||
}
|
||||
}
|
||||
|
||||
//keep the pseudonym list updated
|
||||
players[killerid].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
players[killedid].nameFound(curr->getTime(),curr->getArgument(1)->asPlayerGetName());
|
||||
|
||||
}
|
||||
break;
|
||||
case CLogEvent::TEAM_JOIN:
|
||||
{
|
||||
int team=curr->getArgument(1)->getFloatValue();
|
||||
team--; //teams are logged as 1-4. tfstats stores them as 0-3
|
||||
PID pid=curr->getArgument(0)->asPlayerGetPID();
|
||||
|
||||
|
||||
CPlayer& p=players[pid];
|
||||
team_exists[team]=true;
|
||||
|
||||
int oldteam=team;
|
||||
if(p.teams.anythingAtTime(curr->getTime()-1))
|
||||
oldteam=p.teams.atTime(curr->getTime()-1);
|
||||
else //if this is the first team join, count them as in the game
|
||||
players[pid].logontime=curr->getTime();
|
||||
|
||||
//keep the pseudonym list updated
|
||||
players[pid].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
|
||||
players[pid].teams.add(curr->getTime(),team);
|
||||
|
||||
if (p.allclassesplayed.anythingAtTime(curr->getTime()))
|
||||
{
|
||||
player_class plrcurrclass=players[pid].allclassesplayed.atTime(curr->getTime());
|
||||
players[pid].perteam[oldteam].classesplayed.cut(curr->getTime());
|
||||
players[pid].perteam[team].classesplayed.add(curr->getTime(),plrcurrclass);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CLogEvent::TEAM_RENAME:
|
||||
{
|
||||
int teamid=curr->getArgument(0)->getFloatValue()-1;
|
||||
string tname=curr->getArgument(1)->getStringValue();
|
||||
teamnames[teamid]=tname;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLogEvent::SERVER_NAME:
|
||||
{
|
||||
servername=curr->getArgument(0)->getStringValue();
|
||||
}
|
||||
break;
|
||||
case CLogEvent::SERVER_SPAWN:
|
||||
{
|
||||
mapname=curr->getArgument(0)->getStringValue();
|
||||
}
|
||||
break;
|
||||
case CLogEvent::DISCONNECT:
|
||||
{
|
||||
PID pid=curr->getArgument(0)->asPlayerGetPID();
|
||||
players[pid].logofftime=curr->getTime();
|
||||
players[pid].allclassesplayed.endTime=curr->getTime();
|
||||
players[pid].allclassesplayed.cut(curr->getTime());
|
||||
players[pid].teams.cut(curr->getTime());
|
||||
players[pid].aliases.cut(curr->getTime());
|
||||
|
||||
int currTeam=players[pid].teams.atTime(curr->getTime());
|
||||
players[pid].perteam[currTeam].classesplayed.cut(curr->getTime());
|
||||
|
||||
//keep the pseudonym list updated
|
||||
if (pid!=-1) //sometimes disconnect messages have -1 for the pid
|
||||
players[pid].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
|
||||
}
|
||||
break;
|
||||
case CLogEvent::NAMED_BROADCAST:
|
||||
{
|
||||
//keep the pseudonym list updated
|
||||
const CLogEventArgument* pArg=curr->getArgument(1);
|
||||
PID pid=pArg->asPlayerGetPID();
|
||||
players[pid].nameFound(curr->getTime(),curr->getArgument(1)->asPlayerGetName());
|
||||
}
|
||||
break;
|
||||
case CLogEvent::NAMED_GOAL_ACTIVATE:
|
||||
{
|
||||
//keep the pseudonym list updated
|
||||
players[curr->getArgument(0)->asPlayerGetPID()].nameFound(curr->getTime(),curr->getArgument(0)->asPlayerGetName());
|
||||
}
|
||||
break;
|
||||
case CLogEvent::LOG_CLOSED:
|
||||
{
|
||||
logclosetime=curr->getTime();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef _PARSEDEBUG
|
||||
|
||||
printf("%s:\n",CLogEvent::TypeNames[(int)curr->getType()]);
|
||||
fflush(stdout);
|
||||
printf("\t%s\n",curr->m_StrippedText);
|
||||
fflush(stdout);
|
||||
for (int i=0;curr->getArgument(i);i++)
|
||||
{
|
||||
if (i==0)
|
||||
printf("\t\targs: ");
|
||||
fflush(stdout);
|
||||
printf("\"%s\" ",curr->getArgument(i)->getStringValue());
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (logclosetime==0 && !plogfile->empty())
|
||||
{
|
||||
CEventListIterator it=plogfile->end();
|
||||
--it;
|
||||
logclosetime=(*it)->getTime();
|
||||
}
|
||||
|
||||
map<PID,CPlayer>::iterator it2;
|
||||
for(it2=players.begin();it2!=players.end();++it2)
|
||||
{
|
||||
CPlayer& p=(*it2).second;
|
||||
|
||||
|
||||
if (p.aliases.endTime < logclosetime)
|
||||
p.aliases.endTime=logclosetime;
|
||||
|
||||
p.name=p.aliases.favourite();
|
||||
|
||||
if (p.allclassesplayed.endTime < logclosetime)
|
||||
p.allclassesplayed.endTime=logclosetime;
|
||||
|
||||
if (p.teams.endTime < logclosetime)
|
||||
p.teams.endTime=logclosetime;
|
||||
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
//if you have no kills you have to play on a team at least 30 seconds to be counted part of it
|
||||
//also give a one-suicide grace so they can killthemselves to get onto another team?
|
||||
if (p.teams.howLong(i) < 30 && p.perteam[i].kills==0)// && p.perteam[i].deaths < 1)
|
||||
p.teams.remove(i);
|
||||
|
||||
CTimeIndexedList<player_class>* v= &p.perteam[i].classesplayed;
|
||||
p.perteam[i].classesplayed.endTime=logclosetime;
|
||||
|
||||
time_t t=p.teams.howLong(i);
|
||||
p.perteam[i].timeon=t;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CMatchInfo::getPlayerID
|
||||
// Purpose: resolves a player name to that players PID
|
||||
// Input: name - the name
|
||||
// Output: PID the PID
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
PID CMatchInfo::getPlayerID(string name)
|
||||
{
|
||||
CPlayerListIterator it;
|
||||
|
||||
//ugh! O(n)
|
||||
for (it=playerBegin();it!=playerEnd();++it)
|
||||
{
|
||||
PID id=(*it).first;
|
||||
CPlayer curr=(*it).second;
|
||||
|
||||
if (curr.name == name)
|
||||
return id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
unsigned long CMatchInfo::getPlayerWONID(string name)
|
||||
{
|
||||
CPlayerListIterator it;
|
||||
|
||||
//ugh! O(n)
|
||||
for (it=playerBegin();it!=playerEnd();++it)
|
||||
{
|
||||
CPlayer curr=(*it).second;
|
||||
|
||||
if (curr.name == name)
|
||||
return curr.WONID;
|
||||
}
|
||||
return 0xffffffff;
|
||||
}
|
||||
*/
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CMatchInfo::CMatchInfo
|
||||
// Purpose: Constructor
|
||||
// Input: plf - the log file
|
||||
// Output:
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
CMatchInfo::CMatchInfo(CEventList* plf)
|
||||
:numPlrs(0),logclosetime(0),plogfile(plf)
|
||||
{
|
||||
teamnames[0]="Blue";
|
||||
teamnames[1]="Red";
|
||||
teamnames[2]="Yellow";
|
||||
teamnames[3]="Green";
|
||||
team_exists[0]=team_exists[1]=team_exists[2]=team_exists[3]=false;
|
||||
|
||||
|
||||
generate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CMatchInfo::teamID
|
||||
// Purpose: resolves a team name to its ID
|
||||
// Input: teamname - the team name
|
||||
// Output: int the ID of the team
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
int CMatchInfo::teamID(string teamname)
|
||||
{
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
if (stricmp(teamname.c_str(),teamnames[i].c_str())==0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CMatchInfo::getTimeOn
|
||||
// Purpose: returns how long the specified player has been playing
|
||||
// Input: pid - the player being queried
|
||||
// Output: time_t the time he/she played
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
time_t CMatchInfo::getTimeOn(PID pid)
|
||||
{
|
||||
CPlayer& p=players[pid];
|
||||
|
||||
if (p.logofftime==0)
|
||||
p.logofftime=logclosetime;
|
||||
|
||||
time_t timeon=p.logofftime-p.logontime;
|
||||
|
||||
return timeon;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CMatchInfo
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#pragma warning(disable:4786)
|
||||
#ifndef MATCHINFO_H
|
||||
#define MATCHINFO_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "EventList.h"
|
||||
#include "util.h"
|
||||
#include "player.h"
|
||||
#include "time.h"
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CMatchInfo is a collection of data gleaned from the logfile. An
|
||||
// instance of this class contains info that many different report elements and
|
||||
// awards use, such as player names, teams, and things like that.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CMatchInfo
|
||||
{
|
||||
private:
|
||||
CPlayerList players;
|
||||
public:
|
||||
CPlayerListIterator playerBegin(){return players.begin();}
|
||||
CPlayerListIterator playerEnd(){return players.end();}
|
||||
|
||||
CPlayerList& playerList(){return players;}
|
||||
private:
|
||||
string teamnames[MAX_TEAMS];
|
||||
bool team_exists[MAX_TEAMS];
|
||||
string servername;
|
||||
string mapname;
|
||||
|
||||
|
||||
|
||||
int numPlrs;
|
||||
time_t logclosetime;
|
||||
time_t logopentime;
|
||||
CEventList* plogfile;
|
||||
bool bLanGame;
|
||||
|
||||
public:
|
||||
|
||||
explicit CMatchInfo(CEventList* plf);
|
||||
|
||||
bool isLanGame(){return bLanGame;}
|
||||
|
||||
void generate();
|
||||
CEventList* eventList(){return plogfile;}
|
||||
|
||||
int numPlayers(){return numPlrs;}
|
||||
string mapName(){return mapname;}
|
||||
|
||||
|
||||
char* playerName(PID pid,char* out){if (pid==1) return "PID=-1!"; strcpy(out,players[pid].name.c_str());return out;}
|
||||
string playerName(PID pid){return pid==-1?string("PID=-1!"):players[pid].name;}
|
||||
|
||||
PID getPlayerID(string name);
|
||||
//unsigned int getPlayerWONID(string name);
|
||||
|
||||
|
||||
//unsigned int getPlayerWONID(PID pid){return players[pid].WONID;}
|
||||
|
||||
//int playerTeamID(PID p){return players[p].team;}
|
||||
|
||||
string teamName(int TID){return teamnames[TID];}
|
||||
int teamID(string teamname);
|
||||
bool teamExists(int tid){return team_exists[tid];}
|
||||
|
||||
string getServerName(){return servername;}
|
||||
|
||||
time_t getTimeOn(PID pid);
|
||||
time_t logCloseTime(){return logclosetime;}
|
||||
time_t logOpenTime(){return logopentime;}
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern CMatchInfo* g_pMatchInfo;
|
||||
|
||||
#endif // MATCHINFO_H
|
||||
@@ -0,0 +1,227 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "MatchResults.h"
|
||||
|
||||
void CMatchResults::init()
|
||||
{
|
||||
memset(teams,0,sizeof(team)*MAX_TEAMS);
|
||||
memset(loserString,0,STRLEN);
|
||||
memset(winnerString,0,STRLEN);
|
||||
valid=false;
|
||||
draw=false;
|
||||
numTeams=0;
|
||||
}
|
||||
|
||||
void CMatchResults::generate()
|
||||
{
|
||||
CEventListIterator it=g_pMatchInfo->eventList()->end();
|
||||
--it;
|
||||
|
||||
for (it=g_pMatchInfo->eventList()->begin();it!=g_pMatchInfo->eventList()->end();++it)
|
||||
{
|
||||
|
||||
if ((*it)->getType()==CLogEvent::MATCH_RESULTS_MARKER)
|
||||
valid=true;
|
||||
|
||||
else if ((*it)->getType()==CLogEvent::MATCH_DRAW)
|
||||
{
|
||||
draw=true;
|
||||
}
|
||||
|
||||
else if ((*it)->getType()==CLogEvent::MATCH_VICTOR)
|
||||
{
|
||||
//winning teams are recited first, then losing teams. so start in "winning" mode
|
||||
bool fWinMode=true;
|
||||
|
||||
char eventText[200];
|
||||
strcpy(eventText,(*it)->getFullMessage());
|
||||
|
||||
char seps[] = " \n\t";
|
||||
char *token;
|
||||
|
||||
token = strtok( eventText, seps );
|
||||
while( token != NULL )
|
||||
{
|
||||
if (stricmp(token,"defeated")==0)
|
||||
fWinMode=false;
|
||||
|
||||
else if (token[0]=='\"')
|
||||
{
|
||||
//found a team name
|
||||
//depending on win/lose mode, assign that team appropriately
|
||||
token++; //advance past the first quote
|
||||
char* quote2=strchr(token,'\"');
|
||||
*quote2='\0'; //null out the second quote;
|
||||
|
||||
//get team ID
|
||||
int tID=g_pMatchInfo->teamID(token);
|
||||
teams[tID].fWinner=fWinMode;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
//Get next token
|
||||
token = strtok( NULL, seps );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if ((*it)->getType()==CLogEvent::MATCH_TEAM_RESULTS)
|
||||
{
|
||||
int team=g_pMatchInfo->teamID((*it)->getArgument(0)->getStringValue());
|
||||
teams[team].valid=true;
|
||||
teams[team].numplayers=(*it)->getArgument(1)->getFloatValue();
|
||||
teams[team].frags=(*it)->getArgument(2)->getFloatValue();
|
||||
teams[team].unacc_frags=(*it)->getArgument(3)->getFloatValue();
|
||||
teams[team].score=(*it)->getArgument(4)->getFloatValue();
|
||||
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
teams[team].allies[i]= (i==team); //initially set team to be allied with itself.
|
||||
}
|
||||
//get allies
|
||||
i=5;
|
||||
CLogEventArgument const * pArg=(*it)->getArgument(i++);
|
||||
while(pArg)
|
||||
{
|
||||
int ally=pArg->getFloatValue()-1;
|
||||
teams[team].allies[ally]=true;
|
||||
teams[ally].allies[team]=true; //one sided alliances don't exist.
|
||||
pArg=(*it)->getArgument(i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
char* CMatchResults::getWinnerTeamsString()
|
||||
{
|
||||
bool firstWinner=true;
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
if (teams[i].valid && teams[i].fWinner)
|
||||
{
|
||||
if (!firstWinner)
|
||||
strcat(winnerString," and ");
|
||||
strcat(winnerString,g_pMatchInfo->teamName(i).c_str());
|
||||
firstWinner=false;
|
||||
}
|
||||
}
|
||||
return winnerString;
|
||||
}
|
||||
|
||||
int CMatchResults::getWinnerTeamScore()
|
||||
{
|
||||
if (draw)
|
||||
return teams[0].score;
|
||||
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
if (teams[i].valid && teams[i].fWinner)
|
||||
return teams[i].score;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMatchResults::calcRealWinners()
|
||||
{
|
||||
//first find the highest score.
|
||||
int maxScoreTeam=0;
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
teams[i].fWinner=false;
|
||||
if (teams[i].score > teams[maxScoreTeam].score)
|
||||
maxScoreTeam=i;
|
||||
}
|
||||
|
||||
//mark that team as a winner, then mark all their allies as winners
|
||||
teams[maxScoreTeam].fWinner=true;
|
||||
for (int j=0;j<MAX_TEAMS;j++)
|
||||
{
|
||||
if (teams[maxScoreTeam].allies[j])
|
||||
teams[j].fWinner=true;
|
||||
}
|
||||
}
|
||||
|
||||
char* CMatchResults::getLoserTeamsString()
|
||||
{
|
||||
bool firstLoser=true;
|
||||
|
||||
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
if (teams[i].valid && !teams[i].fWinner)
|
||||
{
|
||||
if (!firstLoser)
|
||||
strcat(loserString," and ");
|
||||
strcat(loserString,g_pMatchInfo->teamName(i).c_str());
|
||||
firstLoser=false;
|
||||
}
|
||||
}
|
||||
return loserString;
|
||||
}
|
||||
|
||||
int CMatchResults::getLoserTeamScore()
|
||||
{
|
||||
if (draw)
|
||||
return teams[0].score;
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
if (teams[i].valid && !teams[i].fWinner)
|
||||
return teams[i].score;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CMatchResults::Outnumbered(int WinnerOrLoser)
|
||||
{
|
||||
int losers=0;
|
||||
int winners=0;
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
if (teams[i].fWinner)
|
||||
winners+=teams[i].numplayers;
|
||||
else
|
||||
losers+=teams[i].numplayers;
|
||||
}
|
||||
|
||||
if (WinnerOrLoser == WINNER)
|
||||
return losers > winners;
|
||||
else
|
||||
return losers < winners;
|
||||
}
|
||||
|
||||
int CMatchResults::numWinningTeams()
|
||||
{
|
||||
int num=0;
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
if (teams[i].fWinner) num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
void CMatchResults::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
calcRealWinners(); //deal with logging bug in DLL
|
||||
html.write("<div class=headline>\n");
|
||||
|
||||
if (!valid)
|
||||
html.write("No winner has been determined.");
|
||||
else if (!draw)
|
||||
{
|
||||
bool fOutnumbered=false;
|
||||
bool winPlural=numWinningTeams()==1;
|
||||
|
||||
html.write("%s %s! They scored %li points to %s's %li\n",getWinnerTeamsString(),winPlural?"wins":"win",getWinnerTeamScore(),getLoserTeamsString(),getLoserTeamScore());
|
||||
}
|
||||
else
|
||||
html.write("The match ends in a draw! <br> All teams scored %li \n",getWinnerTeamScore());
|
||||
|
||||
|
||||
html.write("</div>");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "report.h"
|
||||
|
||||
class CMatchResults: public CReport
|
||||
{
|
||||
public:
|
||||
enum Consts
|
||||
{
|
||||
WINNER=1,
|
||||
LOSER=0,
|
||||
|
||||
STRLEN=200,
|
||||
};
|
||||
private:
|
||||
struct team
|
||||
{
|
||||
bool valid;
|
||||
int score;
|
||||
int frags;
|
||||
int unacc_frags;
|
||||
int numplayers;
|
||||
bool fWinner;
|
||||
bool allies[MAX_TEAMS];
|
||||
};
|
||||
|
||||
team teams[MAX_TEAMS];
|
||||
int numTeams;
|
||||
char winnerString[STRLEN];
|
||||
char loserString[STRLEN];
|
||||
|
||||
bool valid;
|
||||
bool draw;
|
||||
|
||||
void init();
|
||||
|
||||
void calcRealWinners();
|
||||
|
||||
char* getWinnerTeamsString();
|
||||
int getWinnerTeamScore();
|
||||
bool Outnumbered(int WinnerOrLoser);
|
||||
char* getLoserTeamsString();
|
||||
int getLoserTeamScore();
|
||||
int numWinningTeams();
|
||||
|
||||
public:
|
||||
|
||||
explicit CMatchResults(){init();}
|
||||
|
||||
void generate();
|
||||
void writeHTML(CHTMLFile& html);
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: code to track allocations via replacing the global new operator
|
||||
// some of this code was written by Paul Andre LeBlanc
|
||||
// <paul.a.leblanc@sympatico.ca> I got it off of dejanews.com
|
||||
// usage: new TRACKED object-type
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include <new.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream.h>
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef _MEMDEBUG
|
||||
#define _MDEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MDEBUG
|
||||
static int numBytesAllocated=0;
|
||||
//these were written by me, wes cumberland, not paul andre leblanc
|
||||
void * operator new(size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
numBytesAllocated+=size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void * operator new[](size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
numBytesAllocated+=size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
//this code will track allocations
|
||||
//this code was written by Paul Andre LeBlanc <paul.a.leblanc@sympatico.ca>
|
||||
//I got it off of dejanews.com
|
||||
void *operator new(size_t size, const char *file, const int line)
|
||||
{
|
||||
void *ptr = new char[size];
|
||||
numBytesAllocated+=size;
|
||||
cout << "new: Allocating " << size << " bytes in file " << file << ", line " << line << ", address is " << ptr << " (" << numBytesAllocated<<" total allocated)"<< endl;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *operator new[](size_t size, const char *file, const int line) {
|
||||
void *ptr = new char[size];
|
||||
numBytesAllocated+=size;
|
||||
cout << "new[]: Allocating " << size << " bytes in file " << file << ", line " << line << ", address is " << ptr << " (" << numBytesAllocated<<" total allocated)" << endl;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void *ptr, const char *file, const int line) {
|
||||
cout << "delete: Freeing memory allocated at file " << file << ", line " << line << ", address is " << ptr << endl;
|
||||
delete [] (char *) ptr;
|
||||
}
|
||||
|
||||
void operator delete[](void *ptr, const char *file, const int line)
|
||||
{
|
||||
cout << "delete[]: Freeing memory allocated at file " << file << ", line " << line << ", address is " << ptr << endl;
|
||||
delete [] (char *) ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: TFStats_win32_new_handler
|
||||
// Purpose: this function will be called if TFStats runs out of memory (unlikely)
|
||||
// this is a win32 specific version, the linux version does not pass an argument
|
||||
// Input: sz - the size of the allocation that failed
|
||||
// Output: int
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
int TFStats_win32_new_handler(size_t sz)
|
||||
{
|
||||
printf("TFStats ran out of memory trying to allocate %li bytes\n",sz);
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: TFStats_linux_new_handler
|
||||
// Purpose: this function will be called if TFStats runs out of memory (unlikely)
|
||||
// this is a linux specific version, the win32 version passes an argument
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void TFStats_linux_new_handler(void)
|
||||
{
|
||||
printf("TFStats ran out of memory!\n");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: TFStats_setNewHandler
|
||||
// Purpose: sets the new handler to the TFStats new handler
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void TFStats_setNewHandler()
|
||||
{
|
||||
#ifdef WIN32
|
||||
_set_new_handler(TFStats_win32_new_handler);
|
||||
_set_new_mode(1);
|
||||
#else
|
||||
std::set_new_handler(TFStats_linux_new_handler);
|
||||
//std::set_new_mode(1);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: declarations to track allocations via replacing the global new operator
|
||||
// some of this code was written by Paul Andre LeBlanc
|
||||
// <paul.a.leblanc@sympatico.ca> I got it off of dejanews.com
|
||||
// usage: new TRACKED object-type
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef MEMDBG_H
|
||||
#define MEMDBG_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef _MEMDEBUG
|
||||
#define _MDEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MDEBUG
|
||||
#define TRACKED (__FILE__, __LINE__)
|
||||
#else
|
||||
#define TRACKED
|
||||
#endif
|
||||
|
||||
#ifdef _MDEBUG
|
||||
void *operator new(size_t size, const char *file, const int line);
|
||||
void *operator new[](size_t size, const char *file, const int line);
|
||||
void operator delete(void *ptr, const char *file, const int line);
|
||||
void operator delete[](void *ptr, const char *file, const int line);
|
||||
|
||||
|
||||
//replacing global new for debugging purposes.
|
||||
//these were written by me, wes cumberland, not paul andre leblanc
|
||||
void* operator new(size_t size);
|
||||
void* operator new[](size_t size);
|
||||
void operator delete(void* v);
|
||||
void operator delete[](void* v);
|
||||
#endif
|
||||
|
||||
//leave this in, even for release build
|
||||
int TFStats_win32_new_handler(size_t sz);
|
||||
void TFStats_linux_new_handler(void);
|
||||
|
||||
void TFStats_setNewHandler();
|
||||
|
||||
#endif // MEMDBG_H
|
||||
@@ -0,0 +1,11 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "pid.h"
|
||||
#include <map>
|
||||
|
||||
std::map<int,PID> pidMap;
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: interface and implementation of PID.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef PID_H
|
||||
#define PID_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
typedef unsigned long PID;
|
||||
#include <map>
|
||||
extern std::map<int,PID> pidMap;
|
||||
#endif // PID_H
|
||||
@@ -0,0 +1,129 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#pragma warning (disable:4786)
|
||||
#include <string>
|
||||
|
||||
#include "Player.h"
|
||||
#include "MatchInfo.h"
|
||||
using namespace std;
|
||||
|
||||
|
||||
CPlayer::CPlayer()
|
||||
:teams()
|
||||
{
|
||||
WONID=pid=svrPID=-1;
|
||||
logontime=logofftime=reconnects=0;
|
||||
name="uninitted";
|
||||
}
|
||||
|
||||
void CPlayer::nameFound(time_t t, string alias)
|
||||
{
|
||||
if (aliases.atTime(t)!=alias)
|
||||
{
|
||||
aliases.add(t,alias);
|
||||
}
|
||||
name=aliases.favourite();
|
||||
}
|
||||
|
||||
time_t CPlayer::plr_per_team_data::timeOn()
|
||||
{
|
||||
/*if (logofftime==0)
|
||||
{
|
||||
logofftime=g_pMatchInfo->logCloseTime();
|
||||
}
|
||||
|
||||
return logofftime-logontime;
|
||||
*/
|
||||
return timeon;
|
||||
}
|
||||
time_t CPlayer::totalTimeOn()
|
||||
{
|
||||
if (logofftime==0)
|
||||
{
|
||||
logofftime=g_pMatchInfo->logCloseTime();
|
||||
}
|
||||
|
||||
return logofftime-logontime;
|
||||
}
|
||||
|
||||
|
||||
double CPlayer::plr_per_team_data::rank()
|
||||
{
|
||||
double d = (kills-deaths);
|
||||
double time=((double)timeOn())/1000.0;
|
||||
|
||||
if (time < .000001)
|
||||
return d;
|
||||
|
||||
return d/time;
|
||||
}
|
||||
|
||||
|
||||
string CPlayer::plr_per_team_data::faveWeapon()
|
||||
{
|
||||
if (faveweapon=="" && weaponKills.begin()!=weaponKills.end())
|
||||
{
|
||||
faveweapkills=0;
|
||||
//noKills=false;
|
||||
|
||||
map<string,int>::iterator weapIt=weaponKills.begin();
|
||||
string& fave=(string&) (*weapIt).first;
|
||||
int faveKills=(*weapIt).second;
|
||||
|
||||
for (weapIt;weapIt!=weaponKills.end();++weapIt)
|
||||
{
|
||||
const string& weapName=(*weapIt).first;
|
||||
int kills=(*weapIt).second;
|
||||
|
||||
if (kills < faveKills)
|
||||
continue;
|
||||
|
||||
fave=weapName;
|
||||
faveKills=kills;
|
||||
}
|
||||
|
||||
faveweapkills=faveKills;
|
||||
faveweapon=fave;
|
||||
}
|
||||
|
||||
return faveweapon;
|
||||
}
|
||||
|
||||
int CPlayer::plr_per_team_data::faveWeapKills()
|
||||
{
|
||||
if (faveweapkills==0)
|
||||
{
|
||||
//calculate favourite weapon stats
|
||||
faveWeapon();
|
||||
}
|
||||
return faveweapkills;
|
||||
}
|
||||
|
||||
void CPlayer::merge()
|
||||
{
|
||||
perteam[ALL_TEAMS].kills=perteam[0].kills+perteam[1].kills+perteam[2].kills+perteam[3].kills;
|
||||
perteam[ALL_TEAMS].deaths=perteam[0].deaths+perteam[1].deaths+perteam[2].deaths+perteam[3].deaths;
|
||||
perteam[ALL_TEAMS].suicides=perteam[0].suicides+perteam[1].suicides+perteam[2].suicides+perteam[3].suicides;
|
||||
perteam[ALL_TEAMS].teamkills=perteam[0].teamkills+perteam[1].teamkills+perteam[2].teamkills+perteam[3].teamkills;
|
||||
perteam[ALL_TEAMS].teamkilled=perteam[0].teamkilled+perteam[1].teamkilled+perteam[2].teamkilled+perteam[3].teamkilled;
|
||||
perteam[ALL_TEAMS].timeon=perteam[0].timeon+perteam[1].timeon+perteam[2].timeon+perteam[3].timeon;
|
||||
|
||||
|
||||
for (int i=0;i<MAX_TEAMS;i++)
|
||||
{
|
||||
map<std::string,int>::iterator it;
|
||||
for (it=perteam[i].weaponKills.begin();it!=perteam[i].weaponKills.end();++it)
|
||||
{
|
||||
string weapname=(*it).first;
|
||||
int kills=(*it).second;
|
||||
perteam[ALL_TEAMS].weaponKills[weapname]+=kills;
|
||||
}
|
||||
}
|
||||
//this is probably only a shallow copy, but that's ok
|
||||
perteam[ALL_TEAMS].classesplayed=allclassesplayed;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CPlayer
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#pragma warning (disable:4786)
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "TimeIndexedList.h"
|
||||
#include "pid.h"
|
||||
class CMatchInfo;
|
||||
|
||||
class CPlayer
|
||||
{
|
||||
public:
|
||||
struct plr_per_team_data
|
||||
{
|
||||
int kills;
|
||||
int deaths;
|
||||
int suicides;
|
||||
//double rank;
|
||||
int teamkills;
|
||||
int teamkilled;
|
||||
std::map<std::string,int> weaponKills;
|
||||
std::string faveweapon;
|
||||
int faveweapkills;
|
||||
double rank();
|
||||
std::string faveWeapon();
|
||||
int faveWeapKills();
|
||||
plr_per_team_data(){kills=deaths=suicides=teamkills=teamkilled=faveweapkills=0;}
|
||||
|
||||
CTimeIndexedList<player_class> classesplayed; //stores class, indexed by the time when that class was switched to.
|
||||
|
||||
time_t timeon;
|
||||
time_t timeOn();
|
||||
};
|
||||
|
||||
CTimeIndexedList<player_class> allclassesplayed; //stores class, indexed by the time when that class was switched to.
|
||||
|
||||
CTimeIndexedList<int> teams;
|
||||
plr_per_team_data perteam[MAX_TEAMS+1];
|
||||
|
||||
CTimeIndexedList<std::string> aliases;
|
||||
std::string name; //this will be set to the favourite name of the player
|
||||
//int team;
|
||||
int svrPID;
|
||||
unsigned long WONID;
|
||||
string ipAddress;
|
||||
int reconnects;
|
||||
|
||||
|
||||
PID pid;
|
||||
time_t logontime;
|
||||
time_t logofftime;
|
||||
time_t totalTimeOn();
|
||||
|
||||
|
||||
|
||||
|
||||
// int teamID(){return team;}
|
||||
CPlayer();
|
||||
|
||||
void nameFound(time_t t, std::string alias);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//merge stats from all teams into 5th "team" (all teams)
|
||||
void merge();
|
||||
};
|
||||
|
||||
#include "pid.h"
|
||||
typedef std::map<PID,CPlayer> CPlayerList;
|
||||
typedef CPlayerList::iterator CPlayerListIterator;
|
||||
|
||||
#endif // PLAYER_H
|
||||
@@ -0,0 +1,263 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CPlayerReport;
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "util.h"
|
||||
#include "PlayerReport.h"
|
||||
|
||||
#include "PlrPersist.h"
|
||||
|
||||
map<unsigned long,bool> CPlayerReport::alreadyPersisted;
|
||||
map<unsigned long,bool> CPlayerReport::alreadyWroteCombStats;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlayerReport::writeHTML
|
||||
// Purpose: writes the player's stats out as HTML
|
||||
// Input: html - the html file to which we're writing
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlayerReport::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
//if we're writing the stats for a persistent player, just pass execution off to that function!
|
||||
if (reportingPersistedPlayer)
|
||||
{
|
||||
writePersistHTML(html);
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->totalTimeOn(); //this ensures that the logoff time is correct
|
||||
|
||||
if (iWhichTeam==ALL_TEAMS)
|
||||
pPlayer->merge();
|
||||
else if (!pPlayer->teams.contains(iWhichTeam))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int tid=iWhichTeam;
|
||||
|
||||
if (tid==ALL_TEAMS)
|
||||
html.write("<font class=headline>%s</font><br>\n",pPlayer->name.c_str());
|
||||
else
|
||||
html.write("<font class=player%s2>%s</font><hr align=left width=60%%>\n",Util::teamcolormap[tid],pPlayer->name.c_str());
|
||||
|
||||
if (pPlayer->aliases.size() > 1)
|
||||
{
|
||||
map<string,bool> namePrinted;
|
||||
namePrinted[pPlayer->name.c_str()]=true;
|
||||
|
||||
html.write("<font class=whitetext>aliases:</font> <font class=awards2>");
|
||||
CTimeIndexedList<string>::iterator nmiter=pPlayer->aliases.begin();
|
||||
bool printed1=false;
|
||||
for (nmiter;nmiter!=pPlayer->aliases.end();++nmiter)
|
||||
{
|
||||
if (namePrinted[nmiter->data]!=true)
|
||||
{
|
||||
if (printed1)
|
||||
html.write(", ");
|
||||
html.write(nmiter->data.c_str());
|
||||
namePrinted[nmiter->data]=true;
|
||||
printed1=true;
|
||||
}
|
||||
}
|
||||
html.write("</font><br>\n");
|
||||
}
|
||||
|
||||
html.write("<font class=whitetext>rank:</font> <font class=awards2> %.2lf </font><br>\n",pPlayer->perteam[tid].rank());
|
||||
html.write("<font class=whitetext>kills/deaths:</font> <font class=awards2>%li/%li </font><br>\n",pPlayer->perteam[tid].kills,pPlayer->perteam[tid].deaths);
|
||||
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()));
|
||||
|
||||
|
||||
int numClassesPlayed=pPlayer->perteam[tid].classesplayed.numDifferent();
|
||||
player_class faveClass=pPlayer->perteam[tid].classesplayed.favourite();
|
||||
|
||||
if (numClassesPlayed == 1)
|
||||
{
|
||||
if (faveClass!=PC_UNDEFINED)
|
||||
html.write("<font class=whitetext>class:</font> <font class=awards2> %s </font><br>\n",plrClassNames[faveClass]);
|
||||
}
|
||||
else if (numClassesPlayed > 1)
|
||||
{
|
||||
if (faveClass!=PC_UNDEFINED)
|
||||
html.write("<font class=whitetext>favorite class:</font> <font class=awards2> %s </font><br>\n",plrClassNames[faveClass]);
|
||||
|
||||
html.write("<font class=whitetext>classes played:</font> <font class=awards2> ");
|
||||
bool printedone=false;
|
||||
for(int pc=PC_SCOUT;pc!=PC_OBSERVER;++pc)
|
||||
{
|
||||
if (pPlayer->perteam[tid].classesplayed.contains((player_class)pc))
|
||||
{
|
||||
if (printedone)
|
||||
html.write(", ");
|
||||
|
||||
html.write(plrClassNames[pc]);
|
||||
printedone=true;
|
||||
}
|
||||
}
|
||||
html.write(" </font><br>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
const string weap=pPlayer->perteam[tid].faveWeapon();
|
||||
const string faveWeap=Util::getFriendlyWeaponName(weap);
|
||||
if (pPlayer->perteam[tid].kills!=0)
|
||||
{
|
||||
char lowerWeapName[50];
|
||||
Util::str2lowercase(lowerWeapName,faveWeap.c_str());
|
||||
html.write("<font class=whitetext>favorite weapon:</font> <font class=awards2> %s</font><br>\n",faveWeap.c_str());
|
||||
html.write("<font class=whitetext>kills with %s:</font> <font class=awards2> %li</font><br>\n",lowerWeapName,pPlayer->perteam[tid].faveWeapKills());
|
||||
}
|
||||
|
||||
|
||||
int numTeamsPlayed=pPlayer->teams.numDifferent();
|
||||
|
||||
if (numTeamsPlayed > 1)
|
||||
{
|
||||
if (iWhichTeam==ALL_TEAMS)
|
||||
html.write("<font class=whitetext>Played on</font> <font class=whitetext> ");
|
||||
else
|
||||
html.write("<font class=whitetext>Also played on</font> <font class=whitetext> ");
|
||||
|
||||
map<int,bool> alreadyPrinted;
|
||||
CTimeIndexedList<int>::iterator tmiter=pPlayer->teams.begin();
|
||||
bool printed1=false;
|
||||
for (tmiter;tmiter!=pPlayer->teams.end();++tmiter)
|
||||
{
|
||||
int team=tmiter->data;
|
||||
if (team != iWhichTeam && !alreadyPrinted[team])
|
||||
{
|
||||
if (printed1)
|
||||
html.write(" and ");
|
||||
html.write("<font class=player%s>%s</font>",Util::teamcolormap[team],Util::teamcolormap[team]);//
|
||||
printed1=true;
|
||||
alreadyPrinted[team]=true;
|
||||
}
|
||||
}
|
||||
html.write("</font><br>\n");
|
||||
}
|
||||
|
||||
if (numTeamsPlayed > 1 && iWhichTeam != ALL_TEAMS)
|
||||
{
|
||||
html.write("<a class=whitetext href=\"%lu.html\"> <u> Combined stats for this match </u> </a> <br> \n",pPlayer->pid);
|
||||
|
||||
if (!alreadyWroteCombStats[pPlayer->pid])
|
||||
{
|
||||
CPlayerReport cpr(pPlayer,ALL_TEAMS);
|
||||
char numbuf[200];
|
||||
char namebuf[200];
|
||||
sprintf(numbuf,"%lu.html",pPlayer->pid);
|
||||
sprintf(namebuf,"Combined match statistics for %s",pPlayer->name.c_str());
|
||||
cpr.makeHTMLPage(numbuf,namebuf);
|
||||
alreadyWroteCombStats[pPlayer->pid]=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pApp->cmdLineSwitches["persistplayerstats"]=="yes" && !g_pMatchInfo->isLanGame())
|
||||
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());
|
||||
|
||||
if (g_pMatchInfo->isLanGame())
|
||||
return;
|
||||
if (alreadyPersisted[pPlayer->WONID] || reportingPersistedPlayer)
|
||||
return;
|
||||
|
||||
alreadyPersisted[pPlayer->WONID]=true;
|
||||
|
||||
if (g_pApp->cmdLineSwitches["persistplayerstats"]=="yes")
|
||||
{
|
||||
CPlrPersist cpp;
|
||||
CPlrPersist onDisk;
|
||||
cpp.generate(*pPlayer);
|
||||
onDisk.read(pPlayer->WONID);
|
||||
cpp.merge(onDisk);
|
||||
cpp.write();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlayerReport::writePersistHTML
|
||||
// Purpose: writes a persistent player's stats out. these look slightly different
|
||||
// than normal players stats
|
||||
// Input: html - the html file to write the html to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlayerReport::writePersistHTML(CHTMLFile& html)
|
||||
{
|
||||
html.write("<a name=\"%lu\">\n",pPersist->WONID);
|
||||
html.write("<font class=headline2>%s</font><hr align=left width=60%%>\n",pPersist->faveName().c_str());
|
||||
|
||||
|
||||
map<string,bool> namePrinted;
|
||||
namePrinted[pPersist->faveName()]=true;
|
||||
|
||||
map<string,int>::iterator nmiter=pPersist->nickmap.begin();
|
||||
bool printed1=false;
|
||||
for (nmiter;nmiter!=pPersist->nickmap.end();++nmiter)
|
||||
{
|
||||
if (namePrinted[nmiter->first]!=true)
|
||||
{
|
||||
if (!printed1)
|
||||
html.write("<font class=whitetext>other names used:</font> <font class=awards2>");
|
||||
if (printed1)
|
||||
html.write(", ");
|
||||
html.write(nmiter->first.c_str());
|
||||
namePrinted[nmiter->first]=true;
|
||||
printed1=true;
|
||||
}
|
||||
}
|
||||
if (printed1)
|
||||
html.write("</font><br>\n");
|
||||
|
||||
|
||||
|
||||
html.write("<font class=whitetext>rank:</font> <font class=awards2> %.2lf </font><br>\n",pPersist->rank());
|
||||
html.write("<font class=whitetext>kills/deaths:</font> <font class=awards2>%li/%li </font><br>\n",pPersist->kills,pPersist->deaths);
|
||||
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));
|
||||
html.write("<font class=whitetext>matches played:</font> <font class=awards2> %li </font><br>\n",pPersist->matches);
|
||||
|
||||
|
||||
string faveClass=pPersist->faveClass();
|
||||
if (faveClass!="Undefined")
|
||||
html.write("<font class=whitetext>favorite class:</font> <font class=awards2> %s </font><br>\n",faveClass.c_str());
|
||||
|
||||
|
||||
bool printedone=false;
|
||||
map<string,int>::iterator classit=pPersist->classmap.begin();
|
||||
map<string,bool> classPrinted;
|
||||
classPrinted[pPersist->faveClass()]=true;
|
||||
for(classit;classit!=pPersist->classmap.end();++classit)
|
||||
{
|
||||
if (classPrinted[classit->first]==false)
|
||||
{
|
||||
if (!printedone)
|
||||
html.write("<font class=whitetext>other classes played:</font> <font class=awards2> ");
|
||||
if (printedone)
|
||||
html.write(", ");
|
||||
html.write(classit->first.c_str());
|
||||
classPrinted[classit->first]=true;
|
||||
printedone=true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (printedone)
|
||||
html.write(" </font><br>\n");
|
||||
|
||||
const string weap=pPersist->faveWeap();
|
||||
const string faveWeap=Util::getFriendlyWeaponName(weap);
|
||||
if (pPersist->kills!=0)
|
||||
{
|
||||
char lowerWeapName[50];
|
||||
Util::str2lowercase(lowerWeapName,faveWeap.c_str());
|
||||
html.write("<font class=whitetext>favorite weapon:</font> <font class=awards2> %s</font><br>\n",faveWeap.c_str());
|
||||
html.write("<font class=whitetext>kills with %s:</font> <font class=awards2> %li</font><br>\n",lowerWeapName,pPersist->faveweapkills);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface of CPlayerReport
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef PLAYERREPORT_H
|
||||
#define PLAYERREPORT_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "Player.h"
|
||||
#include "Report.h"
|
||||
#include "PlrPersist.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: Reports a specific player's stats.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CPlayerReport: public CReport
|
||||
{
|
||||
private:
|
||||
CPlayer* pPlayer;
|
||||
CPlrPersist* pPersist;
|
||||
int iWhichTeam;
|
||||
|
||||
static map<unsigned long,bool> alreadyPersisted;
|
||||
static map<unsigned long,bool> alreadyWroteCombStats;
|
||||
bool reportingPersistedPlayer;
|
||||
|
||||
void writePersistHTML(CHTMLFile& html);
|
||||
public:
|
||||
CPlayerReport(CPlayer* pP,int t):pPlayer(pP),iWhichTeam(t){reportingPersistedPlayer=false;}
|
||||
CPlayerReport(CPlrPersist* pPP):pPersist(pPP) {iWhichTeam=-1;reportingPersistedPlayer=true;}
|
||||
|
||||
virtual void writeHTML(CHTMLFile& html);
|
||||
};
|
||||
|
||||
|
||||
#endif // PLAYERREPORT_H
|
||||
@@ -0,0 +1,96 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CPlayerSpecifics
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "PlayerSpecifics.h"
|
||||
#include "PlayerReport.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlayerSpecifics::init
|
||||
// Purpose: intializes the object
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlayerSpecifics::init()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlayerSpecifics::generate
|
||||
// Purpose: generates intermediate data from match info
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlayerSpecifics::generate()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlayerSpecifics::writeHTML
|
||||
// Purpose: writes out html based on the intermediate data generated by generate()
|
||||
// Input: html - the html file to output to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlayerSpecifics::writeHTML(CHTMLFile& html)
|
||||
{
|
||||
int numteams=0;
|
||||
for (int t=0;t<MAX_TEAMS;t++)
|
||||
if (g_pMatchInfo->teamExists(t)) numteams++;
|
||||
|
||||
html.write("<table cols=%li cellspacing=0 border=0 cellpadding=10 bordercolor=black>\n",numteams);
|
||||
|
||||
CPlayerListIterator i;
|
||||
//multimap<double,CPlayer,greater<double> > ranksort;
|
||||
|
||||
//split playerlist into teams;
|
||||
multimap<double,CPlayer,greater<double> > rankedteams[MAX_TEAMS];
|
||||
|
||||
for (i=g_pMatchInfo->playerBegin();i!=g_pMatchInfo->playerEnd();++i)
|
||||
{
|
||||
PID pid=(*i).first;
|
||||
CPlayer p=(*i).second;
|
||||
for (int t=0;t<MAX_TEAMS;t++)
|
||||
{
|
||||
if (p.teams.contains(t))
|
||||
{
|
||||
double rank=p.perteam[t].rank();
|
||||
pair<double,CPlayer> insertme(rank,p);
|
||||
rankedteams[t].insert(insertme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(!rankedteams[0].empty() || !rankedteams[1].empty() || !rankedteams[2].empty() || !rankedteams[3].empty())
|
||||
{
|
||||
html.write("<tr>\n");
|
||||
int t;
|
||||
|
||||
for (t=0;t<MAX_TEAMS;t++)
|
||||
{
|
||||
if (!g_pMatchInfo->teamExists(t))
|
||||
continue;
|
||||
|
||||
html.write("<td width=250 valign=top>");
|
||||
|
||||
|
||||
if (rankedteams[t].begin()==rankedteams[t].end())
|
||||
continue;
|
||||
else
|
||||
{
|
||||
CPlayer& plr=(*(rankedteams[t].begin())).second;
|
||||
CPlayerReport cpr(&plr,t);
|
||||
cpr.writeHTML(html);
|
||||
rankedteams[t].erase(rankedteams[t].begin());
|
||||
//break;
|
||||
}
|
||||
html.write("</td>\n");
|
||||
}
|
||||
html.write("</tr>\n");
|
||||
}
|
||||
html.write("</table>");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface to CPlayerSpecifics
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef PLAYERSPECIFICS_H
|
||||
#define PLAYERSPECIFICS_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#pragma warning (disable: 4786)
|
||||
|
||||
#include "report.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CPlayerSpecifics is a whole page report element that reports specific
|
||||
// data about each player in the game. Data such as favourite weapon, rank,
|
||||
// classes played, favourite class, and kills vs deaths.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CPlayerSpecifics :public CReport
|
||||
{
|
||||
private:
|
||||
|
||||
void init();
|
||||
|
||||
|
||||
public:
|
||||
explicit CPlayerSpecifics(){init();}
|
||||
|
||||
void generate();
|
||||
void writeHTML(CHTMLFile& html);
|
||||
};
|
||||
|
||||
#endif // PLAYERSPECIFICS_H
|
||||
@@ -0,0 +1,419 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#pragma warning (disable:4786)
|
||||
#include "PlrPersist.h"
|
||||
#include "TextFile.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlrPersist::generate
|
||||
// Purpose: fills in the fields of this with the data in the given CPlayer object
|
||||
// Input: cp - the player object to get data from
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlrPersist::generate(CPlayer& cp)
|
||||
{
|
||||
kills=deaths=timeon=0;
|
||||
valid=true;
|
||||
WONID=cp.WONID;
|
||||
matches=1;
|
||||
|
||||
lastplayed=cp.logofftime;
|
||||
|
||||
//do perteam stuff
|
||||
CTimeIndexedList<int>::iterator teamiter=cp.teams.begin();
|
||||
for (teamiter;teamiter!=cp.teams.end();++teamiter)
|
||||
{
|
||||
int tdt=teamiter->data;
|
||||
kills+=cp.perteam[teamiter->data].kills;
|
||||
deaths+=cp.perteam[teamiter->data].deaths;
|
||||
timeon+=cp.perteam[teamiter->data].timeon;
|
||||
|
||||
map<string,int>::iterator it;
|
||||
it=cp.perteam[teamiter->data].weaponKills.begin();
|
||||
for (it;it!=cp.perteam[teamiter->data].weaponKills.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int kills=it->second;
|
||||
weapmap[name]+=kills;
|
||||
}
|
||||
}
|
||||
|
||||
CTimeIndexedList<player_class>::iterator clsit=cp.allclassesplayed.begin();
|
||||
for (clsit;clsit!=cp.allclassesplayed.end();++clsit)
|
||||
{
|
||||
string classname=plrClassNames[clsit->data];
|
||||
classmap[classname]+=cp.allclassesplayed.howLong(clsit->data);
|
||||
}
|
||||
|
||||
CTimeIndexedList<string>::iterator nameiter;
|
||||
for (nameiter=cp.aliases.begin();nameiter!=cp.aliases.end();++nameiter)
|
||||
{
|
||||
nickmap[nameiter->data]+=cp.aliases.howLong(nameiter->data);
|
||||
}
|
||||
|
||||
pair<time_t,time_t> startstop;
|
||||
startstop.first=cp.logontime;
|
||||
startstop.second=cp.logofftime;
|
||||
|
||||
playtimes.push_back(startstop);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlrPersist::merge
|
||||
// Purpose: merges the stats of another CPlrPersist object into this one.
|
||||
// This is the key operation of this class. This is how player stats are kept up
|
||||
// to date over time. If the two data files have playtimes that overlap, they
|
||||
// are not merged (unless the mergeOverlaps flag is true)
|
||||
// Input: other - the CPlrPersist object that we want to merge into this one
|
||||
// mergeOverlaps - if true, overlapping playtimes are ignored.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlrPersist::merge(CPlrPersist& other,bool mergeOverlaps)
|
||||
{
|
||||
if (!other.valid)
|
||||
return; //don't modify
|
||||
if (WONID!=other.WONID)
|
||||
{
|
||||
g_pApp->warning("merging stats for two different WONIDs (%lu, %lu)",WONID,other.WONID);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//do playtimes first to see if overlaps occur
|
||||
list<pair<time_t,time_t> >::iterator itOther=other.playtimes.begin();
|
||||
for (itOther;itOther!=other.playtimes.end();++itOther)
|
||||
{
|
||||
list<pair<time_t,time_t> >::iterator overlap=timesOverlap(itOther->first,itOther->second);
|
||||
time_t overlapSecond=overlap->second;
|
||||
time_t overlapFirst=overlap->first;
|
||||
if (mergeOverlaps || overlap==playtimes.end())
|
||||
playtimes.push_back(*itOther);
|
||||
else
|
||||
{
|
||||
g_pApp->warning("not merging stats for WON ID# %lu, playtime ranges overlap\n\t((%lu-%lu) overlaps with (%lu-%lu))",WONID,itOther->first,itOther->second,overlap->first,overlap->second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
matches+=other.matches;
|
||||
kills+=other.kills;
|
||||
deaths+=other.deaths;
|
||||
timeon+=other.timeon;
|
||||
if (other.lastplayed > lastplayed)
|
||||
lastplayed=other.lastplayed;
|
||||
|
||||
//do names
|
||||
map<string,int>::iterator it;
|
||||
it=other.nickmap.begin();
|
||||
for (it;it!=other.nickmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int time=it->second;
|
||||
nickmap[name]+=time;
|
||||
}
|
||||
|
||||
//do weapons
|
||||
it=other.weapmap.begin();
|
||||
for (it;it!=other.weapmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int kills=it->second;
|
||||
weapmap[name]+=kills;
|
||||
}
|
||||
|
||||
//do classes
|
||||
it=other.classmap.begin();
|
||||
for (it;it!=other.classmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int time=it->second;
|
||||
classmap[name]+=time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlrPersist::read
|
||||
// Purpose: fills in the fields of this by reading data out of a file
|
||||
// Input: f - the file from which to read the data
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlrPersist::read(CTextFile& f)
|
||||
{
|
||||
if (!f.isValid())
|
||||
{
|
||||
kills=deaths=timeon=0; WONID=-1;
|
||||
valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(WONID==-1)
|
||||
{
|
||||
//parse it out of f;
|
||||
string s=f.fileName();
|
||||
char buf[100];
|
||||
int startpos=s.find_last_of(g_pApp->os->pathSeperator());
|
||||
int endpos=s.find_last_of(".");
|
||||
if (endpos == -1)
|
||||
return;
|
||||
if (startpos==-1)
|
||||
startpos=0;
|
||||
|
||||
s.copy(buf,(endpos-startpos),startpos);
|
||||
buf[endpos-startpos]=0;
|
||||
WONID=strtoul(buf,NULL,10);
|
||||
if (!WONID)
|
||||
{
|
||||
WONID=-1;
|
||||
valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
valid=false;
|
||||
|
||||
if (!f.eof()) kills=f.readInt(); else return;
|
||||
if (!f.eof()) deaths=f.readInt(); else return;
|
||||
if (!f.eof()) timeon=f.readULong(); else return;
|
||||
if (!f.eof()) matches=f.readInt(); else return;
|
||||
if (!f.eof()) lastplayed=f.readULong(); else return;
|
||||
|
||||
string next;
|
||||
|
||||
if (!f.eof())
|
||||
{
|
||||
f.discard("names");
|
||||
next= f.peekNextString();
|
||||
while ( next!="endnames")
|
||||
{
|
||||
string name=f.readString();
|
||||
int timeon=f.readInt();
|
||||
nickmap[name]=timeon;
|
||||
next=f.peekNextString();
|
||||
}
|
||||
f.discard("endnames");
|
||||
} else return;
|
||||
|
||||
if (!f.eof())
|
||||
{
|
||||
f.discard("weapons");
|
||||
next= f.peekNextString();
|
||||
while (next!="endweapons")
|
||||
{
|
||||
string name=f.readString();
|
||||
int kills=f.readInt();
|
||||
weapmap[name]=kills;
|
||||
next=f.peekNextString();
|
||||
}
|
||||
f.discard("endweapons");
|
||||
} else return;
|
||||
|
||||
if (!f.eof())
|
||||
{
|
||||
f.discard("classes");
|
||||
next= f.peekNextString();
|
||||
while (next!="endclasses")
|
||||
{
|
||||
string name=f.readString();
|
||||
int timeused=f.readInt();
|
||||
classmap[name]=timeused;
|
||||
next=f.peekNextString();
|
||||
}
|
||||
f.discard("endclasses");
|
||||
} else return;
|
||||
|
||||
if (!f.eof())
|
||||
{
|
||||
f.discard("playtimes");
|
||||
next= f.peekNextString();
|
||||
while (next!="endplaytimes")
|
||||
{
|
||||
pair<time_t,time_t> startstop;
|
||||
startstop.first=f.readULong();
|
||||
startstop.second=f.readULong();
|
||||
playtimes.push_back(startstop);
|
||||
next=f.peekNextString();
|
||||
}
|
||||
f.discard("endplaytimes");
|
||||
} else return;
|
||||
|
||||
valid=true;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CPlrPersist::read
|
||||
// Purpose: converts the WONID to a file name (<wonid>.tfs) and passes execution
|
||||
// off to the above read function.
|
||||
// Input: WONID - the WONID of the player whose datafile we want to read
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CPlrPersist::read(unsigned long WONID)
|
||||
{
|
||||
|
||||
string file=g_pApp->playerDirectory;
|
||||
char buf[100];
|
||||
file+=g_pApp->os->ultoa(WONID,buf,10);
|
||||
file+=".tfs";
|
||||
|
||||
this->WONID=WONID;
|
||||
|
||||
CTextFile f(file.c_str());
|
||||
read(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPlrPersist::write()
|
||||
{
|
||||
string file=g_pApp->playerDirectory;
|
||||
char buf[100];
|
||||
file+=g_pApp->os->ultoa(WONID,buf,10);
|
||||
file+=".tfs";
|
||||
|
||||
FILE* fout=fopen(file.c_str(),"wt");
|
||||
|
||||
fprintf(fout,"%li //kills\n",kills);
|
||||
fprintf(fout,"%li //deaths\n",deaths);
|
||||
fprintf(fout,"%lu //timeon\n",timeon);
|
||||
fprintf(fout,"%li //matches played\n",matches);
|
||||
fprintf(fout,"%lu //last played\n",lastplayed);
|
||||
|
||||
map<string,int>::iterator it;
|
||||
|
||||
fprintf(fout,"names\n");
|
||||
it=nickmap.begin();
|
||||
for (it;it!=nickmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int time=it->second;
|
||||
fprintf(fout,"\t\"%s\" %li //has used the name \"%s\" for %02li:%02li:%02li\n",name.c_str(),time,name.c_str(),Util::time_t2hours(time),Util::time_t2mins(time),Util::time_t2secs(time));
|
||||
}
|
||||
fprintf(fout,"endnames\n");
|
||||
|
||||
fprintf(fout,"weapons\n");
|
||||
it=weapmap.begin();
|
||||
for (it;it!=weapmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int kills=it->second;
|
||||
fprintf(fout,"\t\"%s\" %li //has killed %li people with \"%s\"\n",name.c_str(),kills,kills,name.c_str());
|
||||
}
|
||||
fprintf(fout,"endweapons\n");
|
||||
|
||||
fprintf(fout,"classes\n");
|
||||
it=classmap.begin();
|
||||
for (it;it!=classmap.end();++it)
|
||||
{
|
||||
string name=it->first;
|
||||
int time=it->second;
|
||||
fprintf(fout,"\t\"%s\" %li //has played as a \"%s\" for %02li:%02li:%02li\n",name.c_str(),time,name.c_str(),Util::time_t2hours(time),Util::time_t2mins(time),Util::time_t2secs(time));
|
||||
}
|
||||
fprintf(fout,"endclasses\n");
|
||||
|
||||
fprintf(fout,"playtimes\n");
|
||||
list<pair<time_t,time_t> >::iterator it2=playtimes.begin();
|
||||
for (it2;it2!=playtimes.end();++it2)
|
||||
{
|
||||
char buf[500];
|
||||
time_t t1=it2->first;
|
||||
time_t t2=it2->second;
|
||||
bool doesOverlap;
|
||||
|
||||
list<pair<time_t,time_t> >::iterator overlap=timesOverlap(it2->first,it2->second,false);
|
||||
doesOverlap= overlap!=playtimes.end();
|
||||
|
||||
|
||||
fprintf(fout,"\t%lu %lu //played from %s.",it2->first,it2->second,Util::makeDurationString(it2->first,it2->second,buf," to "));
|
||||
if (doesOverlap)
|
||||
fprintf(fout,"Warning! overlaps with time range (%lu-%lu)",overlap->first,overlap->second);
|
||||
fprintf(fout,"\n");
|
||||
|
||||
}
|
||||
fprintf(fout,"endplaytimes\n");
|
||||
|
||||
|
||||
fclose(fout);
|
||||
|
||||
}
|
||||
|
||||
|
||||
list<pair<time_t,time_t> >::iterator CPlrPersist::timesOverlap(time_t start, time_t end,bool testself)
|
||||
{
|
||||
list<pair<time_t,time_t> >::iterator it;
|
||||
it=playtimes.begin();
|
||||
for (it;it!=playtimes.end();++it)
|
||||
{
|
||||
time_t itFirst=it->first;
|
||||
time_t itSecond=it->second;
|
||||
if (start == it->first && end == it->second)
|
||||
{
|
||||
if (testself)
|
||||
break;
|
||||
}
|
||||
//if start is in current range
|
||||
else if (start >= it->first && start <= it->second)
|
||||
break;
|
||||
|
||||
//if end is in current range
|
||||
else if (end >= it->first && end <= it->second)
|
||||
break;
|
||||
|
||||
//if the start is before this range and end is after
|
||||
else if (start <= it->first && end >= it->second)
|
||||
break;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
string CPlrPersist::faveString(map<string,int>& theMap)
|
||||
{
|
||||
string retstr;
|
||||
time_t max=0;
|
||||
map<string,int>::iterator it=theMap.begin();
|
||||
for (it;it!=theMap.end();++it)
|
||||
{
|
||||
if (it->second > max)
|
||||
{
|
||||
max=it->second;
|
||||
retstr=it->first;
|
||||
}
|
||||
}
|
||||
return retstr;
|
||||
}
|
||||
|
||||
string CPlrPersist::faveName()
|
||||
{
|
||||
return faveString(nickmap);
|
||||
}
|
||||
string CPlrPersist::faveWeap()
|
||||
{
|
||||
string s=faveString(weapmap);
|
||||
faveweapkills=weapmap[s];
|
||||
return s;
|
||||
}
|
||||
string CPlrPersist::faveClass()
|
||||
{
|
||||
return faveString(classmap);
|
||||
}
|
||||
|
||||
double CPlrPersist::rank()
|
||||
{
|
||||
return ((double)((double)kills - (double)deaths) * 1000.0) / (double)timeon;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//========= 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:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#ifndef PLRPERSIST_H
|
||||
#define PLRPERSIST_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include "TimeIndexedList.h"
|
||||
#include "Player.h"
|
||||
#include "TextFile.h"
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: Represents persistent player data. This class is used to save and load
|
||||
// Player data from the disk.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CPlrPersist
|
||||
{
|
||||
public:
|
||||
unsigned long WONID;
|
||||
int kills;
|
||||
int deaths;
|
||||
time_t timeon;
|
||||
|
||||
bool valid;
|
||||
|
||||
string faveString(map<string,int>& theMap);
|
||||
|
||||
map<string,int> nickmap;
|
||||
string faveName();
|
||||
map<string,int> weapmap;
|
||||
string faveWeap();
|
||||
map<string,int> classmap;
|
||||
string faveClass();
|
||||
list<pair<time_t,time_t> > playtimes;
|
||||
|
||||
time_t lastplayed;
|
||||
|
||||
int matches;
|
||||
int suicides;
|
||||
int faveweapkills;
|
||||
double rank();
|
||||
|
||||
|
||||
CPlrPersist()
|
||||
{
|
||||
kills=deaths=suicides=faveweapkills=matches=0;WONID=-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void read(unsigned long WONID);
|
||||
void read(CTextFile& f);
|
||||
void merge(CPlrPersist& cpp,bool mergeOverlaps=false);
|
||||
void generate(CPlayer& cp);
|
||||
void write();
|
||||
|
||||
list<pair<time_t,time_t> >::iterator timesOverlap(time_t start, time_t end,bool testself=true);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // PLRPERSIST_H
|
||||
@@ -0,0 +1,50 @@
|
||||
TFStats v2.0 readme file
|
||||
|
||||
v2.0 New Features
|
||||
* Full search custom rules. Custom rules can now search every event in the log
|
||||
and match based on regular expression matching patterns.
|
||||
* General Rule File. TFStats now reads TFC.RUL in addition to any map specific
|
||||
rule files so you can put any server-specific rules in tfc.rul.
|
||||
* Persistent Player Statistics. Player's stats are now saved (if you so specify)
|
||||
on the hard-disk and every time you generate a report more are saved and/or
|
||||
merged (if a player's stats had already been saved). What this does is allow
|
||||
player stats to accumulate over time, across many matches. This also has support
|
||||
for omitting players who have been absent for a long time from the report.
|
||||
* Stats Resume for Lan Games. Stats Resume now works on Lan games by matching IP
|
||||
addresses. It will match by name if it cannot match by IP for some reason.
|
||||
* Windows Front End. the Win32 version of TFStats now features an easy-to-use
|
||||
Windows front end that automates generating several logs at once and provides
|
||||
easy to use controls to control all of the new switches that TFStats supports and
|
||||
the directories it reads from and writes to.
|
||||
* Shared Report Resources. TFStats can now generate several reports that share
|
||||
the same set of reports to preserve hard-drive space.
|
||||
|
||||
v2.0 Bug Fixes
|
||||
*Players with < and > in their names now work properly.
|
||||
*Multiline Broadcasts are now handled correctly.
|
||||
|
||||
v1.5 New Features
|
||||
*Team Differentiation: If a player plays on two different teams, tfstats
|
||||
gathers stats for each team seperately, then when viewing that players
|
||||
stats, there's a link to that player's merged stats.
|
||||
*Pseudonyms for players: This is so it's not confusing if players change their
|
||||
names. it uses the name they used for the most time, and also lists other
|
||||
names they used.
|
||||
*DisplayMM2 switch: The user (the person who runs tfstats) can now choose if
|
||||
they want to display team messages or not. a lot of clans e-mailed me asking
|
||||
me to take out mm2 messages from the dialogue readout.
|
||||
*Stats Resume: Disconnected players resume their stats where they left off
|
||||
when they reconnect. This doesn't work in lan games because there is no
|
||||
WONID to work with.
|
||||
*Garbage handling: TFStats is more robust when it comes to garbage input now.
|
||||
|
||||
v1.5 Bug Fixes
|
||||
*The team kill award now works
|
||||
*medics don't get double kills anymore
|
||||
*the dates are now correct
|
||||
*RandomPC is now handled correctly
|
||||
|
||||
As always you can e-mail tfstats@valvesoftware.com with questions, comments
|
||||
and feature suggestions. Read the TFStats manual for full documentation
|
||||
|
||||
Thanks for using TFStats!
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef CREGEX_H
|
||||
#include <jm/cregex.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef CREGEX_H
|
||||
#include <jm/cregex.h>
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef __FILEITER_H
|
||||
|
||||
#include <jm/fileiter.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE cregex.h
|
||||
* VERSION 2.12
|
||||
*/
|
||||
|
||||
#ifndef CREGEX_H
|
||||
#define CREGEX_H
|
||||
|
||||
#include <jm/jm_cfg.h>
|
||||
|
||||
/* include these defs only for POSIX compatablity */
|
||||
|
||||
typedef int regoff_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int re_magic;
|
||||
unsigned int re_nsub; /* number of parenthesized subexpressions */
|
||||
const char* re_endp; /* end pointer for REG_PEND */
|
||||
void* guts; /* none of your business :-) */
|
||||
unsigned int eflags; /* none of your business :-) */
|
||||
} regex_tA;
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
typedef struct
|
||||
{
|
||||
unsigned int re_magic;
|
||||
unsigned int re_nsub; /* number of parenthesized subexpressions */
|
||||
const wchar_t* re_endp; /* end pointer for REG_PEND */
|
||||
void* guts; /* none of your business :-) */
|
||||
unsigned int eflags; /* none of your business :-) */
|
||||
} regex_tW;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
regoff_t rm_so; /* start of match */
|
||||
regoff_t rm_eo; /* end of match */
|
||||
} regmatch_t;
|
||||
|
||||
/* regcomp() flags */
|
||||
#define REG_BASIC 0000
|
||||
#define REG_EXTENDED 0001
|
||||
#define REG_ICASE 0002
|
||||
#define REG_NOSUB 0004
|
||||
#define REG_NEWLINE 0010
|
||||
#define REG_NOSPEC 0020
|
||||
#define REG_PEND 0040
|
||||
#define REG_DUMP 0200
|
||||
#define REG_NOCOLLATE 0400
|
||||
|
||||
#define REG_ASSERT 15
|
||||
#define REG_INVARG 16
|
||||
#define REG_ATOI 255 /* convert name to number (!) */
|
||||
#define REG_ITOA 0400 /* convert number to name (!) */
|
||||
|
||||
/* regexec() flags */
|
||||
#define REG_NOTBOL 00001
|
||||
#define REG_NOTEOL 00002
|
||||
#define REG_STARTEND 00004
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JM_IX_DECL int RE_CCALL regcompA(regex_tA*, const char*, int);
|
||||
JM_IX_DECL unsigned int RE_CCALL regerrorA(int, const regex_tA*, char*, unsigned int);
|
||||
JM_IX_DECL int RE_CCALL regexecA(const regex_tA*, const char*, unsigned int, regmatch_t*, int);
|
||||
JM_IX_DECL void RE_CCALL regfreeA(regex_tA*);
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_IX_DECL int RE_CCALL regcompW(regex_tW*, const wchar_t*, int);
|
||||
JM_IX_DECL unsigned int RE_CCALL regerrorW(int, const regex_tW*, wchar_t*, unsigned int);
|
||||
JM_IX_DECL int RE_CCALL regexecW(const regex_tW*, const wchar_t*, unsigned int, regmatch_t*, int);
|
||||
JM_IX_DECL void RE_CCALL regfreeW(regex_tW*);
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define regcomp regcompW
|
||||
#define regerror regerrorW
|
||||
#define regexec regexecW
|
||||
#define regfree regfreeW
|
||||
#define regex_t regex_tW
|
||||
#else
|
||||
#define regcomp regcompA
|
||||
#define regerror regerrorA
|
||||
#define regexec regexecA
|
||||
#define regfree regfreeA
|
||||
#define regex_t regex_tA
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
JM_NAMESPACE(__JM)
|
||||
#endif
|
||||
|
||||
/* regerror() flags */
|
||||
typedef enum
|
||||
{
|
||||
REG_NOERROR = 0, /* Success. */
|
||||
REG_NOMATCH = 1, /* Didn't find a match (for regexec). */
|
||||
|
||||
/* POSIX regcomp return error codes. (In the order listed in the
|
||||
standard.) */
|
||||
REG_BADPAT = 2, /* Invalid pattern. */
|
||||
REG_ECOLLATE = 3, /* Undefined collating element. */
|
||||
REG_ECTYPE = 4, /* Invalid character class name. */
|
||||
REG_EESCAPE = 5, /* Trailing backslash. */
|
||||
REG_ESUBREG = 6, /* Invalid back reference. */
|
||||
REG_EBRACK = 7, /* Unmatched left bracket. */
|
||||
REG_EPAREN = 8, /* Parenthesis imbalance. */
|
||||
REG_EBRACE = 9, /* Unmatched \{. */
|
||||
REG_BADBR = 10, /* Invalid contents of \{\}. */
|
||||
REG_ERANGE = 11, /* Invalid range end. */
|
||||
REG_ESPACE = 12, /* Ran out of memory. */
|
||||
REG_BADRPT = 13, /* No preceding re for repetition op. */
|
||||
REG_EEND = 14, /* unexpected end of expression */
|
||||
REG_ESIZE = 15, /* expression too big */
|
||||
REG_ERPAREN = 16, /* unmatched right parenthesis */
|
||||
REG_EMPTY = 17, /* empty expression */
|
||||
REG_E_MEMORY = 18, /* out of memory */
|
||||
REG_E_UNKNOWN = 19 /* unknown error */
|
||||
} reg_errcode_t;
|
||||
|
||||
enum match_flags
|
||||
{
|
||||
match_default = 0,
|
||||
match_not_bol = 1, // first is not start of line
|
||||
match_not_eol = match_not_bol << 1, // last is not end of line
|
||||
match_not_bob = match_not_eol << 1, // first is not start of buffer
|
||||
match_not_eob = match_not_bob << 1, // last is not end of buffer
|
||||
match_not_bow = match_not_eob << 1, // first is not start of word
|
||||
match_not_eow = match_not_bow << 1, // last is not end of word
|
||||
match_not_dot_newline = match_not_eow << 1, // \n is not matched by '.'
|
||||
match_not_dot_null = match_not_dot_newline << 1, // '\0' is not matched by '.'
|
||||
match_prev_avail = match_not_dot_null << 1, // *--first is a valid expression
|
||||
match_init = match_prev_avail << 1, // internal use
|
||||
match_any = match_init << 1, // don't care what we match
|
||||
match_not_null = match_any << 1, // string can't be null
|
||||
match_continuous = match_not_null << 1, // each grep match must continue from
|
||||
// uninterupted from the previous one
|
||||
match_stop = match_continuous << 1 // stop after first match (grep)
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
JM_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
//
|
||||
// C++ high level wrapper goes here:
|
||||
//
|
||||
#if defined(__cplusplus) && !defined(JM_NO_STRING_H)
|
||||
#include <string>
|
||||
#include <vector>
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
class RegExData;
|
||||
class RegEx;
|
||||
struct pred1;
|
||||
struct pred2;
|
||||
struct pred3;
|
||||
struct pred4;
|
||||
|
||||
typedef bool (*GrepCallback)(const RegEx& expression);
|
||||
typedef bool (*GrepFileCallback)(const char* file, const RegEx& expression);
|
||||
typedef bool (*FindFilesCallback)(const char* file);
|
||||
|
||||
class JM_IX_DECL RegEx
|
||||
{
|
||||
private:
|
||||
RegExData* pdata;
|
||||
public:
|
||||
RegEx();
|
||||
RegEx(const RegEx& o);
|
||||
~RegEx();
|
||||
RegEx(const char* c, bool icase = false);
|
||||
RegEx(const __JM_STD::string& s, bool icase = false);
|
||||
RegEx& operator=(const RegEx& o);
|
||||
RegEx& operator=(const char* p);
|
||||
RegEx& operator=(const __JM_STD::string& s){ return this->operator=(s.c_str()); }
|
||||
unsigned int SetExpression(const char* p, bool icase = false);
|
||||
unsigned int SetExpression(const __JM_STD::string& s, bool icase = false){ return SetExpression(s.c_str(), icase); }
|
||||
__JM_STD::string Expression()const;
|
||||
//
|
||||
// now matching operators:
|
||||
//
|
||||
bool Match(const char* p, unsigned int flags = match_default);
|
||||
bool Match(const __JM_STD::string& s, unsigned int flags = match_default) { return Match(s.c_str(), flags); }
|
||||
bool Search(const char* p, unsigned int flags = match_default);
|
||||
bool Search(const __JM_STD::string& s, unsigned int flags = match_default) { return Search(s.c_str(), flags); }
|
||||
unsigned int Grep(GrepCallback cb, const char* p, unsigned int flags = match_default);
|
||||
unsigned int Grep(GrepCallback cb, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(cb, s.c_str(), flags); }
|
||||
unsigned int Grep(__JM_STD::vector<__JM_STD::string>& v, const char* p, unsigned int flags = match_default);
|
||||
unsigned int Grep(__JM_STD::vector<__JM_STD::string>& v, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(v, s.c_str(), flags); }
|
||||
unsigned int Grep(__JM_STD::vector<unsigned int>& v, const char* p, unsigned int flags = match_default);
|
||||
unsigned int Grep(__JM_STD::vector<unsigned int>& v, const __JM_STD::string& s, unsigned int flags = match_default) { return Grep(v, s.c_str(), flags); }
|
||||
unsigned int GrepFiles(GrepFileCallback cb, const char* files, bool recurse = false, unsigned int flags = match_default);
|
||||
unsigned int GrepFiles(GrepFileCallback cb, const __JM_STD::string& files, bool recurse = false, unsigned int flags = match_default) { return GrepFiles(cb, files.c_str(), recurse, flags); }
|
||||
unsigned int FindFiles(FindFilesCallback cb, const char* files, bool recurse = false, unsigned int flags = match_default);
|
||||
unsigned int FindFiles(FindFilesCallback cb, const __JM_STD::string& files, bool recurse = false, unsigned int flags = match_default) { return FindFiles(cb, files.c_str(), recurse, flags); }
|
||||
//
|
||||
// now operators for returning what matched in more detail:
|
||||
//
|
||||
unsigned int Position(int i = 0)const;
|
||||
unsigned int Length(int i = 0)const;
|
||||
unsigned int Line()const;
|
||||
unsigned int Marks()const;
|
||||
__JM_STD::string What(int i = 0)const;
|
||||
__JM_STD::string operator[](int i)const { return What(i); }
|
||||
|
||||
friend struct pred1;
|
||||
friend struct pred2;
|
||||
friend struct pred3;
|
||||
friend struct pred4;
|
||||
};
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING) && defined(__cplusplus)
|
||||
|
||||
using __JM::RegEx;
|
||||
using __JM::GrepCallback;
|
||||
using __JM::GrepFileCallback;
|
||||
using __JM::FindFilesCallback;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING) && defined(__cplusplus)
|
||||
|
||||
using __JM::match_flags;
|
||||
using __JM::reg_errcode_t;
|
||||
|
||||
using __JM::REG_NOERROR;
|
||||
using __JM::REG_NOMATCH;
|
||||
using __JM::REG_BADPAT;
|
||||
using __JM::REG_ECOLLATE;
|
||||
using __JM::REG_ECTYPE;
|
||||
using __JM::REG_EESCAPE;
|
||||
using __JM::REG_ESUBREG;
|
||||
using __JM::REG_EBRACK;
|
||||
using __JM::REG_EPAREN;
|
||||
using __JM::REG_EBRACE;
|
||||
using __JM::REG_BADBR;
|
||||
using __JM::REG_ERANGE;
|
||||
using __JM::REG_ESPACE;
|
||||
using __JM::REG_BADRPT;
|
||||
using __JM::REG_EEND;
|
||||
using __JM::REG_ESIZE;
|
||||
using __JM::REG_ERPAREN;
|
||||
using __JM::REG_EMPTY;
|
||||
using __JM::REG_E_MEMORY;
|
||||
using __JM::REG_E_UNKNOWN;
|
||||
using __JM::match_default;
|
||||
using __JM::match_not_bol;
|
||||
using __JM::match_not_eol;
|
||||
using __JM::match_not_bob;
|
||||
using __JM::match_not_eob;
|
||||
using __JM::match_not_bow;
|
||||
using __JM::match_not_eow;
|
||||
using __JM::match_not_dot_newline;
|
||||
using __JM::match_not_dot_null;
|
||||
using __JM::match_prev_avail;
|
||||
using __JM::match_init;
|
||||
using __JM::match_any;
|
||||
using __JM::match_not_null;
|
||||
using __JM::match_continuous;
|
||||
using __JM::match_stop;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* FILE fileiter.h
|
||||
* VERSION 2.12
|
||||
*
|
||||
* this file declares various platform independent file and directory
|
||||
* iterators, plus binary file input in the form of class map_file.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __FILEITER_H
|
||||
#define __FILEITER_H
|
||||
|
||||
#include <jm/jm_cfg.h>
|
||||
|
||||
#if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) && !defined(JM_NO_WIN32)
|
||||
|
||||
#define FI_W32
|
||||
#include <windows.h>
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
typedef WIN32_FIND_DATA _fi_find_data;
|
||||
typedef HANDLE _fi_find_handle;
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#define _fi_invalid_handle INVALID_HANDLE_VALUE
|
||||
#define _fi_dir FILE_ATTRIBUTE_DIRECTORY
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#ifndef JM_NO_STL
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#if defined(__SUNPRO_CC) && !defined(JM_NO_NAMESPACES)
|
||||
using __JM_STD::list;
|
||||
#endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 256
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
struct _fi_find_data
|
||||
{
|
||||
unsigned dwFileAttributes;
|
||||
char cFileName[MAX_PATH];
|
||||
};
|
||||
|
||||
struct _fi_priv_data;
|
||||
|
||||
typedef _fi_priv_data* _fi_find_handle;
|
||||
#define _fi_invalid_handle NULL
|
||||
#define _fi_dir 1
|
||||
|
||||
_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData);
|
||||
bool _fi_FindNextFile(_fi_find_handle hFindFile, _fi_find_data* lpFindFileData);
|
||||
bool _fi_FindClose(_fi_find_handle hFindFile);
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#ifdef FindFirstFile
|
||||
#undef FindFirstFile
|
||||
#endif
|
||||
#ifdef FindNextFile
|
||||
#undef FindNextFile
|
||||
#endif
|
||||
#ifdef FindClose
|
||||
#undef FindClose
|
||||
#endif
|
||||
|
||||
#define FindFirstFile _fi_FindFirstFile
|
||||
#define FindNextFile _fi_FindNextFile
|
||||
#define FindClose _fi_FindClose
|
||||
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
#ifdef FI_W32 // win32 mapfile
|
||||
|
||||
class JM_IX_DECL mapfile
|
||||
{
|
||||
HANDLE hfile;
|
||||
HANDLE hmap;
|
||||
const char* _first;
|
||||
const char* _last;
|
||||
public:
|
||||
|
||||
typedef const char* iterator;
|
||||
|
||||
mapfile(){ hfile = hmap = 0; _first = _last = 0; }
|
||||
mapfile(const char* file){ hfile = hmap = 0; _first = _last = 0; open(file); }
|
||||
~mapfile(){ close(); }
|
||||
void open(const char* file);
|
||||
void close();
|
||||
const char* begin(){ return _first; }
|
||||
const char* end(){ return _last; }
|
||||
size_t size(){ return _last - _first; }
|
||||
bool valid(){ return (hfile != 0) && (hfile != INVALID_HANDLE_VALUE); }
|
||||
};
|
||||
|
||||
|
||||
#elif !defined(JM_NO_STL) // use POSIX API to emulate the memory map:
|
||||
|
||||
class JM_IX_DECL mapfile_iterator;
|
||||
|
||||
class JM_IX_DECL mapfile
|
||||
{
|
||||
typedef char* pointer;
|
||||
FILE* hfile;
|
||||
long int _size;
|
||||
pointer* _first;
|
||||
pointer* _last;
|
||||
mutable __JM_STD::list<pointer*> condemed;
|
||||
enum sizes
|
||||
{
|
||||
buf_size = 4096
|
||||
};
|
||||
void lock(pointer* node)const;
|
||||
void unlock(pointer* node)const;
|
||||
public:
|
||||
|
||||
typedef mapfile_iterator iterator;
|
||||
|
||||
mapfile(){ hfile = 0; _size = 0; _first = _last = 0; }
|
||||
mapfile(const char* file){ hfile = 0; _size = 0; _first = _last = 0; open(file); }
|
||||
~mapfile(){ close(); }
|
||||
void open(const char* file);
|
||||
void close();
|
||||
iterator begin()const;
|
||||
iterator end()const;
|
||||
unsigned long size()const{ return _size; }
|
||||
bool valid()const{ return hfile != 0; }
|
||||
friend class mapfile_iterator;
|
||||
};
|
||||
|
||||
class JM_IX_DECL mapfile_iterator : public JM_RA_ITERATOR(char, long)
|
||||
{
|
||||
typedef mapfile::pointer pointer;
|
||||
pointer* node;
|
||||
const mapfile* file;
|
||||
unsigned long offset;
|
||||
long position()const
|
||||
{
|
||||
return file ? ((node - file->_first) * mapfile::buf_size + offset) : 0;
|
||||
}
|
||||
void position(long pos)
|
||||
{
|
||||
if(file)
|
||||
{
|
||||
node = file->_first + (pos / mapfile::buf_size);
|
||||
offset = pos % mapfile::buf_size;
|
||||
}
|
||||
}
|
||||
public:
|
||||
mapfile_iterator() { node = 0; file = 0; offset = 0; }
|
||||
mapfile_iterator(const mapfile* f, long position)
|
||||
{
|
||||
file = f;
|
||||
node = f->_first + position / mapfile::buf_size;
|
||||
offset = position % mapfile::buf_size;
|
||||
if(file)
|
||||
file->lock(node);
|
||||
}
|
||||
mapfile_iterator(const mapfile_iterator& i)
|
||||
{
|
||||
file = i.file;
|
||||
node = i.node;
|
||||
offset = i.offset;
|
||||
if(file)
|
||||
file->lock(node);
|
||||
}
|
||||
~mapfile_iterator()
|
||||
{
|
||||
if(file && node)
|
||||
file->unlock(node);
|
||||
}
|
||||
mapfile_iterator& operator = (const mapfile_iterator& i);
|
||||
char operator* ()const
|
||||
{
|
||||
assert(node >= file->_first);
|
||||
assert(node < file->_last);
|
||||
return file ? *(*node + sizeof(int) + offset) : char(0);
|
||||
}
|
||||
mapfile_iterator& operator++ ();
|
||||
mapfile_iterator operator++ (int);
|
||||
mapfile_iterator& operator-- ();
|
||||
mapfile_iterator operator-- (int);
|
||||
|
||||
mapfile_iterator& operator += (long off)
|
||||
{
|
||||
position(position() + off);
|
||||
return *this;
|
||||
}
|
||||
mapfile_iterator& operator -= (long off)
|
||||
{
|
||||
position(position() - off);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline bool operator==(const mapfile_iterator& i, const mapfile_iterator& j)
|
||||
{
|
||||
return (i.file == j.file) && (i.node == j.node) && (i.offset == j.offset);
|
||||
}
|
||||
#ifndef JM_NO_NOT_EQUAL
|
||||
friend inline bool operator!=(const mapfile_iterator& i, const mapfile_iterator& j)
|
||||
{
|
||||
return !(i == j);
|
||||
}
|
||||
#endif
|
||||
friend inline bool operator<(const mapfile_iterator& i, const mapfile_iterator& j)
|
||||
{
|
||||
return i.position() < j.position();
|
||||
}
|
||||
|
||||
friend mapfile_iterator operator + (const mapfile_iterator& i, long off);
|
||||
friend mapfile_iterator operator - (const mapfile_iterator& i, long off);
|
||||
friend inline long operator - (const mapfile_iterator& i, const mapfile_iterator& j)
|
||||
{
|
||||
return i.position() - j.position();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// _fi_sep determines the directory separator, either '\\' or '/'
|
||||
JM_IX_DECL extern const char* _fi_sep;
|
||||
|
||||
struct file_iterator_ref
|
||||
{
|
||||
_fi_find_handle hf;
|
||||
_fi_find_data _data;
|
||||
long count;
|
||||
};
|
||||
|
||||
|
||||
class JM_IX_DECL file_iterator : public JM_INPUT_ITERATOR(const char*, __JM_STDC::ptrdiff_t)
|
||||
{
|
||||
char* _root;
|
||||
char* _path;
|
||||
char* ptr;
|
||||
file_iterator_ref* ref;
|
||||
|
||||
public:
|
||||
file_iterator();
|
||||
file_iterator(const char* wild);
|
||||
~file_iterator();
|
||||
file_iterator(const file_iterator&);
|
||||
file_iterator& operator=(const file_iterator&);
|
||||
const char* root() { return _root; }
|
||||
const char* path() { return _path; }
|
||||
_fi_find_data* data() { return &(ref->_data); }
|
||||
void next();
|
||||
file_iterator& operator++() { next(); return *this; }
|
||||
file_iterator operator++(int);
|
||||
const char* operator*() { return path(); }
|
||||
|
||||
friend inline bool operator == (const file_iterator& f1, const file_iterator& f2)
|
||||
{
|
||||
return ((f1.ref->hf == _fi_invalid_handle) && (f1.ref->hf == _fi_invalid_handle));
|
||||
}
|
||||
#ifndef JM_NO_NOT_EQUAL
|
||||
friend inline bool operator != (const file_iterator& f1, const file_iterator& f2)
|
||||
{
|
||||
return !(f1 == f2);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
inline bool operator < (const file_iterator& f1, const file_iterator& f2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class JM_IX_DECL directory_iterator : public JM_INPUT_ITERATOR(const char*, __JM_STDC::ptrdiff_t)
|
||||
{
|
||||
char* _root;
|
||||
char* _path;
|
||||
char* ptr;
|
||||
file_iterator_ref* ref;
|
||||
|
||||
public:
|
||||
directory_iterator();
|
||||
directory_iterator(const char* wild);
|
||||
~directory_iterator();
|
||||
directory_iterator(const directory_iterator& other);
|
||||
directory_iterator& operator=(const directory_iterator& other);
|
||||
|
||||
const char* root() { return _root; }
|
||||
const char* path() { return _path; }
|
||||
_fi_find_data* data() { return &(ref->_data); }
|
||||
void next();
|
||||
directory_iterator& operator++() { next(); return *this; }
|
||||
directory_iterator operator++(int);
|
||||
const char* operator*() { return path(); }
|
||||
|
||||
static const char* separator() { return _fi_sep; }
|
||||
|
||||
friend inline bool operator == (const directory_iterator& f1, const directory_iterator& f2)
|
||||
{
|
||||
return ((f1.ref->hf == _fi_invalid_handle) && (f1.ref->hf == _fi_invalid_handle));
|
||||
}
|
||||
|
||||
#ifndef JM_NO_NOT_EQUAL
|
||||
friend inline bool operator != (const directory_iterator& f1, const directory_iterator& f2)
|
||||
{
|
||||
return !(f1 == f2);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
inline bool operator < (const directory_iterator& f1, const directory_iterator& f2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#if !defined(JM_NO_NAMESPACES) && !defined(JM_NO_USING)
|
||||
|
||||
using __JM::directory_iterator;
|
||||
using __JM::file_iterator;
|
||||
using __JM::mapfile;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // __WINITER_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef JM_OPT_H
|
||||
#define JM_OPT_H
|
||||
|
||||
/* #define JM_AUTO_CONFIGURE */
|
||||
#ifdef JM_AUTO_CONFIGURE
|
||||
|
||||
/* Namespace Options: */
|
||||
|
||||
/* JM_NO_NAMESPACES Define if your compiler does not support namespaces */
|
||||
/* #define JM_NO_NAMESPACES */
|
||||
|
||||
/* __JM Defines the namespace used for this library,
|
||||
defaults to "jm", but can be changed by defining
|
||||
__JM on the command line. */
|
||||
/* #define __JM */
|
||||
|
||||
/* __JM_STD Defines the namespace used by the underlying STL
|
||||
(if any), defaults to "std", can be changed by
|
||||
defining __JM_STD on the command line. */
|
||||
/* #define __JM_STD */
|
||||
|
||||
|
||||
/* __JM_STDC Defines the namespace used by the C Library defs.
|
||||
Defaults to "std" as recomended by the latest
|
||||
draft standard, can be redefined by defining
|
||||
__JM_STDC on the command line. */
|
||||
/* #define __JM_STDC */
|
||||
|
||||
|
||||
|
||||
/* Compiler options: */
|
||||
|
||||
/* JM_NO_EXCEPTIONS Disables exception handling support. */
|
||||
/* #define JM_NO_EXCEPTIONS */
|
||||
|
||||
/* JM_NO_MUTABLE Disables use of mutable keyword. */
|
||||
/* #define JM_NO_MUTABLE */
|
||||
|
||||
/* JM_INT32 The type for 32-bit integers - what C calls intfast32_t */
|
||||
/* #define JM_INT32 */
|
||||
|
||||
/* JM_NO_DEFAULT_PARAM If templates can not have default parameters. */
|
||||
/* #define JM_NO_DEFAULT_PARAM */
|
||||
|
||||
/* JM_NO_TRICKY_DEFAULT_PARAM If templates can not have derived default parameters. */
|
||||
/* #define JM_NO_TRICKY_DEFAULT_PARAM */
|
||||
|
||||
/* JM_NO_TEMPLATE_TYPENAME If class scope typedefs of the form:
|
||||
typedef typename X<T> Y;
|
||||
where T is a template parameter to this,
|
||||
do not compile unless the typename is omitted. */
|
||||
/* #define JM_NO_TEMPLATE_TYPENAME */
|
||||
|
||||
/* JM_NO_TEMPLATE_FRIEND If template friend declarations are not supported */
|
||||
/* #define JM_NO_TEMPLATE_FRIEND */
|
||||
|
||||
/* JM_PLATFORM_WINDOWS Platform is MS Windows. */
|
||||
/* #define JM_PLATFORM_WINDOWS */
|
||||
|
||||
/* JM_PLATFORM_DOS Platform if MSDOS. */
|
||||
/* #define JM_PLATFORM_DOS */
|
||||
|
||||
/* JM_PLATFORM_W32 Platform is MS Win32 */
|
||||
/* #define JM_PLATFORM_W32 */
|
||||
|
||||
/* JM_NO_WIN32 Disable Win32 support even when present */
|
||||
/* #define JM_NO_WIN32 */
|
||||
|
||||
/* JM_NO_BOOL If bool is not a distict type. */
|
||||
/* #define JM_NO_BOOL */
|
||||
|
||||
/* JM_NO_WCHAR_H If there is no <wchar.h> */
|
||||
/* #define JM_NO_WCHAR_H */
|
||||
|
||||
/* JM_NO_WCTYPE_H If there is no <wctype.h> */
|
||||
/* #define JM_NO_WCTYPE_H */
|
||||
|
||||
/* JM_NO_WCSTRING If there are no wcslen and wcsncmp functions available. */
|
||||
/* #define JM_NO_WCSTRING */
|
||||
|
||||
/* JM_NO_SWPRINTF If there is no swprintf available. */
|
||||
/* #define JM_NO_SWPRINTF */
|
||||
|
||||
/* JM_NO_WSPRINTF If there is no wsprintf available. */
|
||||
/* #define JM_NO_WSPRINTF */
|
||||
|
||||
/* JM_NO_MEMBER_TEMPLATES If member function templates or nested template classes are not allowed. */
|
||||
/* #define JM_NO_MEMBER_TEMPLATES */
|
||||
|
||||
/* JM_NO_TEMPLATE_RETURNS If template functions based on return type are not supported. */
|
||||
/* #define JM_NO_TEMPLATE_RETURNS */
|
||||
|
||||
/* JM_NO_PARTIAL_FUNC_SPEC If partial template function specialisation is not supported */
|
||||
/* #define JM_NO_PARTIAL_FUNC_SPEC */
|
||||
|
||||
/* JM_NO_INT64 If 64bit integers are not supported. */
|
||||
/* JM_INT64t The type of a 64-bit signed integer if available. */
|
||||
/* JM_IMM64(val) Declares a 64-bit immediate value by appending any
|
||||
necessary suffix to val. */
|
||||
/* JM_INT64_T 0 = NA
|
||||
1 = short
|
||||
2 = int
|
||||
3 = long
|
||||
4 = int64_t
|
||||
5 = long long
|
||||
6 = __int64 */
|
||||
/* #define JM_INT64_T */
|
||||
|
||||
/* JM_NO_CAT Define if the compiler does not support POSIX style
|
||||
message categories (catopen catgets catclose). */
|
||||
/* #define JM_NO_CAT */
|
||||
|
||||
/* JM_THREADS Define if the compiler supports multiple threads in
|
||||
the current translation mode. */
|
||||
/* #define JM_THREADS */
|
||||
|
||||
/* JM_TEMPLATE_SPECIALISE Defaults to template<> , ie the template specialisation
|
||||
prefix, can be redefined to nothing for older compilers. */
|
||||
/* #define JM_TEMPLATE_SPECIALISE */
|
||||
|
||||
/* JM_NESTED_TEMPLATE_DECL Defaults to template, the standard prefix when accessing
|
||||
nested template classes, can be redefined to nothing if
|
||||
the compiler does not support this. */
|
||||
/* #define JM_NESTED_TEMPLATE_DECL */
|
||||
|
||||
/* JM_NO_TEMPLATE_INST If explicit template instantiation with the "template class X<T>"
|
||||
syntax is not supported */
|
||||
/* #define JM_NO_TEMPLATE_INST */
|
||||
|
||||
/* JM_NO_TEMPLATE_MERGE If template in separate translation units don't merge at link time */
|
||||
/* #define JM_NO_TEMPLATE_MERGE */
|
||||
|
||||
/* JM_NO_TEMPLATE_MERGE_A If template merging from library archives is not supported */
|
||||
/* #define JM_NO_TEMPLATE_MERGE_A */
|
||||
|
||||
/* JM_NO_TEMPLATE_SWITCH_MERGE If merging of templates containing switch statements is not supported */
|
||||
/* #define JM_NO_TEMPLATE_SWITCH_MERGE */
|
||||
|
||||
/* RE_CALL Optionally define a calling convention for C++ functions */
|
||||
/* #define RE_CALL */
|
||||
|
||||
/* RE_CCALL Optionally define a calling convention for C functions */
|
||||
/* #define RE_CCALL */
|
||||
|
||||
/* JM_SIZEOF_SHORT sizeof(short) */
|
||||
/* #define JM_SIZEOF_SHORT */
|
||||
|
||||
/* JM_SIZEOF_INT sizeof(int) */
|
||||
/* #define JM_SIZEOF_INT */
|
||||
|
||||
/* JM_SIZEOF_LONG sizeof(long) */
|
||||
/* #define JM_SIZEOF_LONG */
|
||||
|
||||
/* JM_SIZEOF_WCHAR_T sizeof(wchar_t) */
|
||||
/* #define JM_SIZEOF_WCHAR_T */
|
||||
|
||||
|
||||
/* STL options: */
|
||||
|
||||
/* JM_NO_EXCEPTION_H Define if you do not a compliant <exception>
|
||||
header file. */
|
||||
/* #define JM_NO_EXCEPTION_H */
|
||||
|
||||
/* JM_NO_ITERATOR_H Define if you do not have a version of <iterator>. */
|
||||
/* #define JM_NO_ITERATOR_H */
|
||||
|
||||
/* JM_NO_MEMORY_H Define if <memory> does not fully comply with the
|
||||
latest standard, and is not auto-recognised,
|
||||
that means nested template classes
|
||||
which hardly any compilers support at present. */
|
||||
/* #define JM_NO_MEMORY_H */
|
||||
|
||||
/* JM_NO_LOCALE_H Define if there is no verion of the standard
|
||||
<locale> header available. */
|
||||
/* #define JM_NO_LOCALE_H */
|
||||
|
||||
/* JM_NO_STL Disables the use of any supporting STL code. */
|
||||
/* #define JM_NO_STL */
|
||||
|
||||
/* JM_NO_NOT_EQUAL Disables the generation of operator!= if this
|
||||
clashes with the STL version. */
|
||||
|
||||
/* JM_NO_STRING_H Define if <string> not available */
|
||||
/* #define JM_NO_STRING_H */
|
||||
|
||||
/* JM_NO_STRING_DEF_ARGS Define if std::basic_string<charT> not allowed - in
|
||||
other words if the template is missing its required
|
||||
default arguments. */
|
||||
/* #define JM_NO_STRING_DEF_ARGS */
|
||||
|
||||
/* JM_NO_TYPEINFO Define if <typeinfo> is absent or non-standard */
|
||||
/* #define JM_NO_TYPEINFO */
|
||||
|
||||
/* JM_USE_ALGO If <algo.h> not <algorithm> is present */
|
||||
/* #define JM_USE_ALGO */
|
||||
|
||||
/* JM_OLD_IOSTREAM If the new iostreamm classes are not available */
|
||||
/* #define JM_OLD_IOSTREAM */
|
||||
|
||||
/* JM_DISTANCE_T For std::distance:
|
||||
0 = NA
|
||||
1 = std::distance(i, j, n)
|
||||
2 = n = std::distance(i, j) */
|
||||
/* #define JM_DISTANCE_T */
|
||||
|
||||
/* JM_ITERATOR_T Defines generic standard iterator type if available, use this as
|
||||
a shortcut to define all the other iterator types.
|
||||
1 = __JM_STD::iterator<__JM_STD::tag_type, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::tag_type, T, D> */
|
||||
/* #define JM_ITERATOR_T */
|
||||
|
||||
/* JM_OI_T For output iterators:
|
||||
0 = NA
|
||||
1 = __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D>
|
||||
3 = __JM_STD::output_iterator */
|
||||
/* #define JM_OI_T */
|
||||
|
||||
/* JM_II_T For input iterators:
|
||||
0 = NA
|
||||
1 = __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D>
|
||||
3 = __JM_STD::input_iterator<T, D>
|
||||
4 = __JM_STD::input_iterator<T> */
|
||||
/* #define JM_II_T */
|
||||
|
||||
/* JM_FI_T For forward iterators:
|
||||
0 = NA
|
||||
1 = __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D>
|
||||
3 = __JM_STD::forward_iterator<T, D> */
|
||||
/* #define JM_FI_T */
|
||||
|
||||
/* JM_BI_T For bidirectional iterators:
|
||||
0 = NA
|
||||
1 = __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D>
|
||||
3 = __JM_STD::bidirectional_iterator<T, D> */
|
||||
/* #define JM_BI_T */
|
||||
|
||||
/* JM_RI_T For random access iterators:
|
||||
0 = NA
|
||||
1 = __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
|
||||
2 = __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D>
|
||||
3 = __JM_STD::random_access_iterator<T, D> */
|
||||
/* #define JM_RI_T */
|
||||
|
||||
/* JM_NO_OI_ASSIGN If output iterators ostream_iterator<>, back_insert_iterator<> and
|
||||
front_insert_iterator<> do not have assignment operators */
|
||||
/* #define JM_NO_OI_ASSIGN */
|
||||
|
||||
|
||||
#if JM_INT64_T == 0
|
||||
#define JM_NO_INT64
|
||||
#elif JM_INT64_T == 1
|
||||
#define JM_INT64t short
|
||||
#define JM_IMM64(val) val
|
||||
#elif JM_INT64_T == 2
|
||||
#define JM_INT64t int
|
||||
#define JM_IMM64(val) val
|
||||
#elif JM_INT64_T == 3
|
||||
#define JM_INT64t long
|
||||
#define JM_IMM64(val) val##L
|
||||
#elif JM_INT64_T == 4
|
||||
#define JM_INT64t int64_t
|
||||
#define JM_IMM64(val) INT64_C(val)
|
||||
#elif JM_INT64_T == 5
|
||||
#define JM_INT64t long long
|
||||
#define JM_IMM64(val) val##LL
|
||||
#elif JM_INT64_T == 6
|
||||
#define JM_INT64t __int64
|
||||
#define JM_IMM64(val) val##i64
|
||||
#else
|
||||
syntax error: unknown value for JM_INT64_T
|
||||
#endif
|
||||
|
||||
#if JM_DISTANCE_T == 0
|
||||
# define JM_DISTANCE(i, j, n) n = j - i
|
||||
#elif JM_DISTANCE_T == 1
|
||||
# define JM_DISTANCE(i, j, n) n = __JM_STD::distance(i, j)
|
||||
#elif JM_DISTANCE_T == 2
|
||||
# define JM_DISTANCE(i, j, n) (n = 0, __JM_STD::distance(i, j, n))
|
||||
#else
|
||||
syntax erorr
|
||||
#endif
|
||||
|
||||
#ifdef JM_ITERATOR_T
|
||||
#ifndef JM_OI_T
|
||||
#define JM_OI_T JM_ITERATOR_T
|
||||
#endif
|
||||
#ifndef JM_II_T
|
||||
#define JM_II_T JM_ITERATOR_T
|
||||
#endif
|
||||
#ifndef JM_FI_T
|
||||
#define JM_FI_T JM_ITERATOR_T
|
||||
#endif
|
||||
#ifndef JM_BI_T
|
||||
#define JM_BI_T JM_ITERATOR_T
|
||||
#endif
|
||||
#ifndef JM_RI_T
|
||||
#define JM_RI_T JM_ITERATOR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if JM_OI_T == 0
|
||||
# define JM_OUTPUT_ITERATOR(T, D) dummy_iterator_base<T>
|
||||
#elif JM_OI_T == 1
|
||||
# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D, T*, T&>
|
||||
#elif JM_OI_T == 2
|
||||
# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::output_iterator_tag, T, D>
|
||||
#elif JM_OI_T == 3
|
||||
# define JM_OUTPUT_ITERATOR(T, D) __JM_STD::output_iterator
|
||||
#else
|
||||
syntax error
|
||||
#endif
|
||||
|
||||
#if JM_II_T == 0
|
||||
# define JM_INPUT_ITERATOR(T, D) dummy_iterator_base<T>
|
||||
#elif JM_II_T == 1
|
||||
#define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D, T*, T&>
|
||||
#elif JM_II_T == 2
|
||||
#define JM_INPUT_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::input_iterator_tag, T, D>
|
||||
#elif JM_II_T == 3
|
||||
# define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T, D>
|
||||
#elif JM_II_T == 4
|
||||
# define JM_INPUT_ITERATOR(T, D) __JM_STD::input_iterator<T>
|
||||
#else
|
||||
syntax error
|
||||
#endif
|
||||
|
||||
#if JM_FI_T == 0
|
||||
# define JM_FWD_ITERATOR(T, D) dummy_iterator_base<T>
|
||||
#elif JM_FI_T == 1
|
||||
# define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D, T*, T&>
|
||||
#elif JM_FI_T == 2
|
||||
# define JM_FWD_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::forward_iterator_tag, T, D>
|
||||
#elif JM_FI_T == 3
|
||||
# define JM_FWD_ITERATOR(T, D) __JM_STD::forward_iterator<T, D>
|
||||
#else
|
||||
syntax error
|
||||
#endif
|
||||
|
||||
#if JM_BI_T == 0
|
||||
# define JM_BIDI_ITERATOR(T, D) dummy_iterator_base<T>
|
||||
#elif JM_BI_T == 1
|
||||
# define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D, T*, T&>
|
||||
#elif JM_BI_T == 2
|
||||
# define JM_BIDI_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::bidirectional_iterator_tag, T, D>
|
||||
#elif JM_BI_T == 3
|
||||
# define JM_BIDI_ITERATOR(T, D) __JM_STD::bidirectional_iterator<T, D>
|
||||
#else
|
||||
syntax error
|
||||
#endif
|
||||
|
||||
#if JM_RI_T == 0
|
||||
# define JM_RA_ITERATOR(T, D) dummy_iterator_base<T>
|
||||
#elif JM_RI_T == 1
|
||||
# define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D, T*, T&>
|
||||
#elif JM_RI_T == 2
|
||||
# define JM_RA_ITERATOR(T, D) __JM_STD::iterator<__JM_STD::random_access_iterator_tag, T, D>
|
||||
#elif JM_RI_T == 3
|
||||
# define JM_RA_ITERATOR(T, D) __JM_STD::random_access_iterator<T, D>
|
||||
#else
|
||||
syntax error
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef JM_NO_EXCEPTION_H
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#ifndef JM_NO_ITERATOR_H
|
||||
#include <iterator>
|
||||
#ifdef JM_USE_ALGO
|
||||
#include <algo.h>
|
||||
#else
|
||||
#include <algorithm>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef JM_NO_MEMORY_H
|
||||
#define JM_OLD_ALLOCATORS
|
||||
#define REBIND_INSTANCE(x, y, inst) re_alloc_binder<x, y>(inst)
|
||||
#define REBIND_TYPE(x, y) re_alloc_binder<x, y>
|
||||
#define JM_DEF_ALLOC_PARAM(x) JM_DEFAULT_PARAM( jm_def_alloc )
|
||||
#define JM_DEF_ALLOC(x) jm_def_alloc
|
||||
|
||||
#define JM_NEED_BINDER
|
||||
#define JM_NEED_ALLOC
|
||||
#else
|
||||
#include <memory>
|
||||
#define REBIND_INSTANCE(x, y, inst) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other(inst)
|
||||
#define REBIND_TYPE(x, y) y::JM_NESTED_TEMPLATE_DECL rebind<x>::other
|
||||
#define JM_DEF_ALLOC_PARAM(x) JM_TRICKY_DEFAULT_PARAM( __JM_STD::allocator<x> )
|
||||
#define JM_DEF_ALLOC(x) __JM_STD::allocator<x>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // JM_AUTO_CONFIGURE
|
||||
|
||||
|
||||
#endif /* JM_OPT_H */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE jstack.h
|
||||
* VERSION 2.12
|
||||
*/
|
||||
|
||||
#ifndef __JSTACH_H
|
||||
#define __JSTACK_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
//
|
||||
// class jstack
|
||||
// simplified stack optimised for push/peek/pop
|
||||
// operations, we could use std::stack<std::vector<T>> instead...
|
||||
//
|
||||
template <class T, class Allocator JM_DEF_ALLOC_PARAM(T) >
|
||||
class jstack
|
||||
{
|
||||
private:
|
||||
typedef JM_MAYBE_TYPENAME REBIND_TYPE(unsigned char, Allocator) alloc_type;
|
||||
typedef typename REBIND_TYPE(T, Allocator)::size_type size_type;
|
||||
struct node
|
||||
{
|
||||
node* next;
|
||||
T* start; // first item
|
||||
T* end; // last item
|
||||
T* last; // end of storage
|
||||
};
|
||||
|
||||
//
|
||||
// empty base member optimisation:
|
||||
struct data : public alloc_type
|
||||
{
|
||||
unsigned char buf[sizeof(T)*16];
|
||||
data(const Allocator& a) : alloc_type(a){}
|
||||
};
|
||||
|
||||
data alloc_inst;
|
||||
mutable node* stack;
|
||||
mutable node* unused;
|
||||
node base;
|
||||
size_type block_size;
|
||||
|
||||
void RE_CALL pop_aux()const;
|
||||
void RE_CALL push_aux();
|
||||
|
||||
public:
|
||||
jstack(size_type n = 64, const Allocator& a = Allocator());
|
||||
|
||||
~jstack();
|
||||
|
||||
node* RE_CALL get_node()
|
||||
{
|
||||
node* new_stack = (node*)alloc_inst.allocate(sizeof(node) + sizeof(T) * block_size);
|
||||
new_stack->last = (T*)(new_stack+1);
|
||||
new_stack->start = new_stack->end = new_stack->last + block_size;
|
||||
new_stack->next = 0;
|
||||
return new_stack;
|
||||
}
|
||||
|
||||
bool RE_CALL empty()
|
||||
{
|
||||
return (stack->start == stack->end) && (stack->next == 0);
|
||||
}
|
||||
|
||||
bool RE_CALL good()
|
||||
{
|
||||
return (stack->start != stack->end) || (stack->next != 0);
|
||||
}
|
||||
|
||||
T& RE_CALL peek()
|
||||
{
|
||||
if(stack->start == stack->end)
|
||||
pop_aux();
|
||||
return *stack->end;
|
||||
}
|
||||
|
||||
const T& RE_CALL peek()const
|
||||
{
|
||||
if(stack->start == stack->end)
|
||||
pop_aux();
|
||||
return *stack->end;
|
||||
}
|
||||
|
||||
void RE_CALL pop()
|
||||
{
|
||||
if(stack->start == stack->end)
|
||||
pop_aux();
|
||||
jm_destroy(stack->end);
|
||||
++(stack->end);
|
||||
}
|
||||
|
||||
void RE_CALL pop(T& t)
|
||||
{
|
||||
if(stack->start == stack->end)
|
||||
pop_aux();
|
||||
t = *stack->end;
|
||||
jm_destroy(stack->end);
|
||||
++(stack->end);
|
||||
}
|
||||
|
||||
void RE_CALL push(const T& t)
|
||||
{
|
||||
if(stack->end == stack->last)
|
||||
push_aux();
|
||||
--(stack->end);
|
||||
jm_construct(stack->end, t);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
jstack<T, Allocator>::jstack(size_type n, const Allocator& a)
|
||||
: alloc_inst(a)
|
||||
{
|
||||
unused = 0;
|
||||
block_size = n;
|
||||
stack = &base;
|
||||
base.last = (T*)alloc_inst.buf;
|
||||
base.end = base.start = base.last + 16;
|
||||
base.next = 0;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
void RE_CALL jstack<T, Allocator>::push_aux()
|
||||
{
|
||||
// make sure we have spare space on TOS:
|
||||
register node* new_node;
|
||||
if(unused)
|
||||
{
|
||||
new_node = unused;
|
||||
unused = new_node->next;
|
||||
new_node->next = stack;
|
||||
stack = new_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_node = get_node();
|
||||
new_node->next = stack;
|
||||
stack = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
void RE_CALL jstack<T, Allocator>::pop_aux()const
|
||||
{
|
||||
// make sure that we have a valid item
|
||||
// on TOS:
|
||||
jm_assert(stack->next);
|
||||
register node* p = stack;
|
||||
stack = p->next;
|
||||
p->next = unused;
|
||||
unused = p;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
jstack<T, Allocator>::~jstack()
|
||||
{
|
||||
node* condemned;
|
||||
while(good())
|
||||
pop();
|
||||
while(unused)
|
||||
{
|
||||
condemned = unused;
|
||||
unused = unused->next;
|
||||
alloc_inst.deallocate((unsigned char*)condemned, sizeof(node) + sizeof(T) * block_size);
|
||||
}
|
||||
while(stack != &base)
|
||||
{
|
||||
condemned = stack;
|
||||
stack = stack->next;
|
||||
alloc_inst.deallocate((unsigned char*)condemned, sizeof(node) + sizeof(T) * block_size);
|
||||
}
|
||||
}
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_cls.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly.
|
||||
* character class lookup, for regular
|
||||
* expression library.
|
||||
*/
|
||||
|
||||
#ifndef RE_CLS_H
|
||||
#define RE_CLS_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#ifndef RE_STR_H
|
||||
#include <jm/re_str.h>
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
#define re_classes_max 14
|
||||
|
||||
void RE_CALL re_init_classes();
|
||||
void RE_CALL re_free_classes();
|
||||
void RE_CALL re_update_classes();
|
||||
JM_IX_DECL jm_uintfast32_t RE_CALL __re_lookup_class(const char* p);
|
||||
|
||||
inline jm_uintfast32_t RE_CALL re_lookup_class(const char* first, const char* last)
|
||||
{
|
||||
re_str<char> s(first, last);
|
||||
return __re_lookup_class(s.c_str());
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
inline jm_uintfast32_t RE_CALL re_lookup_class(const wchar_t* first, const wchar_t* last)
|
||||
{
|
||||
re_str<wchar_t> s(first, last);
|
||||
unsigned int len = re_strnarrow((char*)NULL, 0, s.c_str());
|
||||
auto_array<char> buf(new char[len]);
|
||||
re_strnarrow((char*)buf, len, s.c_str());
|
||||
len = __re_lookup_class((char*)buf);
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
|
||||
extern jm_uintfast32_t re_char_class_id[];
|
||||
extern const char* re_char_class_names[];
|
||||
|
||||
#endif
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_coll.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly
|
||||
*/
|
||||
|
||||
#ifndef RE_COLL_H
|
||||
#define RE_COLL_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#ifndef RE_STR_H
|
||||
#include <re_str.h>
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
JM_IX_DECL bool RE_CALL re_lookup_def_collate_name(re_str<char>& buf, const char* name);
|
||||
|
||||
void RE_CALL re_init_collate();
|
||||
void RE_CALL re_free_collate();
|
||||
void RE_CALL re_update_collate();
|
||||
JM_IX_DECL bool RE_CALL __re_lookup_collate(re_str<char>& buf, const char* p);
|
||||
|
||||
inline bool RE_CALL re_lookup_collate(re_str<char>& buf, const char* first, const char* last)
|
||||
{
|
||||
re_str<char> s(first, last);
|
||||
return __re_lookup_collate(buf, s.c_str());
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_IX_DECL bool RE_CALL re_lookup_collate(re_str<wchar_t>& out, const wchar_t* first, const wchar_t* last);
|
||||
#endif
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_kmp.h
|
||||
* VERSION 2.12
|
||||
* Knuth-Morris-Pratt search.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __RE_KMP_H
|
||||
#define __RE_KMP_H
|
||||
|
||||
#ifdef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
template <class charT>
|
||||
struct kmp_info
|
||||
{
|
||||
unsigned int size;
|
||||
unsigned int len;
|
||||
const charT* pstr;
|
||||
int kmp_next[1];
|
||||
};
|
||||
|
||||
template <class charT, class Allocator>
|
||||
void kmp_free(kmp_info<charT>* pinfo, Allocator a)
|
||||
{
|
||||
typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
|
||||
atype(a).deallocate((char*)pinfo, pinfo->size);
|
||||
}
|
||||
|
||||
template <class iterator, class charT, class Trans, class Allocator>
|
||||
kmp_info<charT>* kmp_compile(iterator first, iterator last, charT, Trans translate, Allocator a
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef JM_MAYBE_TYPENAME REBIND_TYPE(char, Allocator) atype;
|
||||
int i, j, m;
|
||||
i = 0;
|
||||
m = 0;
|
||||
JM_DISTANCE(first, last, m);
|
||||
++m;
|
||||
unsigned int size = sizeof(kmp_info<charT>) + sizeof(int)*m + sizeof(charT)*m;
|
||||
--m;
|
||||
//
|
||||
// allocate struct and fill it in:
|
||||
//
|
||||
kmp_info<charT>* pinfo = (kmp_info<charT>*)atype(a).allocate(size);
|
||||
pinfo->size = size;
|
||||
pinfo->len = m;
|
||||
charT* p = (charT*)((char*)pinfo + sizeof(kmp_info<charT>) + sizeof(int)*(m+1));
|
||||
pinfo->pstr = p;
|
||||
while(first != last)
|
||||
{
|
||||
*p = translate(*first MAYBE_PASS_LOCALE(l));
|
||||
++first;
|
||||
++p;
|
||||
}
|
||||
*p = 0;
|
||||
//
|
||||
// finally do regular kmp compile:
|
||||
//
|
||||
j = pinfo->kmp_next[0] = -1;
|
||||
while (i < m)
|
||||
{
|
||||
while ((j > -1) && (pinfo->pstr[i] != pinfo->pstr[j]))
|
||||
j = pinfo->kmp_next[j];
|
||||
++i;
|
||||
++j;
|
||||
if (pinfo->pstr[i] == pinfo->pstr[j])
|
||||
pinfo->kmp_next[i] = pinfo->kmp_next[j];
|
||||
else
|
||||
pinfo->kmp_next[i] = j;
|
||||
}
|
||||
|
||||
return pinfo;
|
||||
}
|
||||
|
||||
|
||||
JM_END_NAMESPACE // namespace regex
|
||||
|
||||
#endif // __RE_KMP_H
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_lib.h
|
||||
* VERSION 2.12
|
||||
* Automatic library file inclusion.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef RE_LIB_H
|
||||
#define RE_LIB_H
|
||||
|
||||
#if defined(_MSC_VER) && !defined(RE_BUILD_DLL)
|
||||
#ifdef _DLL
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "mre200dl.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "mre200l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "mre200dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "mre200m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "mre200d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "mre200.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#endif //_MSC_VER
|
||||
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(RE_BUILD_DLL)
|
||||
#if (__BORLANDC__ > 0x520) && !defined(_NO_VCL)
|
||||
#define JM_USE_VCL
|
||||
#endif
|
||||
|
||||
#if __BORLANDC__ <= 0x520
|
||||
|
||||
#ifdef JM_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "b2re200lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "b2re200v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b2re200lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b2re200l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b2re200m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b2re200.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#elif __BORLANDC__ <= 0x530
|
||||
|
||||
#ifdef JM_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "b3re200lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "b3re200v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b3re200lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b3re200l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b3re200m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b3re200.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#else // Version: 0x540
|
||||
|
||||
#ifdef JM_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "b4re200lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "b4re200v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b4re200lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b4re200l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "b4re200m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "b4re200.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#endif
|
||||
|
||||
#endif //__BORLANDC__
|
||||
|
||||
|
||||
#endif // RE_LIB_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_lst.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly.
|
||||
* re_list support class, for regular
|
||||
* expression library.
|
||||
*/
|
||||
|
||||
#ifndef RE_LST_H
|
||||
#define RE_LST_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#include <new.h>
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
template <class T, class Allocator>
|
||||
class re_list
|
||||
{
|
||||
public:
|
||||
struct node
|
||||
{
|
||||
node* next;
|
||||
T t;
|
||||
node(const T& o) : t(o) {}
|
||||
};
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
node* pos;
|
||||
public:
|
||||
iterator() { pos = 0; }
|
||||
~iterator() {}
|
||||
iterator(const iterator& i) { pos = i.pos; }
|
||||
iterator(node* n) { pos = n; }
|
||||
iterator& operator=(const iterator& i)
|
||||
{
|
||||
pos = i.pos;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(iterator& i)
|
||||
{
|
||||
return pos == i.pos;
|
||||
}
|
||||
bool operator!=(iterator& i)
|
||||
{
|
||||
return pos != i.pos;
|
||||
}
|
||||
T& operator*() { return pos->t; }
|
||||
iterator& operator++()
|
||||
{
|
||||
pos = pos->next;
|
||||
return *this;
|
||||
}
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator t(*this);
|
||||
pos = pos->next;
|
||||
return t;
|
||||
}
|
||||
const node* tell()const
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
{
|
||||
const node* pos;
|
||||
public:
|
||||
const_iterator() { pos = 0; }
|
||||
~const_iterator() {}
|
||||
const_iterator(const const_iterator& i) { pos = i.pos; }
|
||||
const_iterator(const iterator& i) { pos = i.tell(); }
|
||||
const_iterator(const node* n) { pos = n; }
|
||||
const_iterator& operator=(const iterator& i)
|
||||
{
|
||||
pos = i.tell();
|
||||
return *this;
|
||||
}
|
||||
const_iterator& operator=(const const_iterator& i)
|
||||
{
|
||||
pos = i.pos;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const_iterator& i)
|
||||
{
|
||||
return pos == i.pos;
|
||||
}
|
||||
bool operator!=(const_iterator& i)
|
||||
{
|
||||
return pos != i.pos;
|
||||
}
|
||||
const T& operator*() { return pos->t; }
|
||||
const_iterator& operator++()
|
||||
{
|
||||
pos = pos->next;
|
||||
return *this;
|
||||
}
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
const_iterator t(*this);
|
||||
pos = pos->next;
|
||||
return t;
|
||||
}
|
||||
};
|
||||
private:
|
||||
typedef JM_MAYBE_TYPENAME REBIND_TYPE(node, Allocator) node_alloc;
|
||||
|
||||
struct data : public node_alloc
|
||||
{
|
||||
node* first;
|
||||
data(const Allocator& a) : node_alloc(a), first(0) {}
|
||||
};
|
||||
data alloc_inst;
|
||||
|
||||
public:
|
||||
re_list(const Allocator& a = Allocator()) : alloc_inst(a) {}
|
||||
~re_list() { clear(); }
|
||||
iterator RE_CALL begin() { return iterator(alloc_inst.first); }
|
||||
iterator RE_CALL end() { return iterator(0); }
|
||||
const_iterator RE_CALL begin()const { return const_iterator(alloc_inst.first); }
|
||||
const_iterator RE_CALL end()const { return const_iterator(0); }
|
||||
void RE_CALL add(const T& t)
|
||||
{
|
||||
node* temp;
|
||||
temp = alloc_inst.allocate(1);
|
||||
#ifndef JM_NO_EXCEPTIONS
|
||||
try{
|
||||
#endif
|
||||
alloc_inst.construct(temp, t);
|
||||
#ifndef JM_NO_EXCEPTIONS
|
||||
}catch(...){ alloc_inst.deallocate(temp, 1); throw; }
|
||||
#endif
|
||||
temp->next = alloc_inst.first;
|
||||
alloc_inst.first = temp;
|
||||
}
|
||||
void RE_CALL clear();
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
void RE_CALL re_list<T, Allocator>::clear()
|
||||
{
|
||||
node* temp;
|
||||
while(alloc_inst.first)
|
||||
{
|
||||
temp = alloc_inst.first;
|
||||
alloc_inst.first = alloc_inst.first->next;
|
||||
alloc_inst.destroy(temp);
|
||||
alloc_inst.deallocate(temp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_mss.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly.
|
||||
* Message helper functions, for regular
|
||||
* expression library.
|
||||
*/
|
||||
|
||||
#ifndef RE_MSS_H
|
||||
#define RE_MSS_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
//
|
||||
// re_get_message
|
||||
// returns required buffer size if len is zero
|
||||
// otherwise fills in buf.
|
||||
//
|
||||
|
||||
JM_IX_DECL unsigned int RE_CALL re_get_default_message(char* buf, unsigned int len, unsigned int id);
|
||||
|
||||
JM_IX_DECL unsigned int RE_CALL __re_get_message(char* buf, unsigned int len, unsigned int id);
|
||||
|
||||
template <class charT>
|
||||
unsigned int RE_CALL re_get_message(charT* buf, unsigned int len, unsigned int id)
|
||||
{
|
||||
unsigned int size = __re_get_message((char*)0, 0, id);
|
||||
if(len < size)
|
||||
return size;
|
||||
auto_array<char> cb(new char[size]);
|
||||
__re_get_message((char*)cb, size, id);
|
||||
size = re_strwiden(buf, len, (char*)cb);
|
||||
return size;
|
||||
}
|
||||
|
||||
inline unsigned int RE_CALL re_get_message(char* buf, unsigned int len, unsigned int id)
|
||||
{
|
||||
return __re_get_message(buf, len, id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// declare message initialisers:
|
||||
//
|
||||
void RE_CALL re_message_init();
|
||||
void RE_CALL re_message_update();
|
||||
void RE_CALL re_message_free();
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
|
||||
__JM_STD::messages<char>::string_type RE_CALL re_get_def_message(unsigned int i);
|
||||
|
||||
__JM_STD::messages<wchar_t>::string_type RE_CALL re_get_def_message_w(unsigned int i);
|
||||
|
||||
extern const char *re_default_error_messages[];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_nls.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly
|
||||
*/
|
||||
|
||||
#ifndef RE_NLS_H
|
||||
#define RE_NLS_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
#include <jm/regfac.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
enum char_class_type
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
char_class_none = 0,
|
||||
char_class_alnum = __JM_STD::ctype_base::alnum,
|
||||
char_class_alpha = __JM_STD::ctype_base::alpha,
|
||||
char_class_cntrl = __JM_STD::ctype_base::cntrl,
|
||||
char_class_digit = __JM_STD::ctype_base::digit,
|
||||
char_class_graph = __JM_STD::ctype_base::graph,
|
||||
char_class_lower = __JM_STD::ctype_base::lower,
|
||||
char_class_print = __JM_STD::ctype_base::print,
|
||||
char_class_punct = __JM_STD::ctype_base::punct,
|
||||
char_class_space = __JM_STD::ctype_base::space,
|
||||
char_class_upper = __JM_STD::ctype_base::upper,
|
||||
char_class_xdigit = __JM_STD::ctype_base::xdigit,
|
||||
char_class_blank = 1<<12,
|
||||
char_class_underscore = 1<<13,
|
||||
char_class_word = __JM_STD::ctype_base::alnum | char_class_underscore,
|
||||
char_class_unicode = 1<<14,
|
||||
char_class_all_base = char_class_alnum | char_class_alpha | char_class_cntrl
|
||||
| char_class_digit | char_class_graph | char_class_lower
|
||||
| char_class_print | char_class_punct | char_class_space
|
||||
| char_class_upper | char_class_xdigit
|
||||
|
||||
#elif defined(RE_LOCALE_W32)
|
||||
char_class_none = 0,
|
||||
char_class_alnum = C1_ALPHA | C1_DIGIT,
|
||||
char_class_alpha = C1_ALPHA,
|
||||
char_class_cntrl = C1_CNTRL,
|
||||
char_class_digit = C1_DIGIT,
|
||||
char_class_graph = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA,
|
||||
char_class_lower = C1_LOWER,
|
||||
char_class_print = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_BLANK | C1_ALPHA,
|
||||
char_class_punct = C1_PUNCT,
|
||||
char_class_space = C1_SPACE,
|
||||
char_class_upper = C1_UPPER,
|
||||
char_class_xdigit = C1_XDIGIT,
|
||||
char_class_blank = C1_BLANK,
|
||||
char_class_underscore = 0x0200,
|
||||
char_class_word = C1_ALPHA | C1_DIGIT | char_class_underscore,
|
||||
char_class_unicode = 0x0400
|
||||
#else
|
||||
char_class_none = 0,
|
||||
char_class_alpha = 1,
|
||||
char_class_cntrl = char_class_alpha << 1,
|
||||
char_class_digit = char_class_cntrl << 1,
|
||||
char_class_lower = char_class_digit << 1,
|
||||
char_class_punct = char_class_lower << 1,
|
||||
char_class_space = char_class_punct << 1,
|
||||
char_class_upper = char_class_space << 1,
|
||||
char_class_xdigit = char_class_upper << 1,
|
||||
char_class_blank = char_class_xdigit << 1,
|
||||
char_class_unicode = char_class_blank << 1,
|
||||
char_class_underscore = char_class_unicode << 1,
|
||||
|
||||
char_class_alnum = char_class_alpha | char_class_digit,
|
||||
char_class_graph = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore,
|
||||
char_class_print = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore | char_class_blank,
|
||||
char_class_word = char_class_alpha | char_class_digit | char_class_underscore
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// declare our initialise class and functions:
|
||||
//
|
||||
|
||||
template <class charT>
|
||||
class re_initialiser
|
||||
{
|
||||
public:
|
||||
void update();
|
||||
};
|
||||
|
||||
JM_IX_DECL void RE_CALL re_init();
|
||||
JM_IX_DECL void RE_CALL re_update();
|
||||
JM_IX_DECL void RE_CALL re_free();
|
||||
JM_IX_DECL void RE_CALL re_init_w();
|
||||
JM_IX_DECL void RE_CALL re_update_w();
|
||||
JM_IX_DECL void RE_CALL re_free_w();
|
||||
|
||||
JM_TEMPLATE_SPECIALISE
|
||||
class re_initialiser<char>
|
||||
{
|
||||
public:
|
||||
re_initialiser() { re_init(); }
|
||||
~re_initialiser() { re_free(); }
|
||||
void RE_CALL update() { re_update(); }
|
||||
};
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_TEMPLATE_SPECIALISE
|
||||
class re_initialiser<wchar_t>
|
||||
{
|
||||
public:
|
||||
re_initialiser() { re_init_w(); }
|
||||
~re_initialiser() { re_free_w(); }
|
||||
void RE_CALL update() { re_update_w(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// start by declaring externals for RE_LOCALE_C
|
||||
// and RE_LOCALE_W32:
|
||||
//
|
||||
|
||||
JM_IX_DECL extern unsigned char re_syntax_map[];
|
||||
JM_IX_DECL extern unsigned short re_class_map[];
|
||||
JM_IX_DECL extern char re_lower_case_map[];
|
||||
JM_IX_DECL extern char re_zero;
|
||||
JM_IX_DECL extern char re_ten;
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_IX_DECL extern unsigned short re_unicode_classes[];
|
||||
JM_IX_DECL extern const wchar_t* re_lower_case_map_w;
|
||||
JM_IX_DECL extern wchar_t re_zero_w;
|
||||
JM_IX_DECL extern wchar_t re_ten_w;
|
||||
|
||||
JM_IX_DECL wchar_t RE_CALL re_wtolower(wchar_t c);
|
||||
JM_IX_DECL bool RE_CALL re_iswclass(wchar_t c, jm_uintfast32_t f);
|
||||
#endif
|
||||
|
||||
JM_IX_DECL const char* RE_CALL re_get_error_str(unsigned int id);
|
||||
JM_IX_DECL unsigned int RE_CALL re_get_syntax_type(wchar_t c);
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
__JM_STD::string RE_CALL re_get_error_str(unsigned int id, const __JM_STD::locale&);
|
||||
#endif
|
||||
|
||||
//
|
||||
// add some API's for character manipulation:
|
||||
//
|
||||
inline char RE_CALL re_tolower(char c
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, __JM_STD::ctype<char>).tolower(c);
|
||||
#else
|
||||
return re_lower_case_map[(unsigned char)c];
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
inline wchar_t RE_CALL re_tolower(wchar_t c
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).tolower(c);
|
||||
#else
|
||||
return c < 256 ? re_lower_case_map_w[c] : re_wtolower(c);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool RE_CALL re_istype(char c, jm_uintfast32_t f
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
if(JM_USE_FACET(l, __JM_STD::ctype<char>).is((__JM_STD::ctype<char>::mask)(f & char_class_all_base), c))
|
||||
return true;
|
||||
if((f & char_class_underscore) && (c == '_'))
|
||||
return true;
|
||||
if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
|
||||
return true;
|
||||
return false;
|
||||
#else
|
||||
return re_class_map[(unsigned char)c] & f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
inline bool RE_CALL re_istype(wchar_t c, jm_uintfast32_t f
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
if(JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).is((__JM_STD::ctype<wchar_t>::mask)(f & char_class_all_base), c))
|
||||
return true;
|
||||
if((f & char_class_underscore) && (c == '_'))
|
||||
return true;
|
||||
if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
|
||||
return true;
|
||||
return false;
|
||||
#else
|
||||
return c < 256 ? re_unicode_classes[c] & f : re_iswclass(c, f);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
inline char RE_CALL re_get_zero(char
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, regfacet<char>).zero();
|
||||
#else
|
||||
return re_zero;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
inline wchar_t RE_CALL re_get_zero(wchar_t
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, regfacet<wchar_t>).zero();
|
||||
#else
|
||||
return re_zero_w;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
inline char RE_CALL re_get_ten(char
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, regfacet<char>).ten();
|
||||
#else
|
||||
return re_ten;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
inline wchar_t RE_CALL re_get_ten(wchar_t
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef RE_LOCALE_CPP
|
||||
return JM_USE_FACET(l, regfacet<wchar_t>).ten();
|
||||
#else
|
||||
return re_ten_w;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// re_toi:
|
||||
// convert a single character to the int it represents:
|
||||
//
|
||||
template <class charT>
|
||||
unsigned int RE_CALL re_toi(charT c
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if(re_istype(c, char_class_digit MAYBE_PASS_LOCALE(l)))
|
||||
return c - re_get_zero(c MAYBE_PASS_LOCALE(l));
|
||||
if(re_istype(c, char_class_xdigit MAYBE_PASS_LOCALE(l)))
|
||||
return 10 + re_tolower(c MAYBE_PASS_LOCALE(l)) - re_tolower(re_get_ten(c MAYBE_PASS_LOCALE(l)) MAYBE_PASS_LOCALE(l));
|
||||
return -1; // error!!
|
||||
}
|
||||
|
||||
//
|
||||
// re_toi:
|
||||
// parse an int from the input string
|
||||
// update first to point to end of int
|
||||
// on exit.
|
||||
//
|
||||
template <class charT>
|
||||
unsigned int RE_CALL re_toi(const charT*& first, const charT*const last, int radix
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
unsigned int maxval;
|
||||
if(radix < 0)
|
||||
{
|
||||
// if radix is less than zero, then restrict
|
||||
// return value to charT. NB assumes sizeof(charT) <= sizeof(int)
|
||||
radix *= -1;
|
||||
maxval = 1 << (sizeof(charT) * CHAR_BIT - 1);
|
||||
maxval /= radix;
|
||||
maxval *= 2;
|
||||
maxval -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxval = (unsigned int)-1;
|
||||
maxval /= radix;
|
||||
}
|
||||
|
||||
unsigned int result = 0;
|
||||
unsigned int type = (radix > 10) ? char_class_xdigit : char_class_digit;
|
||||
while((first != last) && re_istype(*first, type MAYBE_PASS_LOCALE(l)) && (result <= maxval))
|
||||
{
|
||||
result *= radix;
|
||||
result += re_toi(*first MAYBE_PASS_LOCALE(l));
|
||||
++first;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_IX_DECL bool RE_CALL re_is_combining(wchar_t c);
|
||||
#endif
|
||||
|
||||
extern const char* regex_message_catalogue;
|
||||
|
||||
JM_IX_DECL const char* RE_CALL get_global_locale_name(int);
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_raw.h
|
||||
* VERSION 2.12
|
||||
*/
|
||||
|
||||
#ifndef RE_RAW_H
|
||||
#define RE_RAW_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
union padding
|
||||
{
|
||||
void* p;
|
||||
unsigned int i;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// class raw_storage
|
||||
// basically this is a simplified vector<unsigned char>
|
||||
// this is used by reg_expression for expression storage
|
||||
//
|
||||
|
||||
template <class Allocator>
|
||||
class raw_storage
|
||||
{
|
||||
public:
|
||||
typedef Allocator alloc_type;
|
||||
typedef typename REBIND_TYPE(unsigned char, alloc_type)::size_type size_type;
|
||||
typedef JM_MAYBE_TYPENAME REBIND_TYPE(unsigned char, alloc_type) alloc_inst_type;
|
||||
typedef typename REBIND_TYPE(unsigned char, alloc_type)::pointer pointer;
|
||||
private:
|
||||
//
|
||||
// empty member optimisation:
|
||||
struct alloc_data : public alloc_inst_type
|
||||
{
|
||||
pointer last;
|
||||
alloc_data(const Allocator& a) : alloc_inst_type(a){}
|
||||
} alloc_inst;
|
||||
pointer start, end;
|
||||
public:
|
||||
|
||||
raw_storage(const Allocator& a = Allocator());
|
||||
raw_storage(size_type n, const Allocator& a = Allocator());
|
||||
|
||||
~raw_storage()
|
||||
{
|
||||
alloc_inst.deallocate(start, (alloc_inst.last - start));
|
||||
}
|
||||
|
||||
void RE_CALL resize(size_type n);
|
||||
|
||||
void* RE_CALL extend(size_type n)
|
||||
{
|
||||
if(size_type(alloc_inst.last - end) < n)
|
||||
resize(n + (end - start));
|
||||
register void* result = end;
|
||||
end += n;
|
||||
return result;
|
||||
}
|
||||
|
||||
void* RE_CALL insert(size_type pos, size_type n);
|
||||
|
||||
size_type RE_CALL size()
|
||||
{
|
||||
return end - start;
|
||||
}
|
||||
|
||||
size_type RE_CALL capacity()
|
||||
{
|
||||
return alloc_inst.last - start;
|
||||
}
|
||||
|
||||
void* RE_CALL data()const
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
size_type RE_CALL index(void* ptr)
|
||||
{
|
||||
return (unsigned char*)ptr - start;
|
||||
}
|
||||
|
||||
void RE_CALL clear()
|
||||
{
|
||||
end = start;
|
||||
}
|
||||
|
||||
void RE_CALL align()
|
||||
{
|
||||
// move end up to a boundary:
|
||||
end = (unsigned char*)((long)(end + sizeof(padding) - 1) & ~((long)sizeof(padding) - 1));
|
||||
}
|
||||
|
||||
Allocator RE_CALL allocator()const;
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(const Allocator& a)
|
||||
: alloc_inst(a)
|
||||
{
|
||||
start = end = alloc_inst.allocate(1024);
|
||||
alloc_inst.last = start + 1024;
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a)
|
||||
: alloc_inst(a)
|
||||
{
|
||||
start = end = alloc_inst.allocate(n);
|
||||
alloc_inst.last = start + n;
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
Allocator RE_CALL raw_storage<Allocator>::allocator()const
|
||||
{
|
||||
return alloc_inst;
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
void RE_CALL raw_storage<Allocator>::resize(size_type n)
|
||||
{
|
||||
register size_type newsize = (alloc_inst.last - start) * 2;
|
||||
register size_type datasize = end - start;
|
||||
if(newsize < n)
|
||||
newsize = n;
|
||||
// extend newsize to WORD/DWORD boundary:
|
||||
newsize = (newsize + (sizeof(padding) - 1)) & ~(sizeof(padding) - 1);
|
||||
|
||||
// allocate and copy data:
|
||||
register unsigned char* ptr = alloc_inst.allocate(newsize);
|
||||
memcpy(ptr, start, datasize);
|
||||
|
||||
// get rid of old buffer:
|
||||
alloc_inst.deallocate(start, (alloc_inst.last - start));
|
||||
|
||||
// and set up pointers:
|
||||
start = ptr;
|
||||
end = ptr + datasize;
|
||||
alloc_inst.last = ptr + newsize;
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
void* RE_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
|
||||
{
|
||||
jm_assert(pos <= size_type(end - start));
|
||||
if(size_type(alloc_inst.last - end) < n)
|
||||
resize(n + (end - start));
|
||||
register void* result = start + pos;
|
||||
memmove(start + pos + n, start + pos, (end - start) - pos);
|
||||
end += n;
|
||||
return result;
|
||||
}
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_str.h
|
||||
* VERSION 2.12
|
||||
* This is an internal header file, do not include directly.
|
||||
* String support and helper functions, for regular
|
||||
* expression library.
|
||||
*/
|
||||
|
||||
#ifndef RE_STR_H
|
||||
#define RE_STR_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
//
|
||||
// start by defining some template function aliases for C API functions:
|
||||
//
|
||||
|
||||
template <class charT>
|
||||
size_t RE_CALL re_strlen(const charT *s)
|
||||
{
|
||||
size_t len = 0;
|
||||
while(*s)
|
||||
{
|
||||
++s;
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
int RE_CALL re_strcmp(const charT *s1, const charT *s2)
|
||||
{
|
||||
while(*s1 && *s2)
|
||||
{
|
||||
if(*s1 != *s2)
|
||||
return *s1 - *s2;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return *s1 - *s2;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
charT* RE_CALL re_strcpy(charT *s1, const charT *s2)
|
||||
{
|
||||
charT* base = s1;
|
||||
while(*s2)
|
||||
{
|
||||
*s1 = *s2;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
*s1 = *s2;
|
||||
return base;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
unsigned int RE_CALL re_strwiden(charT *s1, unsigned int len, const char *s2)
|
||||
{
|
||||
unsigned int result = 1 + re_strlen(s2);
|
||||
if(result > len)
|
||||
return result;
|
||||
while(*s2)
|
||||
{
|
||||
*s1 = (unsigned char)*s2;
|
||||
++s2;
|
||||
++s1;
|
||||
}
|
||||
*s1 = (unsigned char)*s2;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
unsigned int RE_CALL re_strnarrow(char *s1, unsigned int len, const charT *s2)
|
||||
{
|
||||
unsigned int result = 1 + re_strlen(s2);
|
||||
if(result > len)
|
||||
return result;
|
||||
while(*s2)
|
||||
{
|
||||
*s1 = (char)(unsigned char)*s2;
|
||||
++s2;
|
||||
++s1;
|
||||
}
|
||||
*s1 = (char)(unsigned char)*s2;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline size_t RE_CALL re_strlen(const char *s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
||||
|
||||
inline int RE_CALL re_strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
inline char* RE_CALL re_strcpy(char *s1, const char *s2)
|
||||
{
|
||||
return strcpy(s1, s2);
|
||||
}
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
|
||||
inline size_t RE_CALL re_strlen(const wchar_t *s)
|
||||
{
|
||||
return wcslen(s);
|
||||
}
|
||||
|
||||
inline int RE_CALL re_strcmp(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
return wcscmp(s1, s2);
|
||||
}
|
||||
|
||||
inline wchar_t* RE_CALL re_strcpy(wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
return wcscpy(s1, s2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(JM_NO_WCSTRING) || defined(JM_PLATFORM_W32)
|
||||
|
||||
JM_IX_DECL unsigned int RE_CALL _re_strnarrow(char *s1, unsigned int len, const wchar_t *s2);
|
||||
JM_IX_DECL unsigned int RE_CALL _re_strwiden(wchar_t *s1, unsigned int len, const char *s2);
|
||||
|
||||
|
||||
inline unsigned int RE_CALL re_strnarrow(char *s1, unsigned int len, const wchar_t *s2)
|
||||
{
|
||||
return _re_strnarrow(s1, len, s2);
|
||||
}
|
||||
|
||||
inline unsigned int RE_CALL re_strwiden(wchar_t *s1, unsigned int len, const char *s2)
|
||||
{
|
||||
return _re_strwiden(s1, len, s2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class charT>
|
||||
charT* RE_CALL re_strdup(const charT* p)
|
||||
{
|
||||
charT* buf = new charT[re_strlen(p) + 1];
|
||||
re_strcpy(buf, p);
|
||||
return buf;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
charT* RE_CALL re_strdup(const charT* p1, const charT* p2)
|
||||
{
|
||||
unsigned int len = p2 - p1 + 1;
|
||||
charT* buf = new charT[len];
|
||||
memcpy(buf, p1, (len - 1) * sizeof(charT));
|
||||
*(buf + len - 1) = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
inline void RE_CALL re_strfree(charT* p)
|
||||
{
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
class re_str
|
||||
{
|
||||
charT* buf;
|
||||
public:
|
||||
re_str()
|
||||
{
|
||||
charT c = 0;
|
||||
buf = re_strdup(&c);
|
||||
}
|
||||
~re_str();
|
||||
re_str(const re_str& other);
|
||||
re_str(const charT* p1);
|
||||
re_str(const charT* p1, const charT* p2);
|
||||
re_str(charT c);
|
||||
|
||||
re_str& RE_CALL operator=(const re_str& other)
|
||||
{
|
||||
re_strfree(buf);
|
||||
buf = re_strdup(other.buf);
|
||||
return *this;
|
||||
}
|
||||
re_str& RE_CALL operator=(const charT* p)
|
||||
{
|
||||
re_strfree(buf);
|
||||
buf = re_strdup(p);
|
||||
return *this;
|
||||
}
|
||||
re_str& RE_CALL operator=(charT c)
|
||||
{
|
||||
re_strfree(buf);
|
||||
buf = re_strdup(&c, &c+1);
|
||||
return *this;
|
||||
}
|
||||
const charT* RE_CALL c_str()const { return buf; }
|
||||
RE_CALL operator const charT*()const { return buf; }
|
||||
unsigned int RE_CALL size()const { return re_strlen(buf); }
|
||||
charT& RE_CALL operator[](unsigned int i) { return buf[i]; }
|
||||
charT RE_CALL operator[](unsigned int i)const { return buf[i]; }
|
||||
|
||||
bool RE_CALL operator==(const re_str& other)const { return re_strcmp(buf, other.buf) == 0; }
|
||||
bool RE_CALL operator==(const charT* p)const { return re_strcmp(buf, p) == 0; }
|
||||
bool RE_CALL operator==(const charT c)const
|
||||
{
|
||||
if((*buf) && (*buf == c) && (*(buf+1) == 0))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool RE_CALL operator!=(const re_str& other)const { return re_strcmp(buf, other.buf) != 0; }
|
||||
bool RE_CALL operator!=(const charT* p)const { return re_strcmp(buf, p) != 0; }
|
||||
bool RE_CALL operator!=(const charT c)const { return !(*this == c); }
|
||||
|
||||
bool RE_CALL operator<(const re_str& other)const { return re_strcmp(buf, other.buf) < 0; }
|
||||
bool RE_CALL operator<=(const re_str& other)const { return re_strcmp(buf, other.buf) <= 0; }
|
||||
bool RE_CALL operator>(const re_str& other)const { return re_strcmp(buf, other.buf) > 0; }
|
||||
bool RE_CALL operator>=(const re_str& other)const { return re_strcmp(buf, other.buf) >= 0; }
|
||||
|
||||
bool RE_CALL operator<(const charT* p)const { return re_strcmp(buf, p) < 0; }
|
||||
bool RE_CALL operator<=(const charT* p)const { return re_strcmp(buf, p) <= 0; }
|
||||
bool RE_CALL operator>(const charT* p)const { return re_strcmp(buf, p) > 0; }
|
||||
bool RE_CALL operator>=(const charT* p)const { return re_strcmp(buf, p) >= 0; }
|
||||
};
|
||||
|
||||
template <class charT>
|
||||
CONSTRUCTOR_INLINE re_str<charT>::~re_str() { re_strfree(buf); }
|
||||
|
||||
template <class charT>
|
||||
CONSTRUCTOR_INLINE re_str<charT>::re_str(const re_str<charT>& other) { buf = re_strdup(other.buf); }
|
||||
|
||||
template <class charT>
|
||||
CONSTRUCTOR_INLINE re_str<charT>::re_str(const charT* p1) { buf = re_strdup(p1); }
|
||||
|
||||
template <class charT>
|
||||
CONSTRUCTOR_INLINE re_str<charT>::re_str(const charT* p1, const charT* p2) { buf = re_strdup(p1, p2); }
|
||||
|
||||
template <class charT>
|
||||
CONSTRUCTOR_INLINE re_str<charT>::re_str(charT c) { buf = re_strdup(&c, &c+1); }
|
||||
|
||||
|
||||
#ifndef JM_NO_WCSTRING
|
||||
JM_IX_DECL void RE_CALL re_transform(re_str<wchar_t>& out, const re_str<wchar_t>& in);
|
||||
#endif
|
||||
JM_IX_DECL void RE_CALL re_transform(re_str<char>& out, const re_str<char>& in);
|
||||
|
||||
template <class charT>
|
||||
void RE_CALL re_trunc_primary(re_str<charT>& s)
|
||||
{
|
||||
for(unsigned int i = 0; i < s.size(); ++i)
|
||||
{
|
||||
if(s[i] <= 1)
|
||||
{
|
||||
s[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RE_LOCALE_C
|
||||
#define TRANSFORM_ERROR (size_t)-1
|
||||
#else
|
||||
#define TRANSFORM_ERROR 0
|
||||
#endif
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE re_thrd.h
|
||||
* VERSION 2.12
|
||||
* Thread synch helper functions, for regular
|
||||
* expression library.
|
||||
*/
|
||||
|
||||
#ifndef RE_THRD_H
|
||||
#define RE_THRD_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#if defined(JM_PLATFORM_W32) && defined(JM_THREADS)
|
||||
//#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if !defined(JM_PLATFORM_W32) && defined(JM_THREADS)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
void RE_CALL re_init_threads();
|
||||
void RE_CALL re_free_threads();
|
||||
|
||||
#ifdef JM_THREADS
|
||||
|
||||
#ifndef JM_PLATFORM_W32
|
||||
|
||||
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||
|
||||
inline void RE_CALL InitializeCriticalSection(CRITICAL_SECTION* ps)
|
||||
{
|
||||
pthread_mutex_init(ps, NULL);
|
||||
}
|
||||
|
||||
inline void RE_CALL DeleteCriticalSection(CRITICAL_SECTION* ps)
|
||||
{
|
||||
pthread_mutex_destroy(ps);
|
||||
}
|
||||
|
||||
inline void RE_CALL EnterCriticalSection(CRITICAL_SECTION* ps)
|
||||
{
|
||||
pthread_mutex_lock(ps);
|
||||
}
|
||||
|
||||
inline void RE_CALL LeaveCriticalSection(CRITICAL_SECTION* ps)
|
||||
{
|
||||
pthread_mutex_unlock(ps);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class Lock>
|
||||
class lock_guard
|
||||
{
|
||||
typedef Lock lock_type;
|
||||
public:
|
||||
lock_guard(lock_type& m, bool aq = true)
|
||||
: mut(m), owned(false){ acquire(aq); }
|
||||
|
||||
~lock_guard()
|
||||
{ acquire(false); }
|
||||
|
||||
void RE_CALL acquire(bool aq = true, DWORD timeout = INFINITE)
|
||||
{
|
||||
if(aq && !owned)
|
||||
{
|
||||
mut.acquire(true, timeout);
|
||||
owned = true;
|
||||
}
|
||||
else if(!aq && owned)
|
||||
{
|
||||
mut.acquire(false);
|
||||
owned = false;
|
||||
}
|
||||
}
|
||||
private:
|
||||
lock_type& mut;
|
||||
bool owned;
|
||||
};
|
||||
|
||||
|
||||
class critical_section
|
||||
{
|
||||
public:
|
||||
critical_section()
|
||||
{ InitializeCriticalSection(&hmutex);}
|
||||
|
||||
critical_section(const critical_section&)
|
||||
{ InitializeCriticalSection(&hmutex);}
|
||||
|
||||
const critical_section& RE_CALL operator=(const critical_section&)
|
||||
{return *this;}
|
||||
|
||||
~critical_section()
|
||||
{DeleteCriticalSection(&hmutex);}
|
||||
|
||||
private:
|
||||
|
||||
void RE_CALL acquire(bool aq, DWORD unused = INFINITE)
|
||||
{ if(aq) EnterCriticalSection(&hmutex);
|
||||
else LeaveCriticalSection(&hmutex);
|
||||
}
|
||||
|
||||
CRITICAL_SECTION hmutex;
|
||||
|
||||
public:
|
||||
typedef lock_guard<critical_section> ro_guard;
|
||||
typedef lock_guard<critical_section> rw_guard;
|
||||
|
||||
friend lock_guard<critical_section>;
|
||||
};
|
||||
|
||||
inline bool RE_CALL operator==(const critical_section&, const critical_section&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool RE_CALL operator<(const critical_section&, const critical_section&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef lock_guard<critical_section> cs_guard;
|
||||
|
||||
JM_IX_DECL extern critical_section* p_re_lock;
|
||||
JM_IX_DECL extern unsigned int re_lock_count;
|
||||
|
||||
#define JM_GUARD(inst) __JM::critical_section::rw_guard g(inst);
|
||||
|
||||
#else // JM_THREADS
|
||||
|
||||
#define JM_GUARD(inst)
|
||||
|
||||
#endif // JM_THREADS
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif // sentry
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE regfac.h
|
||||
* VERSION 2.12
|
||||
*/
|
||||
|
||||
#ifndef REGFAC_H
|
||||
#define REGFAC_H
|
||||
|
||||
#ifndef JM_CFG_H
|
||||
#include <jm/jm_cfg.h>
|
||||
#endif
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <jm/re_str.h>
|
||||
#include <jm/re_cls.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
//
|
||||
// class regfacet
|
||||
//
|
||||
// provides syntax data etc, customised versions
|
||||
// can be installed in an instance of std::locale and imbue'd
|
||||
// into a reg_expression for per-instance localisation.
|
||||
//
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
template <class charT>
|
||||
class regfacet : public __JM_STD::locale::facet
|
||||
{
|
||||
public:
|
||||
static __JM_STD::locale::id id;
|
||||
regfacet(unsigned int i = 0);
|
||||
jm_uintfast32_t RE_CALL lookup_classname(const charT* first, const charT* last)const;
|
||||
bool RE_CALL lookup_collatename(re_str<charT>& s, const re_str<charT>& name)const;
|
||||
unsigned int RE_CALL syntax_type(charT)const;
|
||||
void RE_CALL update(const __JM_STD::locale&)const;
|
||||
charT RE_CALL zero()const;
|
||||
charT RE_CALL ten()const;
|
||||
|
||||
protected:
|
||||
virtual jm_uintfast32_t RE_CALL do_lookup_classname(const charT* first, const charT* last)const = 0;
|
||||
virtual bool RE_CALL do_lookup_collatename(re_str<charT>& s, const re_str<charT>& name)const = 0;
|
||||
virtual unsigned int RE_CALL do_syntax_type(charT)const = 0;
|
||||
virtual void RE_CALL do_update(const __JM_STD::locale&) = 0;
|
||||
|
||||
// required by Rogue Wave, not part of standard:
|
||||
__JM_STD::locale::id& get_id()const { return id; }
|
||||
~regfacet(){}
|
||||
};
|
||||
|
||||
JM_TEMPLATE_SPECIALISE
|
||||
class JM_IX_DECL regfacet<char> : public __JM_STD::locale::facet
|
||||
{
|
||||
public:
|
||||
typedef __JM_STD::messages<char>::string_type string_type;
|
||||
private:
|
||||
unsigned char syntax_map[256];
|
||||
string_type name;
|
||||
char _zero, _ten;
|
||||
__JM_STD::map<__JM_STD::string, unsigned long, __JM_STD::less<__JM_STD::string> > classes;
|
||||
__JM_STD::map<re_str<char>, re_str<char>, __JM_STD::less<re_str<char> > > collating_elements;
|
||||
regfacet(const regfacet&);
|
||||
|
||||
#ifdef RE_THREADS
|
||||
critical_section cs;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static __JM_STD::locale::id id;
|
||||
regfacet(unsigned int i = 0);
|
||||
jm_uintfast32_t RE_CALL lookup_classname(const char* first, const char* last)const { return do_lookup_classname(first, last); }
|
||||
bool RE_CALL lookup_collatename(re_str<char>& s, const re_str<char>& name)const { return do_lookup_collatename(s, name); }
|
||||
unsigned int RE_CALL syntax_type(char c)const { return do_syntax_type(c); }
|
||||
void RE_CALL update(const __JM_STD::locale& l)const { const_cast<regfacet<char>*>(this)->do_update(l); }
|
||||
char RE_CALL zero()const { return _zero; }
|
||||
char RE_CALL ten()const { return _ten; }
|
||||
|
||||
protected:
|
||||
virtual jm_uintfast32_t RE_CALL do_lookup_classname(const char* first, const char* last)const;
|
||||
virtual bool RE_CALL do_lookup_collatename(re_str<char>& s, const re_str<char>& name)const;
|
||||
virtual unsigned int RE_CALL do_syntax_type(char)const;
|
||||
virtual void RE_CALL do_update(const __JM_STD::locale&);
|
||||
|
||||
// required by Rogue Wave, not part of standard:
|
||||
__JM_STD::locale::id& get_id()const { return id; }
|
||||
~regfacet();
|
||||
|
||||
};
|
||||
|
||||
JM_TEMPLATE_SPECIALISE
|
||||
class JM_IX_DECL regfacet<wchar_t> : public __JM_STD::locale::facet
|
||||
{
|
||||
public:
|
||||
typedef __JM_STD::messages<wchar_t>::string_type string_type;
|
||||
private:
|
||||
__JM_STD::messages<char>::string_type name;
|
||||
|
||||
struct syntax_map
|
||||
{
|
||||
wchar_t c;
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
__JM_STD::list<syntax_map> syntax;
|
||||
wchar_t _zero, _ten;
|
||||
__JM_STD::map<__JM_STD::wstring, unsigned long, __JM_STD::less<__JM_STD::wstring> > classes;
|
||||
const __JM_STD::locale* ploc;
|
||||
__JM_STD::map<re_str<wchar_t>, re_str<wchar_t>, __JM_STD::less<re_str<wchar_t> > > collating_elements;
|
||||
regfacet(const regfacet&);
|
||||
|
||||
#ifdef RE_THREADS
|
||||
critical_section cs;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static __JM_STD::locale::id id;
|
||||
regfacet(unsigned int i = 0);
|
||||
jm_uintfast32_t RE_CALL lookup_classname(const wchar_t* first, const wchar_t* last)const { return do_lookup_classname(first, last); }
|
||||
bool RE_CALL lookup_collatename(re_str<wchar_t>& s, const re_str<wchar_t>& name)const { return do_lookup_collatename(s, name); }
|
||||
unsigned int RE_CALL syntax_type(wchar_t c)const { return do_syntax_type(c); }
|
||||
void RE_CALL update(const __JM_STD::locale& l)const { const_cast<regfacet<wchar_t>*>(this)->do_update(l); }
|
||||
wchar_t RE_CALL zero()const { return _zero; }
|
||||
wchar_t RE_CALL ten()const { return _ten; }
|
||||
|
||||
protected:
|
||||
virtual jm_uintfast32_t RE_CALL do_lookup_classname(const wchar_t* first, const wchar_t* last)const;
|
||||
virtual bool RE_CALL do_lookup_collatename(re_str<wchar_t>& s, const re_str<wchar_t>& name)const;
|
||||
virtual unsigned int RE_CALL do_syntax_type(wchar_t)const;
|
||||
virtual void RE_CALL do_update(const __JM_STD::locale&);
|
||||
|
||||
// required by Rogue Wave, not part of standard:
|
||||
__JM_STD::locale::id& get_id()const { return id; }
|
||||
~regfacet();
|
||||
|
||||
};
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,565 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-9
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE regfmt.h
|
||||
* VERSION 2.12
|
||||
*
|
||||
* Provides formatting output routines for search and replace
|
||||
* operations. Note this is an internal header file included
|
||||
* by regex.h, do not include on its own.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef REGFMT_H
|
||||
#define REGFMT_H
|
||||
|
||||
|
||||
JM_NAMESPACE(__JM)
|
||||
|
||||
template <class O, class I>
|
||||
O RE_CALL re_copy_out(O out, I first, I last)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*out = *first;
|
||||
++out;
|
||||
++first;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
void RE_CALL re_skip_format(const charT*& fmt
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef JM_NO_TEMPLATE_TYPENAME
|
||||
typedef char_regex_traits<charT> re_traits_type;
|
||||
#else
|
||||
typedef typename char_regex_traits<charT> re_traits_type;
|
||||
#endif
|
||||
unsigned int parens = 0;
|
||||
unsigned int c;
|
||||
while(*fmt)
|
||||
{
|
||||
c = re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l));
|
||||
if((c == syntax_colon) && (parens == 0))
|
||||
{
|
||||
++fmt;
|
||||
return;
|
||||
}
|
||||
else if(c == syntax_close_bracket)
|
||||
{
|
||||
if(parens == 0)
|
||||
{
|
||||
++fmt;
|
||||
return;
|
||||
}
|
||||
--parens;
|
||||
}
|
||||
else if(c == syntax_open_bracket)
|
||||
++parens;
|
||||
else if(c == syntax_slash)
|
||||
{
|
||||
++fmt;
|
||||
if(*fmt == 0)
|
||||
return;
|
||||
}
|
||||
++fmt;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JM_NO_OI_ASSIGN
|
||||
|
||||
//
|
||||
// ugly hack for buggy output iterators
|
||||
|
||||
template <class T>
|
||||
inline void oi_assign(T* p, T v)
|
||||
{
|
||||
jm_destroy(p);
|
||||
jm_construct(p, v);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
inline void oi_assign(T* p, T v)
|
||||
{
|
||||
//
|
||||
// if you get a compile time error in here then you either
|
||||
// need to rewrite your output iterator to make it assignable
|
||||
// (as is required by the standard), or define JM_NO_OI_ASSIGN
|
||||
// to use the ugly hack above
|
||||
*p = v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
|
||||
//
|
||||
// Ugly ugly hack,
|
||||
// template don't merge if they contain switch statements so declare these
|
||||
// templates in unnamed namespace (ie with internal linkage), each translation
|
||||
// unit then gets its own local copy, it works seemlessly but bloats the app.
|
||||
namespace{
|
||||
#endif
|
||||
|
||||
//
|
||||
// algorithm reg_format:
|
||||
// takes the result of a match and a format string
|
||||
// and merges them to produce a new string which
|
||||
// is sent to an OutputIterator,
|
||||
// __reg_format_aux does the actual work:
|
||||
//
|
||||
template <class OutputIterator, class iterator, class Allocator, class charT>
|
||||
OutputIterator RE_CALL __reg_format_aux(OutputIterator out,
|
||||
const reg_match<iterator, Allocator>& m,
|
||||
const charT*& fmt,
|
||||
bool isif
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& l
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef JM_NO_TEMPLATE_TYPENAME
|
||||
typedef char_regex_traits<charT> re_traits_type;
|
||||
#else
|
||||
typedef typename char_regex_traits<charT> re_traits_type;
|
||||
#endif
|
||||
|
||||
const charT* fmt_end = fmt;
|
||||
while(*fmt_end) ++ fmt_end;
|
||||
|
||||
while(*fmt)
|
||||
{
|
||||
switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
|
||||
{
|
||||
case syntax_dollar:
|
||||
++fmt;
|
||||
if(*fmt == 0) // oops trailing $
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
return out;
|
||||
}
|
||||
switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
|
||||
{
|
||||
case syntax_start_buffer:
|
||||
oi_assign(&out, re_copy_out(out, iterator(m[-1].first), iterator(m[-1].second)));
|
||||
++fmt;
|
||||
continue;
|
||||
case syntax_end_buffer:
|
||||
oi_assign(&out, re_copy_out(out, iterator(m[-2].first), iterator(m[-2].second)));
|
||||
++fmt;
|
||||
continue;
|
||||
case syntax_digit:
|
||||
{
|
||||
unsigned int index = re_traits_type::toi(fmt, fmt_end, 10 MAYBE_PASS_LOCALE(l));
|
||||
oi_assign(&out, re_copy_out(out, iterator(m[index].first), iterator(m[index].second)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// anything else:
|
||||
if(*fmt == '&')
|
||||
{
|
||||
oi_assign(&out, re_copy_out(out, iterator(m[0].first), iterator(m[0].second)));
|
||||
++fmt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// probably an error, treat as a literal '$'
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
}
|
||||
continue;
|
||||
case syntax_slash:
|
||||
{
|
||||
// escape sequence:
|
||||
charT c;
|
||||
++fmt;
|
||||
if(*fmt == 0)
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
return out;
|
||||
}
|
||||
switch(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)))
|
||||
{
|
||||
case syntax_a:
|
||||
c = '\a';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_f:
|
||||
c = '\f';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_n:
|
||||
c = '\n';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_r:
|
||||
c = '\r';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_t:
|
||||
c = '\t';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_v:
|
||||
c = '\v';
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_x:
|
||||
++fmt;
|
||||
if(fmt == fmt_end)
|
||||
{
|
||||
*out = *--fmt;
|
||||
++out;
|
||||
return out;
|
||||
}
|
||||
// maybe have \x{ddd}
|
||||
if(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) == syntax_open_brace)
|
||||
{
|
||||
++fmt;
|
||||
if(fmt == fmt_end)
|
||||
{
|
||||
fmt -= 2;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
continue;
|
||||
}
|
||||
if(re_traits_type::is_class(*fmt, char_class_xdigit MAYBE_PASS_LOCALE(l)) == false)
|
||||
{
|
||||
fmt -= 2;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
continue;
|
||||
}
|
||||
c = (charT)re_traits_type::toi(fmt, fmt_end, -16 MAYBE_PASS_LOCALE(l));
|
||||
if(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) != syntax_close_brace)
|
||||
{
|
||||
while(re_traits_type::syntax_type(*fmt MAYBE_PASS_LOCALE(l)) != syntax_slash)
|
||||
--fmt;
|
||||
++fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
continue;
|
||||
}
|
||||
++fmt;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(re_traits_type::is_class(*fmt, char_class_xdigit MAYBE_PASS_LOCALE(l)) == false)
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
continue;
|
||||
}
|
||||
c = (charT)re_traits_type::toi(fmt, fmt_end, -16 MAYBE_PASS_LOCALE(l));
|
||||
}
|
||||
break;
|
||||
case syntax_c:
|
||||
++fmt;
|
||||
if(fmt == fmt_end)
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
return out;
|
||||
}
|
||||
if(((typename re_traits_type::uchar_type)(*fmt) < (typename re_traits_type::uchar_type)'@')
|
||||
|| ((typename re_traits_type::uchar_type)(*fmt) > (typename re_traits_type::uchar_type)127) )
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
break;
|
||||
}
|
||||
c = (charT)((typename re_traits_type::uchar_type)(*fmt) - (typename re_traits_type::uchar_type)'@');
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_e:
|
||||
c = (charT)27;
|
||||
++fmt;
|
||||
break;
|
||||
case syntax_digit:
|
||||
c = (charT)re_traits_type::toi(fmt, fmt_end, -8 MAYBE_PASS_LOCALE(l));
|
||||
break;
|
||||
default:
|
||||
c = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
*out = c;
|
||||
continue;
|
||||
}
|
||||
case syntax_open_bracket:
|
||||
++fmt; // recurse
|
||||
oi_assign(&out, __reg_format_aux(out, m, fmt, false MAYBE_PASS_LOCALE(l)));
|
||||
continue;
|
||||
case syntax_close_bracket:
|
||||
++fmt; // return from recursion
|
||||
return out;
|
||||
case syntax_colon:
|
||||
if(isif)
|
||||
{
|
||||
++fmt;
|
||||
return out;
|
||||
}
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
continue;
|
||||
case syntax_question:
|
||||
{
|
||||
++fmt;
|
||||
if(*fmt == 0)
|
||||
{
|
||||
--fmt;
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
return out;
|
||||
}
|
||||
unsigned int id = re_traits_type::toi(fmt, fmt_end, 10 MAYBE_PASS_LOCALE(l));
|
||||
if(m[id].matched)
|
||||
{
|
||||
oi_assign(&out, __reg_format_aux(out, m, fmt, true MAYBE_PASS_LOCALE(l)));
|
||||
if(re_traits_type::syntax_type(*(fmt-1) MAYBE_PASS_LOCALE(l)) == syntax_colon)
|
||||
re_skip_format(fmt MAYBE_PASS_LOCALE(l));
|
||||
}
|
||||
else
|
||||
{
|
||||
re_skip_format(fmt MAYBE_PASS_LOCALE(l));
|
||||
if(re_traits_type::syntax_type(*(fmt-1) MAYBE_PASS_LOCALE(l)) == syntax_colon)
|
||||
oi_assign(&out, __reg_format_aux(out, m, fmt, true MAYBE_PASS_LOCALE(l)));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
default:
|
||||
*out = *fmt;
|
||||
++out;
|
||||
++fmt;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
#if defined(JM_NO_TEMPLATE_SWITCH_MERGE) && !defined(JM_NO_NAMESPACES)
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
|
||||
template <class OutputIterator, class iterator, class Allocator, class charT>
|
||||
OutputIterator RE_CALL reg_format(OutputIterator out,
|
||||
const reg_match<iterator, Allocator>& m,
|
||||
const charT* fmt
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, __JM_STD::locale locale_inst = __JM_STD::locale()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
//
|
||||
// start by updating the locale:
|
||||
//
|
||||
#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
|
||||
static re_initialiser<charT> locale_initialiser;
|
||||
locale_initialiser.update();
|
||||
#else
|
||||
if(JM_HAS_FACET(locale_inst, regfacet<charT>) == false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
locale_inst = __JM_STD::_ADDFAC(locale_inst, new regfacet<charT>());
|
||||
#else
|
||||
locale_inst = __JM_STD::locale(locale_inst, new regfacet<charT>());
|
||||
#endif
|
||||
}
|
||||
JM_USE_FACET(locale_inst, regfacet<charT>).update(locale_inst);
|
||||
#endif
|
||||
return __reg_format_aux(out, m, fmt, false MAYBE_PASS_LOCALE(locale_inst));
|
||||
}
|
||||
|
||||
template <class S>
|
||||
class string_out_iterator
|
||||
{
|
||||
S* out;
|
||||
public:
|
||||
string_out_iterator(S& s) : out(&s) {}
|
||||
string_out_iterator& operator++() { return *this; }
|
||||
string_out_iterator& operator++(int) { return *this; }
|
||||
string_out_iterator& operator*() { return *this; }
|
||||
string_out_iterator& operator=(typename S::value_type v)
|
||||
{
|
||||
out->append(1, v);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef JM_NO_STRING_DEF_ARGS
|
||||
template <class iterator, class Allocator, class charT>
|
||||
__JM_STD::basic_string<charT> RE_CALL reg_format(const reg_match<iterator, Allocator>& m, const charT* fmt
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, __JM_STD::locale locale_inst = __JM_STD::locale()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
__JM_STD::basic_string<charT> result;
|
||||
string_out_iterator<__JM_STD::basic_string<charT> > i(result);
|
||||
reg_format(i, m, fmt MAYBE_PASS_LOCALE(locale_inst));
|
||||
return result;
|
||||
}
|
||||
#elif !defined(JM_NO_STRING_H)
|
||||
template <class iterator, class Allocator>
|
||||
__JM_STD::string RE_CALL reg_format(const reg_match<iterator, Allocator>& m, const char* fmt
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, __JM_STD::locale locale_inst = __JM_STD::locale()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
__JM_STD::string result;
|
||||
string_out_iterator<__JM_STD::string> i(result);
|
||||
reg_format(i, m, fmt MAYBE_PASS_LOCALE(locale_inst));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template <class OutputIterator, class iterator, class charT, class Allocator>
|
||||
class merge_out_predicate
|
||||
{
|
||||
OutputIterator* out;
|
||||
iterator* last;
|
||||
const charT* fmt;
|
||||
bool copy_none;
|
||||
|
||||
#ifdef RE_LOCALE_CPP
|
||||
const __JM_STD::locale& l;
|
||||
#endif
|
||||
|
||||
public:
|
||||
merge_out_predicate(OutputIterator& o, iterator& pi, const charT* f, bool c
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, const __JM_STD::locale& loc
|
||||
#endif
|
||||
) : out(&o), last(&pi), fmt(f), copy_none(c)
|
||||
#ifdef RE_LOCALE_CPP
|
||||
, l(loc)
|
||||
#endif
|
||||
{}
|
||||
|
||||
~merge_out_predicate() {}
|
||||
bool RE_CALL operator()(const __JM::reg_match<iterator, Allocator>& m)
|
||||
{
|
||||
const charT* f = fmt;
|
||||
if(copy_none)
|
||||
oi_assign(out, re_copy_out(*out, iterator(m[-1].first), iterator(m[-1].second)));
|
||||
oi_assign(out, __reg_format_aux(*out, m, f, false MAYBE_PASS_LOCALE(l)));
|
||||
*last = m[-2].first;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class OutputIterator, class iterator, class traits, class Allocator, class charT>
|
||||
OutputIterator RE_CALL reg_merge(OutputIterator out,
|
||||
iterator first,
|
||||
iterator last,
|
||||
const reg_expression<charT, traits, Allocator>& e,
|
||||
const charT* fmt,
|
||||
bool copy = true,
|
||||
unsigned int flags = match_default)
|
||||
{
|
||||
//
|
||||
// start by updating the locale:
|
||||
//
|
||||
#if defined(RE_LOCALE_C) || defined(RE_LOCALE_W32)
|
||||
static re_initialiser<charT> locale_initialiser;
|
||||
locale_initialiser.update();
|
||||
#else
|
||||
__JM_STD::locale locale_inst(e.locale());
|
||||
if(JM_HAS_FACET(locale_inst, regfacet<charT>) == false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
locale_inst = __JM_STD::_ADDFAC(locale_inst, new regfacet<charT>());
|
||||
#else
|
||||
locale_inst = __JM_STD::locale(locale_inst, new regfacet<charT>());
|
||||
#endif
|
||||
}
|
||||
JM_USE_FACET(locale_inst, regfacet<charT>).update(locale_inst);
|
||||
#endif
|
||||
iterator l = first;
|
||||
merge_out_predicate<OutputIterator, iterator, charT, Allocator> oi(out, l, fmt, copy MAYBE_PASS_LOCALE(locale_inst));
|
||||
reg_grep(oi, first, last, e, flags);
|
||||
return copy ? re_copy_out(out, l, last) : out;
|
||||
}
|
||||
|
||||
#ifndef JM_NO_STRING_DEF_ARGS
|
||||
template <class traits, class Allocator, class charT>
|
||||
__JM_STD::basic_string<charT> RE_CALL reg_merge(const __JM_STD::basic_string<charT>& s,
|
||||
const reg_expression<charT, traits, Allocator>& e,
|
||||
const charT* fmt,
|
||||
bool copy = true,
|
||||
unsigned int flags = match_default)
|
||||
{
|
||||
__JM_STD::basic_string<charT> result;
|
||||
string_out_iterator<__JM_STD::basic_string<charT> > i(result);
|
||||
reg_merge(i, s.begin(), s.end(), e, fmt, copy, flags);
|
||||
return result;
|
||||
}
|
||||
#elif !defined(JM_NO_STRING_H)
|
||||
template <class traits, class Allocator>
|
||||
__JM_STD::string RE_CALL reg_merge(const __JM_STD::string& s,
|
||||
const reg_expression<char, traits, Allocator>& e,
|
||||
const char* fmt,
|
||||
bool copy = true,
|
||||
unsigned int flags = match_default)
|
||||
{
|
||||
__JM_STD::string result;
|
||||
string_out_iterator<__JM_STD::string> i(result);
|
||||
reg_merge(i, s.begin(), s.end(), e, fmt, copy, flags);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
JM_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#ifndef __REGEX_H
|
||||
#include <jm/regex.h>
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef __REGEX_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4786)
|
||||
#pragma warning(disable: 4800)
|
||||
#endif
|
||||
|
||||
#include <jm/regex.h>
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implematation of CReport
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "report.h"
|
||||
#include "util.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CReport::makeHTMLPage
|
||||
// Purpose: makes a whole page out of the element that it is called on
|
||||
// Input: pageName - the name of the html file
|
||||
// pageTitle - the title of the document
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CReport::makeHTMLPage(char* pageName,char* pageTitle)
|
||||
{
|
||||
CHTMLFile Page(pageName,pageTitle);
|
||||
report(Page);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Function: CReport::report
|
||||
// Purpose: generates the report's output and adds it to anHTML file
|
||||
// Input: html - the HTML file to add this report element to
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CReport::report(CHTMLFile& html)
|
||||
{
|
||||
generate();
|
||||
writeHTML(html);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of CReport
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef REPORT_H
|
||||
#define REPORT_H
|
||||
#ifdef WIN32
|
||||
#pragma once
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
#include "MatchInfo.h"
|
||||
#include "HTML.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Purpose: CReport is the base class for all elements of a report. This includes
|
||||
// things like scoreboards and awards.
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
class CReport
|
||||
{
|
||||
protected:
|
||||
//every element must have some info about the match to go off of.
|
||||
//moved into global pointer. g_pMatchInfo
|
||||
//CMatchInfo* pMatchInfo;
|
||||
virtual void init(){}
|
||||
public:
|
||||
//explicit CReport(CMatchInfo* pMInfo):pMatchInfo(pMInfo){}
|
||||
explicit CReport(){}
|
||||
virtual void writeHTML(CHTMLFile& html){}
|
||||
virtual void generate(){}
|
||||
|
||||
virtual void makeHTMLPage(char* pageName,char* pageTitle);
|
||||
virtual void report(CHTMLFile& html);
|
||||
virtual ~CReport(){}
|
||||
};
|
||||
|
||||
|
||||
#endif // REPORT_H
|
||||
@@ -0,0 +1,57 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
char* szHeaderFile=
|
||||
"//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========\n"\
|
||||
"//\n"\
|
||||
"// The copyright to the contents herein is the property of Valve, L.L.C.\n"\
|
||||
"// The contents may be used and/or copied only with the written permission of\n"\
|
||||
"// Valve, L.L.C., or in accordance with the terms and conditions stipulated in\n"\
|
||||
"// the agreement/contract under which the contents have been supplied.\n"\
|
||||
"//\n"\
|
||||
"// Purpose: \n"\
|
||||
"//\n"\
|
||||
"// $Workfile: $\n"\
|
||||
"// $Date: $\n"\
|
||||
"//\n"\
|
||||
"//------------------------------------------------------------------------------------------------------\n"\
|
||||
"// $Log: $\n"\
|
||||
"//\n"\
|
||||
"// $NoKeywords: $\n"\
|
||||
"//=============================================================================\n"\
|
||||
"#ifndef BINARYRESOURCE_H\n"\
|
||||
"#define BINARYRESOURCE_H\n"\
|
||||
"#ifdef WIN32\n"\
|
||||
"#pragma once\n"\
|
||||
"#endif\n"\
|
||||
"#include <string>\n"\
|
||||
"#include <stdio.h>\n"\
|
||||
"\n"\
|
||||
"class CBinaryResource\n"\
|
||||
"{\n"\
|
||||
"private:\n"\
|
||||
" std::string filename;\n"\
|
||||
" size_t numBytes;\n"\
|
||||
" unsigned char* pData;\n"\
|
||||
"public:\n"\
|
||||
" CBinaryResource(char* name, size_t bytes,unsigned char* data)\n"\
|
||||
" :filename(name),numBytes(bytes),pData(data)\n"\
|
||||
" {}\n"\
|
||||
" \n"\
|
||||
" bool writeOut()\n"\
|
||||
" {\n"\
|
||||
" FILE* f=fopen(filename.c_str(),\"wb\");\n"\
|
||||
" if (!f)\n"\
|
||||
" return false;\n"\
|
||||
" fwrite(pData,1,numBytes,f);\n"\
|
||||
" fclose(f);\n"\
|
||||
" return true;\n"\
|
||||
" }\n"\
|
||||
"};\n"\
|
||||
"\n"\
|
||||
"#endif // BINARYRESOURCE_H\n"\
|
||||
"\n";
|
||||
@@ -0,0 +1,111 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_PER_LINE 40
|
||||
|
||||
extern char* szHeaderFile;
|
||||
|
||||
void printUsage()
|
||||
{
|
||||
printf("res2c <res file name> <c file name> <object name>\n");
|
||||
}
|
||||
|
||||
char* id4filename(const char* filename)
|
||||
{
|
||||
static char id[500];
|
||||
|
||||
const char* read=filename;
|
||||
char *write=id;
|
||||
|
||||
for (read;*read;read++)
|
||||
{
|
||||
//if first char
|
||||
if (read==filename)
|
||||
{
|
||||
if (isalpha(*read) || *read=='_')
|
||||
*write++=*read;
|
||||
}
|
||||
else if (isalnum(*read))
|
||||
*write++=*read;
|
||||
}
|
||||
*write++='s';
|
||||
*write++='r';
|
||||
*write++='c';
|
||||
*write++='\0';
|
||||
|
||||
return id;
|
||||
}
|
||||
void main(int argc, const char* argv[])
|
||||
{
|
||||
if (argc < 4)
|
||||
{
|
||||
printUsage();
|
||||
return;
|
||||
}
|
||||
char cppname[200];
|
||||
sprintf(cppname,"%s.cpp",argv[2]);
|
||||
char hname[200];
|
||||
sprintf(hname,"%s.h",argv[2]);
|
||||
|
||||
FILE* f=fopen(argv[1],"rb");
|
||||
FILE* cppout=fopen(cppname,"at");
|
||||
FILE* hout=fopen(hname,"at");
|
||||
FILE* brheader=fopen("BinaryResource.h","wt");
|
||||
if (!brheader){printf("couldn't open %s to write\n","BinaryResource.h");exit(-1);}
|
||||
if (!f){printf("couldn't read %s\n",argv[1]);exit(-1);}
|
||||
if (!cppout){printf("couldn't open %s to write\n",argv[2]);exit(-1);}
|
||||
if (!hout){printf("couldn't open %s to write\n",argv[2]);exit(-1);}
|
||||
|
||||
|
||||
fprintf(brheader,szHeaderFile);
|
||||
fclose(brheader);
|
||||
|
||||
|
||||
fprintf(cppout,"\nunsigned char %s[]={\n",id4filename(argv[1]));
|
||||
|
||||
int numLeft4Line=NUM_PER_LINE;
|
||||
|
||||
unsigned char c;
|
||||
int result=fread(&c,sizeof(unsigned char),1,f);
|
||||
|
||||
int numbytes=0;
|
||||
while (result)
|
||||
{
|
||||
//int longc=(*c)&0x000000ff;
|
||||
fprintf(cppout,"0x%02.2x,",c);
|
||||
numbytes++;
|
||||
if(--numLeft4Line==0)
|
||||
{
|
||||
numLeft4Line=NUM_PER_LINE;
|
||||
fprintf(cppout,"\n");
|
||||
}
|
||||
result=fread(&c,sizeof(unsigned char),1,f);
|
||||
}
|
||||
|
||||
fprintf(cppout,"\n};\n\n");
|
||||
|
||||
char* coloncolon=strstr(argv[3],"::");
|
||||
if (coloncolon!=NULL)
|
||||
{
|
||||
coloncolon+=2;
|
||||
fprintf(hout,"static CBinaryResource %s;\n",coloncolon);
|
||||
fprintf(cppout,"CBinaryResource %s(\"%s\",%li,%s);\n\n\n",argv[3],argv[1],numbytes,id4filename(argv[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(hout,"//extern CBinaryResource g_%s;\n",argv[3]);
|
||||
fprintf(cppout,"CBinaryResource g_%s;\n",argv[3]);
|
||||
}
|
||||
fclose(cppout);
|
||||
fclose(hout);
|
||||
fclose(f);
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="res2c"
|
||||
ProjectGUID="{3245AFA2-1569-4ED7-B378-3B6461B3F5BA}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Release/res2c.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Release/res2c.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ProgramDatabaseFile=".\Release/res2c.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/res2c.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Debug/res2c.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Debug/res2c.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\Debug/res2c.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/res2c.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="main.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
After Width: | Height: | Size: 309 B |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 368 B |
|
After Width: | Height: | Size: 628 B |
|
After Width: | Height: | Size: 490 B |
|
After Width: | Height: | Size: 490 B |
@@ -0,0 +1,14 @@
|
||||
res2c awards.gif binResources CTFStatsReport::gifAwards
|
||||
res2c bgleft.jpg binResources CTFStatsReport::jpgBgLeft
|
||||
res2c bgtop.jpg binResources CTFStatsReport::jpgBgTop
|
||||
res2c boxscore.gif binResources CTFStatsReport::gifBoxScore
|
||||
res2c game.dialog.off.gif binResources CTFStatsReport::gifGameDialogOff
|
||||
res2c game.dialog.on.gif binResources CTFStatsReport::gifGameDialogOn
|
||||
res2c match.statistics.off.gif binResources CTFStatsReport::gifMatchStatsOff
|
||||
res2c match.statistics.on.gif binResources CTFStatsReport::gifMatchStatsOn
|
||||
res2c scores.gif binResources CTFStatsReport::gifScores
|
||||
res2c server.settings.off.gif binResources CTFStatsReport::gifServerSettingsOff
|
||||
res2c server.settings.on.gif binResources CTFStatsReport::gifServerSettingsOn
|
||||
res2c player.statistics.off.gif binResources CTFStatsReport::gifPlayerStatsOff
|
||||
res2c player.statistics.on.gif binResources CTFStatsReport::gifPlayerStatsOn
|
||||
res2c detailed.gif binResources CTFStatsReport::gifDetailedScores
|
||||
|
After Width: | Height: | Size: 523 B |
|
After Width: | Height: | Size: 523 B |
|
After Width: | Height: | Size: 600 B |
|
After Width: | Height: | Size: 600 B |
|
After Width: | Height: | Size: 578 B |
|
After Width: | Height: | Size: 578 B |
|
After Width: | Height: | Size: 463 B |