diff --git a/src/Makefile b/src/Makefile index 5708eed..0c76171 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,7 @@ USESTDOUT=0 BASE_LIBS=-lgcrypt BASE_CFLAGS=-c -g -O_FILES=build/oastat.o build/oastatstruct.o build/kill2db.o build/init2db.o build/shutdown2db.o build/userinfo2db.o build/disconnect2db.o build/award2db.o +O_FILES=build/oastat.o build/oastatstruct.o build/kill2db.o build/init2db.o build/shutdown2db.o build/userinfo2db.o build/disconnect2db.o build/award2db.o build/ctf2db.o ifeq ($(USESTDOUT),1) O_FILES+= build/db2stdout.o @@ -66,3 +66,7 @@ build/disconnect2db.o: oss2db/Disconnect2Db.cpp oss2db/Disconnect2Db.h build/award2db.o: oss2db/Award2Db.cpp oss2db/Award2Db.h g++ $(BASE_CFLAGS) oss2db/Award2Db.cpp -o build/award2db.o + +build/ctf2db.o: oss2db/Ctf2Db.cpp + g++ $(BASE_CFLAGS) oss2db/Ctf2Db.cpp -o build/ctf2db.o + diff --git a/src/db/Db2DbiXX.cpp b/src/db/Db2DbiXX.cpp index 1713ccf..b7b0766 100644 --- a/src/db/Db2DbiXX.cpp +++ b/src/db/Db2DbiXX.cpp @@ -10,16 +10,21 @@ #define GETNEXTGAMENUMBER "SELECT nextval('oastat_games_gamenumber_seq')" #define STARTGAME "INSERT INTO oastat_games(gamenumber,gametype, mapname, basegame) VALUES (?,?,?,?)" -#define PLAYERSINSERT "INSERT INTO oastat_players(guid,nickname,lastseen,isBot, model, headmodel) VALUES (?,?,now(),?,?,?)" -#define PLAYERSUPDATE "UPDATE oastat_players SET nickname = ?,lastseen = now(),isBot = ?, model = ?, headmodel = ? WHERE guid = ?" +#define PLAYERSINSERT "INSERT INTO oastat_players(guid,nickname,lastseen,isBot, model, headmodel) VALUES (?,?,?,?,?,?)" +#define PLAYERSUPDATE "UPDATE oastat_players SET nickname = ?,lastseen = ?,isBot = ?, model = ?, headmodel = ? WHERE guid = ?" #define USERINFOINSERT "INSERT INTO oastat_userinfo(gamenumber,second,guid,team,model,skill) VALUES (?,?,?,?,?,?)" #define ENDGAME "UPDATE oastat_games SET second=?,time = now() where gamenumber = ?" #define KILL "INSERT INTO oastat_kills(gamenumber,second,attacker,target,modtype) VALUES(?,?,?,?,?)" #define CAPTURE "INSERT INTO oastat_captures(gamenumber,second,player,team) VALUES (?,?,?,?)" #define AWARD "INSERT INTO oastat_awards(gamenumber,second,player,award) VALUES (?,?,?,?)" +#define CTF "INSERT INTO oastat_team_events(gamenumber,second,team,player,gametype,eventtype) VALUES (?,?,?,?,'ctf',?)" static char* booltext[2] = {"false","true"}; +static long long int MakeTimestamp(tm timestamp) { + return mktime(×tamp); +} + Db2DbiXX::Db2DbiXX() { sql = new session("pgsql"); sql->param("dbname","oastat"); @@ -63,6 +68,7 @@ void Db2DbiXX::createTables() { } void Db2DbiXX::startGame(int gametype, string mapname, string basegame) { + sql->reconnect(); Rollback(); //in case there was some garbage that could be comitted (like warmup or an unfinished game) SetOk(true); gamenumber = getNextGameNumber(); @@ -83,18 +89,18 @@ int Db2DbiXX::getGameNumber() { return gamenumber; } -void Db2DbiXX::setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill) { +void Db2DbiXX::setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill, OaStatStruct *oss) { if(team>-1) { try{ *sql << "SAVEPOINT SETPLAYER",exec(); - *sql << PLAYERSINSERT,guid,nickname,booltext[isBot],model,headmodel,exec(); + *sql << PLAYERSINSERT,guid,nickname,oss->getDateTime(),booltext[isBot],model,headmodel,exec(); *sql << "RELEASE SAVEPOINT SETPLAYER",exec(); //Needed by postgresql }catch (dbixx_error &e) { DebugMessage("Already inserted? "+(string)e.what()); *sql << "ROLLBACK TO SAVEPOINT SETPLAYER",exec(); } - *sql << PLAYERSUPDATE,nickname,booltext[isBot],model,headmodel,guid,exec(); + *sql << PLAYERSUPDATE,nickname,oss->getDateTime(),booltext[isBot],model,headmodel,guid,exec(); } *sql << USERINFOINSERT,gamenumber,second,guid,team,model,skill,exec(); DebugMessage("setPlayerInfo for "+nickname+" with GUID: "+guid); @@ -115,6 +121,11 @@ void Db2DbiXX::addAward(int second, string player, int award) { DebugMessage("addAward"); } +void Db2DbiXX::addCtf(int second, string player, int team, int event) { + *sql << CTF,gamenumber,second,team,player,event,exec(); + DebugMessage("addCtf"); +} + int Db2DbiXX::getNextGameNumber() { int result = -1; row r; diff --git a/src/db/Db2DbiXX.hpp b/src/db/Db2DbiXX.hpp index fa01380..66ed8fc 100644 --- a/src/db/Db2DbiXX.hpp +++ b/src/db/Db2DbiXX.hpp @@ -27,10 +27,11 @@ public: void startGame(int gametype, string mapname, string basegame); void endGame(int second); int getGameNumber(); - void setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill); + 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 addCtf(int second, string player, int team, int event); private: session *sql; transaction *commitlock; diff --git a/src/db/Db2PostgreSQL.cpp b/src/db/Db2PostgreSQL.cpp index 99b1bab..13a87df 100644 --- a/src/db/Db2PostgreSQL.cpp +++ b/src/db/Db2PostgreSQL.cpp @@ -168,7 +168,7 @@ void Db2PostgreSQL::setPlayerInfo(string guid, string nickname, bool isBot, int { /* Note: There is a possible race condition here! - * One might consider ending the transaction and using autocommit for this part. + * There should be */ //simpleQuery("COMMIT"); sprintf(query_string,"SELECT * FROM oastat_players WHERE GUID = '%s'",sqlescape(guid).c_str()); diff --git a/src/db/database.hpp b/src/db/database.hpp index d0c02f5..9afe2da 100644 --- a/src/db/database.hpp +++ b/src/db/database.hpp @@ -24,6 +24,7 @@ Copyright (C) 2010 Poul Sander (oastat@poulsander.com) #include #include +#include "../oastatstruct.h" using namespace std; @@ -69,7 +70,7 @@ class Database { * @param headmodel - headmodel used * @param skill - bot skill, bots only */ - virtual void setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill = -1) = 0; + virtual void setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill, OaStatStruct *oss) = 0; /** * Represents a kill @@ -98,6 +99,22 @@ class Database { * @param award the award, numbers must be found in code */ virtual void addAward(int second, string player, int award) = 0; + + /** + * Adds an event from a CTF-game. + * + * Note that event: + * 0 | Flag is taken + * 1 | Flag is captured + * 2 | Flag is returned + * 3 | Flagcarrier got killed + * + * @param second + * @param player + * @param team + * @param event + */ + virtual void addCtf(int second, string player, int team, int event) = 0; }; #endif //_DATABASE_H diff --git a/src/db/db2stdout.cpp b/src/db/db2stdout.cpp index b8fd868..e47d257 100644 --- a/src/db/db2stdout.cpp +++ b/src/db/db2stdout.cpp @@ -110,4 +110,8 @@ void DB2stdout::addAward(int second, string player, int award) { printf(AWARD,gamenumber,second,player.c_str(),award); cout << endl; +} + +void addCtf(int second, string player, int team, int event) { + cout << "missing" << endl; } \ No newline at end of file diff --git a/src/db/db2stdout.h b/src/db/db2stdout.h index 00ee71e..66fab57 100644 --- a/src/db/db2stdout.h +++ b/src/db/db2stdout.h @@ -38,6 +38,7 @@ public: 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 addCtf(int second, string player, int team, int event); private: int gamenumber; }; diff --git a/src/oastat.cpp b/src/oastat.cpp index dde6357..8faf472 100644 --- a/src/oastat.cpp +++ b/src/oastat.cpp @@ -48,6 +48,7 @@ using namespace std; #include "oss2db/userinfo2db.h" #include "oss2db/Disconnect2Db.h" #include "oss2db/Award2Db.h" +#include "oss2db/Ctf2Db.hpp" string clientIdMap[MAX_ID]; @@ -70,6 +71,7 @@ void addCommands() commands.push_back(new Userinfo2Db()); commands.push_back(new Disconnect2Db()); commands.push_back(new Award2Db()); + commands.push_back(new Ctf2Db()); //Add more commands just above here for(int i=0;i #include #include +#include OaStatStruct::OaStatStruct() { second = 0; @@ -38,6 +39,7 @@ OaStatStruct::OaStatStruct(const OaStatStruct& orig) { command = orig.command; parameters = orig.parameters; restOfLine = orig.restOfLine; + _datetime = orig._datetime; } OaStatStruct::~OaStatStruct() { @@ -57,6 +59,8 @@ void OaStatStruct::parseLine(string line) { string tempTimeString = line.substr(0,7); int posColon = tempTimeString.find(":"); int minute = atoi(tempTimeString.substr(0,posColon).c_str()); + time_t thetime = time(NULL); + gmtime_r(&thetime,&_datetime); second = atoi(tempTimeString.substr(posColon+1,7).c_str()); second+=minute*60; line = line.substr(7,line.length()); //Cut the first part of the string. @@ -123,3 +127,25 @@ map OaStatStruct::GetInfostring(string restOfLine) { map OaStatStruct::GetInfostring() { return GetInfostring(restOfLine); } + +tm OaStatStruct::getDateTime() { + return _datetime; +} + +string ZeroPadNumber(int num, int size = 2) +{ + std::ostringstream ss; + ss.clear(); + ss << setw( size ) << setfill( '0' ) << num; + return ss.str(); +} + +string OaStatStruct::getTimeStamp() { + string s; + s = "TIMESTAMP \'" + ZeroPadNumber(_datetime.tm_year+1900,4) + "-" + ZeroPadNumber(_datetime.tm_mon) + "-" + + ZeroPadNumber(_datetime.tm_mday) + " " + ZeroPadNumber(_datetime.tm_hour) + ":" + + ZeroPadNumber(_datetime.tm_min) + ":" + ZeroPadNumber(_datetime.tm_sec) + "\'"; + return s; +} + + diff --git a/src/oastatstruct.h b/src/oastatstruct.h index 5263b6d..b77e005 100644 --- a/src/oastatstruct.h +++ b/src/oastatstruct.h @@ -25,6 +25,7 @@ Copyright (C) 2010 Poul Sander (oastat@poulsander.com) #include #include #include +#include using namespace std; @@ -43,6 +44,7 @@ public: string command; //Like 'ClientConnect', 'Award' and 'Kill' vector parameters; //The parameters for the command. string restOfLine; + tm getDateTime(); void parseLine(string line); void clear(); @@ -56,8 +58,14 @@ public: *Same but uses this.restOfLine */ map GetInfostring(); -private: + /* + Returns a string with the time in the format: + * TIMESTAMP 'YYYY-MM- + */ + string getTimeStamp(); +private: + tm _datetime; }; #endif /* _OASTATSTRUCT_H */ diff --git a/src/oss2db/Ctf2Db.cpp b/src/oss2db/Ctf2Db.cpp new file mode 100644 index 0000000..78ec84f --- /dev/null +++ b/src/oss2db/Ctf2Db.cpp @@ -0,0 +1,33 @@ +/* + * File: Ctf2Db.cpp + * Author: poul + * + * Created on 19. november 2010, 23:08 + */ + +#include "Ctf2Db.hpp" + +Ctf2Db::Ctf2Db() { +} + +Ctf2Db::Ctf2Db(const Ctf2Db& orig) { +} + +Ctf2Db::~Ctf2Db() { +} + + +string Ctf2Db::getCommand() { + return "CTF"; +} + +void Ctf2Db::process(OaStatStruct oss) { + if(oss.command != getCommand() || oss.parameters.size()<3 || oss.parameters.at(0)<0) + return; //Invalid oss + + string player = ""; + if(oss.parameters.at(0)!=-1) + player= clientIdMap[oss.parameters.at(0)]; + + dp->addCtf(oss.second,player,oss.parameters.at(1) /*team*/, oss.parameters.at(2) /*event*/); +} diff --git a/src/oss2db/Ctf2Db.hpp b/src/oss2db/Ctf2Db.hpp new file mode 100644 index 0000000..6d9bfdd --- /dev/null +++ b/src/oss2db/Ctf2Db.hpp @@ -0,0 +1,28 @@ +/* + * File: Ctf2Db.hpp + * Author: poul + * + * Created on 19. november 2010, 23:08 + */ + +#ifndef _CTF2DB_HPP +#define _CTF2DB_HPP + +#include "struct2db.h" +#include "../local.h" + +class Ctf2Db : public Struct2Db { +public: + Ctf2Db(); + Ctf2Db(const Ctf2Db& orig); + virtual ~Ctf2Db(); + + string getCommand(); + + void process(OaStatStruct oss); +private: + +}; + +#endif /* _CTF2DB_HPP */ + diff --git a/src/oss2db/Disconnect2Db.cpp b/src/oss2db/Disconnect2Db.cpp index 098f62d..dc17eba 100644 --- a/src/oss2db/Disconnect2Db.cpp +++ b/src/oss2db/Disconnect2Db.cpp @@ -40,5 +40,5 @@ void Disconnect2Db::process(OaStatStruct oss) { string player = clientIdMap[oss.parameters.at(0)]; - dp->setPlayerInfo(player,"",false,oss.second,-1,"","",-1); + dp->setPlayerInfo(player,"",false,oss.second,-1,"","",-1,&oss); } diff --git a/src/oss2db/shutdown2db.cpp b/src/oss2db/shutdown2db.cpp index a20554c..e6abe60 100644 --- a/src/oss2db/shutdown2db.cpp +++ b/src/oss2db/shutdown2db.cpp @@ -39,4 +39,8 @@ void Shutdown2Db::process(OaStatStruct oss) { if(oss.command != getCommand()) return; dp->endGame(oss.second); -} \ No newline at end of file +} + +bool Shutdown2Db::shouldCommit() { + return true; +} diff --git a/src/oss2db/shutdown2db.h b/src/oss2db/shutdown2db.h index d2681a5..be36ce2 100644 --- a/src/oss2db/shutdown2db.h +++ b/src/oss2db/shutdown2db.h @@ -34,6 +34,8 @@ public: string getCommand(); void process(OaStatStruct oss); + + bool shouldCommit(); private: }; diff --git a/src/oss2db/struct2db.h b/src/oss2db/struct2db.h index 7574a48..6308905 100644 --- a/src/oss2db/struct2db.h +++ b/src/oss2db/struct2db.h @@ -52,6 +52,8 @@ class Struct2Db { */ virtual void process(OaStatStruct oss) = 0; + virtual bool shouldCommit() { return false; }; + protected: Database *dp; //Pointer to the used db }; diff --git a/src/oss2db/userinfo2db.cpp b/src/oss2db/userinfo2db.cpp index 3698c43..b5856f2 100644 --- a/src/oss2db/userinfo2db.cpp +++ b/src/oss2db/userinfo2db.cpp @@ -45,5 +45,5 @@ void Userinfo2Db::process(OaStatStruct oss) { else //bot clientIdMap[oss.parameters.at(0)] = arguments["n"]; - dp->setPlayerInfo(clientIdMap[oss.parameters.at(0)],arguments["n"],arguments["id"]=="",oss.second,atoi(arguments["t"].c_str()), arguments["model"],arguments["hmodel"]); + dp->setPlayerInfo(clientIdMap[oss.parameters.at(0)],arguments["n"],arguments["id"]=="",oss.second,atoi(arguments["t"].c_str()), arguments["model"],arguments["hmodel"],-1,&oss); }