1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //-------------------------------------------------------------------------------------------------
20 //-------------------------------------------------------------------------------------------------
22 #include "nel/misc/variable.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/common.h"
26 #include "game_share/persistent_data.h"
28 #include "character_scan_job.h"
29 #include "character.h"
32 //-------------------------------------------------------------------------------------------------
34 //-------------------------------------------------------------------------------------------------
36 extern NLMISC::CVariable
<std::string
> OutputDirectory
;
39 //-------------------------------------------------------------------------------------------------
40 // methods CCharacterScanJob
41 //-------------------------------------------------------------------------------------------------
43 CCharacterScanJob::CCharacterScanJob()
45 // start by initialising simple properties
50 // setup the special reserved table columns 'account' and 'accountSlot'
51 charTblAddCol("account");
52 charTblAddCol("accountSlot");
54 // open the output file for the character table
55 std::string filename
= "char_tbl.csv";
56 _CharTblFile
= NLMISC::nlfopen(filename
, "wb");
57 if (_CharTblFile
==NULL
)
59 nlwarning("Failed to open output file: %s",filename
.c_str());
64 CCharacterScanJob::~CCharacterScanJob()
69 if (_CharTblFile
!=NULL
)
72 // flush the stats maps to their respective output files
73 for (TCharStatsMap::iterator it
=_CharStatsMap
.begin();it
!=_CharStatsMap
.end();++it
)
75 // create the output file name and open the file for writing
76 std::string filename
="char_stats_"+(*it
).first
+".csv";
77 FILE* f
= NLMISC::nlfopen(filename
, "wb");
80 nlwarning("Failed to open output file: %s",filename
.c_str());
84 // dump data to the file
85 for (TCharStatsMapTbl::iterator it2
=it
->second
.begin();it2
!=it
->second
.end();++it2
)
87 fprintf(f
,"%s,%d,\n",it2
->first
.c_str(),it2
->second
);
90 // the writing is finished so close the file
95 void CCharacterScanJob::update()
97 if (_NextFile
>=_Files
.size())
100 // load the file into a pdr record
101 static CPersistentDataRecord pdr
;
103 pdr
.readFromFile(_Files
[_NextFile
]);
106 // create a character representation and apply the pdr
107 CStatsScanCharacter c
;
110 // iterate over the info extractors executing their core code
111 for (uint32 i
=0;i
<_InfoExtractors
.size();++i
)
113 _InfoExtractors
[i
]->execute(this,&c
);
116 // flush the info collected by the info extractors to the output file
117 charTblFlushRow(123,456);
120 bool CCharacterScanJob::charTblAddCol(const std::string
& name
)
122 nlassert(_State
==INIT
);
124 // make sure the col doesn't already exist in the table
125 for (uint32 i
=0;i
<_TblCols
.size();++i
)
127 nlassert(_TblCols
[i
]!=name
);
130 // add the colt ot he table
131 _TblCols
.push_back(name
);
136 bool CCharacterScanJob::addInfoExtractor(ICharInfoExtractor
* infoExtractor
)
138 // make sure this info extractor doesn't already exist
139 for (uint32 i
=0;i
<_InfoExtractors
.size();++i
)
141 if(_InfoExtractors
[i
]->toString()== infoExtractor
->toString())
143 nlwarning("Attempt to add info extractor to the same job more than once: %s",infoExtractor
->toString().c_str());
148 // append the new info extractor to the buffer
149 _InfoExtractors
.push_back(infoExtractor
);
154 bool CCharacterScanJob::addFilter(ICharFilter
* filter
)
156 // make sure this info extractor doesn't already exist
157 for (uint32 i
=0;i
<_Filters
.size();++i
)
159 if(_Filters
[i
]->toString()== filter
->toString())
161 nlwarning("Attempt to add filter to the same job more than once: %s",filter
->toString().c_str());
166 // append the new info extractor to the buffer
167 _Filters
.push_back(filter
);
172 bool CCharacterScanJob::addFiles(const CFileDescriptionContainer
& fdc
)
174 for (uint32 i
=0;i
<fdc
.size();++i
)
176 // generate a normalised a full file name with expanded path
177 std::string fullFileName
= NLMISC::CPath::getFullPath(NLMISC::CFile::getPath(fdc
[i
].FileName
))+NLMISC::CFile::getFilename(fdc
[i
].FileName
);
179 // make sure the full file name doesn't already exist in the _Files vector
181 for (j
=0;j
<_Files
.size();++j
)
183 if (fullFileName
==_Files
[j
])
189 // add the full file name to the _Files vector
190 _Files
.push_back(fullFileName
);
195 bool CCharacterScanJob::setOutputPath(const std::string
& path
)
197 nlinfo("Setting output path to: %s",path
.c_str());
198 _OutputPath
= NLMISC::CPath::getFullPath(OutputDirectory
)+path
;
199 bool result
= NLMISC::CFile::createDirectoryTree(_OutputPath
);
202 nlwarning("Failed to create directory tree: %s",path
.c_str());
208 void CCharacterScanJob::charTblFlushRow(uint32 account
,uint32 slot
)
210 // setup the stuff for the ne
211 charTblSetEntry("account",NLMISC::toString(account
));
212 charTblSetEntry("accountSlot",NLMISC::toString(slot
));
214 nlassert(_State
==WORK
);
216 // build the row text from the _CurrentRowEntries entries and erase the entries as we go
218 for (uint32 i
=0;i
<_TblCols
.size();++i
)
222 rowTxt
+=_CurrentRowEntries
[_TblCols
[i
]];
223 _CurrentRowEntries
.erase(_TblCols
[i
]);
226 // get rid of any excess entries (spew warnings to compain about the problem)
227 while (!_CurrentRowEntries
.empty())
229 nlwarning("Character Tbl entry found for unknown column: %s: %s",(*_CurrentRowEntries
.begin()).first
.c_str(),(*_CurrentRowEntries
.begin()).second
.c_str());
230 _CurrentRowEntries
.erase(_CurrentRowEntries
.begin());
233 // add the row text to the output file
234 fprintf(_CharTblFile
,"%s\n",rowTxt
.c_str());
235 fflush(_CharTblFile
);
238 void CCharacterScanJob::charTblSetEntry(const std::string
& colName
,const std::string
& value
)
240 nlassert(_State
==WORK
);
242 // ensure we don't already have a value for this col
243 nlassert(_CurrentRowEntries
.find(colName
)==_CurrentRowEntries
.end());
245 // det the value for the col
246 _CurrentRowEntries
[colName
]= value
;
249 void CCharacterScanJob::freqTblAddEntry(const std::string
& tblName
, const std::string
& key
)
251 nlassert(_State
==WORK
);
253 // if the key doesn't exist in the given freq tbl then init the value to 1 else increment
254 if(_CharStatsMap
[tblName
].find(key
)==_CharStatsMap
[tblName
].end())
255 _CharStatsMap
[tblName
][key
]=1;
257 ++_CharStatsMap
[tblName
][key
];
260 bool CCharacterScanJob::finished()
262 return _NextFile
>= _Files
.size();
265 std::string
CCharacterScanJob::getShortStatus()
267 return NLMISC::toString("CharacterFiles %d/%d",_NextFile
,_Files
.size());
270 std::string
CCharacterScanJob::getStatus()
272 return getShortStatus();
275 void CCharacterScanJob::display(NLMISC::CLog
* log
)
277 log
->displayNL("%s",getStatus().c_str());
278 for (uint32 i
=0;i
<_InfoExtractors
.size();++i
)
280 log
->displayNL("- %s",_InfoExtractors
[i
]->toString().c_str());