// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//-------------------------------------------------------------------------------------------------
// includes
//-------------------------------------------------------------------------------------------------
#include "nel/misc/variable.h"
#include "nel/misc/path.h"
#include "nel/misc/common.h"
#include "game_share/persistent_data.h"
#include "character_scan_job.h"
#include "character.h"
//-------------------------------------------------------------------------------------------------
// Variables
//-------------------------------------------------------------------------------------------------
extern NLMISC::CVariable OutputDirectory;
//-------------------------------------------------------------------------------------------------
// methods CCharacterScanJob
//-------------------------------------------------------------------------------------------------
CCharacterScanJob::CCharacterScanJob()
{
// start by initialising simple properties
_CharTblFile=NULL;
_NextFile=0;
_State=INIT;
// setup the special reserved table columns 'account' and 'accountSlot'
charTblAddCol("account");
charTblAddCol("accountSlot");
// open the output file for the character table
std::string filename= "char_tbl.csv";
_CharTblFile = NLMISC::nlfopen(filename, "wb");
if (_CharTblFile==NULL)
{
nlwarning("Failed to open output file: %s",filename.c_str());
_State=ERROR;
}
}
CCharacterScanJob::~CCharacterScanJob()
{
if (_State!=ERROR)
_State=CLOSED;
if (_CharTblFile!=NULL)
fclose(_CharTblFile);
// flush the stats maps to their respective output files
for (TCharStatsMap::iterator it=_CharStatsMap.begin();it!=_CharStatsMap.end();++it)
{
// create the output file name and open the file for writing
std::string filename="char_stats_"+(*it).first+".csv";
FILE* f = NLMISC::nlfopen(filename, "wb");
if (f==NULL)
{
nlwarning("Failed to open output file: %s",filename.c_str());
continue;
}
// dump data to the file
for (TCharStatsMapTbl::iterator it2=it->second.begin();it2!=it->second.end();++it2)
{
fprintf(f,"%s,%d,\n",it2->first.c_str(),it2->second);
}
// the writing is finished so close the file
fclose(f);
}
}
void CCharacterScanJob::update()
{
if (_NextFile>=_Files.size())
return;
// load the file into a pdr record
static CPersistentDataRecord pdr;
pdr.clear();
pdr.readFromFile(_Files[_NextFile]);
++_NextFile;
// create a character representation and apply the pdr
CStatsScanCharacter c;
c.apply(pdr);
// iterate over the info extractors executing their core code
for (uint32 i=0;i<_InfoExtractors.size();++i)
{
_InfoExtractors[i]->execute(this,&c);
}
// flush the info collected by the info extractors to the output file
charTblFlushRow(123,456);
}
bool CCharacterScanJob::charTblAddCol(const std::string& name)
{
nlassert(_State==INIT);
// make sure the col doesn't already exist in the table
for (uint32 i=0;i<_TblCols.size();++i)
{
nlassert(_TblCols[i]!=name);
}
// add the colt ot he table
_TblCols.push_back(name);
return true;
}
bool CCharacterScanJob::addInfoExtractor(ICharInfoExtractor* infoExtractor)
{
// make sure this info extractor doesn't already exist
for (uint32 i=0;i<_InfoExtractors.size();++i)
{
if(_InfoExtractors[i]->toString()== infoExtractor->toString())
{
nlwarning("Attempt to add info extractor to the same job more than once: %s",infoExtractor->toString().c_str());
return false;
}
}
// append the new info extractor to the buffer
_InfoExtractors.push_back(infoExtractor);
return true;
}
bool CCharacterScanJob::addFilter(ICharFilter* filter)
{
// make sure this info extractor doesn't already exist
for (uint32 i=0;i<_Filters.size();++i)
{
if(_Filters[i]->toString()== filter->toString())
{
nlwarning("Attempt to add filter to the same job more than once: %s",filter->toString().c_str());
return false;
}
}
// append the new info extractor to the buffer
_Filters.push_back(filter);
return true;
}
bool CCharacterScanJob::addFiles(const CFileDescriptionContainer& fdc)
{
for (uint32 i=0;i= _Files.size();
}
std::string CCharacterScanJob::getShortStatus()
{
return NLMISC::toString("CharacterFiles %d/%d",_NextFile,_Files.size());
}
std::string CCharacterScanJob::getStatus()
{
return getShortStatus();
}
void CCharacterScanJob::display(NLMISC::CLog* log)
{
log->displayNL("%s",getStatus().c_str());
for (uint32 i=0;i<_InfoExtractors.size();++i)
{
log->displayNL("- %s",_InfoExtractors[i]->toString().c_str());
}
}