diff --git a/src/Makefile b/src/Makefile index 98aee54..b0029fb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,6 +27,9 @@ ifeq ($(USEDBIXX),1) BASE_CFLAGS+= -DUSEDBIXX=1 endif +O_FILES+= build/db2xml.o +BASE_CFLAGS+= -DUSEXML=1 + total: build/oastat clean: @@ -53,6 +56,9 @@ build/db2dbixx.o: db/Db2DbiXX.cpp db/Db2DbiXX.hpp db/database.hpp g++ $(BASE_CFLAGS) db/Db2DbiXX.cpp -o build/db2dbixx.o endif +build/db2xml.o: db/Db2Xml.cpp db/Db2Xml.hpp db/database.hpp $(H_FILES) + g++ $(BASE_CFLAGS) db/Db2Xml.cpp -o build/db2xml.o + build/oastatstruct.o: oastatstruct.cpp oastatstruct.h $(H_FILES) g++ $(BASE_CFLAGS) oastatstruct.cpp -o build/oastatstruct.o diff --git a/src/db/Db2Xml.cpp b/src/db/Db2Xml.cpp new file mode 100644 index 0000000..f3d7401 --- /dev/null +++ b/src/db/Db2Xml.cpp @@ -0,0 +1,240 @@ +/* + * File: Db2Xml.cpp + * Author: poul + * + * Created on 3. december 2011, 17:30 + */ + +#include "Db2Xml.hpp" + + +Db2Xml::Db2Xml() +{ + p_output_dir = "~/oastat"; + p_postscript = ""; + psoudo_playerids.clear(); + nextId = 1; + //mkdir(p_output_dir.c_str()); +} +Db2Xml::Db2Xml(string dbargs) +{ + p_output_dir = "~/oastat"; + p_postscript = ""; + psoudo_playerids.clear(); + nextId = 1; + //mkdir(p_output_dir.c_str()); + + stringstream stream(stringstream::in | stringstream::out); + stream << dbargs; + string holder; + //stream >> holder; + while(!stream.eof()) { + stream >> holder; + if(!stream.eof()) { + string param; + stream >> param; + if(holder == "outputdir") + p_output_dir = param; + if(holder == "postscript") + p_postscript = param; + } + } +} +Db2Xml::Db2Xml(const Db2Xml& orig) +{ + +} +Db2Xml::~Db2Xml() +{ + +} +void Db2Xml::startGame(int gametype, string mapname, string basegame, string servername, OaStatStruct *oss) +{ + isOk = true; + p_xmlcontent = ""; + p_gametime = oss->getDateTime(); + p_servername = servername; + p_xmlcontent += "\n"; + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(p_servername) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % gametype).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(mapname) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(basegame) ).str(); + p_xmlcontent += (boost::format(" %04i-%02i-%02iT%02i:%02i:%02i\n") + % (p_gametime.tm_year+1900) % (p_gametime.tm_mon+1) % (p_gametime.tm_mday) + % (p_gametime.tm_hour) % (p_gametime.tm_min) % (p_gametime.tm_sec) ).str(); +} +void Db2Xml::addGameCvar(string cvar, string value) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(cvar) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(value) ).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::endGame(int second) +{ + if(isOk) { + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += "\n"; + string filename = (boost::format("%1%/%2%_%3%-%4%-%5%_%6%-%7%-%8%.xml") % p_output_dir % p_servername + % (p_gametime.tm_year+1900) % (p_gametime.tm_mon+1) % (p_gametime.tm_mday) + % (p_gametime.tm_hour) % (p_gametime.tm_min) % (p_gametime.tm_sec) ).str(); + ofstream outfile; + outfile.open (filename.c_str()); + outfile << p_xmlcontent; + outfile.close(); + cout << "End game at " << second << "with size " << p_xmlcontent.length() << " written to " << filename << endl; + } +} +int Db2Xml::getGameNumber() +{ + return 1; +} +void Db2Xml::setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill, OaStatStruct *oss) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % guid).str(); + p_xmlcontent += (boost::format(" %1%\n") % getPsoudoId(guid)).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(nickname) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % (isBot? 1:0)).str(); + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(model) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % getXmlEscaped(headmodel) ).str(); + p_xmlcontent += (boost::format(" %1%\n") % skill).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addKill(int second, string attackerID, string targetID, int type) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % attackerID).str(); + p_xmlcontent += (boost::format(" %1%\n") % targetID).str(); + p_xmlcontent += (boost::format(" %1%\n") % type).str(); + p_xmlcontent += " \n"; +} +//void addCapture(int second, string player, int team); +void Db2Xml::addAward(int second, string player, int award) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addScoreInfo(int second, string player, int score) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % score).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addCtf(int second, string player, int team, int event) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % event).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addCtf1f(int second, string player, int team, int event) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % event).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addElimination(int second, int roundnumber, int team, int event) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % roundnumber).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % event).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addCtfElimination(int second, int roundnumber, string player, int team, int event) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % roundnumber).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % event).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addHarvester(int second, string player1, string player2, int team, int event, int score) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player1).str(); + p_xmlcontent += (boost::format(" %1%\n") % player2).str(); + p_xmlcontent += (boost::format(" %1%\n") % team).str(); + p_xmlcontent += (boost::format(" %1%\n") % event).str(); + p_xmlcontent += (boost::format(" %1%\n") % score).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::addChallenge(int second, string player, int challenge, int amount) +{ + if(!isOk) + return; + p_xmlcontent += " \n"; + p_xmlcontent += (boost::format(" %1%\n") % second).str(); + p_xmlcontent += (boost::format(" %1%\n") % player).str(); + p_xmlcontent += (boost::format(" %1%\n") % challenge).str(); + p_xmlcontent += (boost::format(" %1%\n") % amount).str(); + p_xmlcontent += " \n"; +} +void Db2Xml::doNotCommit() +{ + isOk = false; +} + +int Db2Xml::getPsoudoId(string guid) +{ + int ret = psoudo_playerids[guid]; + if(ret > 0) + return ret; + ret = nextId++; + psoudo_playerids[guid] = ret; + return ret; +} + +string Db2Xml::getXmlEscaped(string org) +{ + string result = org; + boost::algorithm::replace_all(result,(string)"&",(string)"&"); + boost::algorithm::replace_all(result,(string)"<",(string)"<"); + boost::algorithm::replace_all(result,(string)">",(string)">"); + boost::algorithm::replace_all(result,(string)"\"",(string)"""); + boost::algorithm::replace_all(result,(string)"'",(string)"'"); + + return result; +} + +void Db2Xml::createTables() { + +} \ No newline at end of file diff --git a/src/db/Db2Xml.hpp b/src/db/Db2Xml.hpp new file mode 100644 index 0000000..53b611c --- /dev/null +++ b/src/db/Db2Xml.hpp @@ -0,0 +1,66 @@ +/* + * File: Db2Xml.hpp + * Author: poul + * + * Created on 3. december 2011, 17:30 + */ + +/* + * This file generates a file + * + */ + +#ifndef DB2XML_HPP +#define DB2XML_HPP + +#include "database.hpp" +#include +#include +#include +#include +#include + +class Db2Xml : public Database { +public: + Db2Xml(); + Db2Xml(string dbargs); + Db2Xml(const Db2Xml& orig); + virtual ~Db2Xml(); + void createTables(); + void startGame(int gametype, string mapname, string basegame, string servername, OaStatStruct *oss); + void addGameCvar(string cvar, string value); + void endGame(int second); + int getGameNumber(); + void setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill, OaStatStruct *oss); + void addKill(int second, string attackerID, string targetID, int type); + //void addCapture(int second, string player, int team); + void addAward(int second, string player, int award); + void addScoreInfo(int second, string player, int score); + void addCtf(int second, string player, int team, int event); + void addCtf1f(int second, string player, int team, int event); + void addElimination(int second, int roundnumber, int team, int event); + void addCtfElimination(int second, int roundnumber, string player, int team, int event); + void addHarvester(int second, string player1, string player2, int team, int event, int score); + void addChallenge(int second, string player, int challenge, int amount); + void doNotCommit(); +private: + string p_output_dir; + string p_servername; //Used for filename + tm p_gametime; //Used for filename + string p_xmlcontent; + string p_postscript; + bool isOk; + + /* + * To make it easier to parse the XML file oastat will generate a unique id for each game + * This is used then converting back to a log file + */ + map psoudo_playerids; + int nextId; + + int getPsoudoId(string guid); + string getXmlEscaped(string org); +}; + +#endif /* DB2XML_HPP */ + diff --git a/src/oastat.cpp b/src/oastat.cpp index 3a9bb67..8fee839 100644 --- a/src/oastat.cpp +++ b/src/oastat.cpp @@ -41,6 +41,9 @@ using namespace std; #ifdef USEDBIXX #include "db/Db2DbiXX.hpp" #endif + +#include "db/Db2Xml.hpp" + #include "oastatstruct.h" #include "oss2db/struct2db.h" #include "local.h" @@ -143,6 +146,13 @@ int main (int argc, const char* argv[]) db = new Db2DbiXX(dbargs); } #endif + if(backend == "Xml") { + cout << "Using XML" << endl; + if(dbargs.length()<1) + db = new Db2Xml(); + else + db = new Db2Xml(dbargs); + } if(!db) { string error("Failed to find backend: "); diff --git a/src/oss2db/init2db.cpp b/src/oss2db/init2db.cpp index 199dbc6..b5e4f34 100644 --- a/src/oss2db/init2db.cpp +++ b/src/oss2db/init2db.cpp @@ -50,8 +50,8 @@ void Init2Db::process(OaStatStruct oss) { it->first == "g_gametype" || it->first == "gamename" || it->first == "mapname" || - it->first == "sv_hostname" || - it->first == "g_timestamp" + it->first == "sv_hostname" /*|| + it->first == "g_timestamp" do not skip this one*/ ) continue; //Skip the ones on the games-table dp->addGameCvar(it->first,it->second);