// The good stuff: http://dev.mysql.com/doc/mysql/en/mysql_query.html #include "amxxmodule.h" #include "CRank.h" #include "rank.h" #ifndef __linux__ #define WINDOWS_LEAN_AND_MEAN #include #endif #include #include #include #define MYSQL_QUERY_IS_A_OKAY 0 cvar_t init_csx_sqlstats_host = {"csx_sqlstats_host", "127.0.0.1", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t init_csx_sqlstats_username = {"csx_sqlstats_username", "", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t init_csx_sqlstats_password = {"csx_sqlstats_password", "", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t init_csx_sqlstats_db = {"csx_sqlstats_db", "amxmodx_stats_cs", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t init_csx_sqlstats_table = {"csx_sqlstats_table", "cs", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t init_csx_sqlstats_exportstats = {"csx_sqlstats_exportstats", "0", FCVAR_SPONLY | FCVAR_PROTECTED}; cvar_t *csx_sqlstats_host; cvar_t *csx_sqlstats_username; cvar_t *csx_sqlstats_password; cvar_t *csx_sqlstats_db; cvar_t *csx_sqlstats_table; cvar_t *csx_sqlstats_exportstats; void OnMetaAttach_sql() { CVAR_REGISTER(&init_csx_sqlstats_host); CVAR_REGISTER(&init_csx_sqlstats_username); CVAR_REGISTER(&init_csx_sqlstats_password); CVAR_REGISTER(&init_csx_sqlstats_db); CVAR_REGISTER(&init_csx_sqlstats_table); CVAR_REGISTER(&init_csx_sqlstats_exportstats); csx_sqlstats_host = CVAR_GET_POINTER(init_csx_sqlstats_host.name); csx_sqlstats_username = CVAR_GET_POINTER(init_csx_sqlstats_username.name); csx_sqlstats_password = CVAR_GET_POINTER(init_csx_sqlstats_password.name); csx_sqlstats_db = CVAR_GET_POINTER(init_csx_sqlstats_db.name); csx_sqlstats_table = CVAR_GET_POINTER(init_csx_sqlstats_table.name); csx_sqlstats_exportstats = CVAR_GET_POINTER(init_csx_sqlstats_exportstats.name); } int Error(MYSQL *mysql) { if (mysql == NULL) return 0; return mysql_errno(mysql); } void RankSystem::saveRankSql() { // Don't do anything if cvar says so. if (csx_sqlstats_exportstats->value == 0.0) return; MF_PrintSrvConsole("[CSX Sql] Exporting players' statistics to SQL db..."); clock_t startTime = clock(); MYSQL *mysql = NULL; mysql = mysql_init(NULL); /* Attempt to get a port */ int port = 0; char *p = strchr(csx_sqlstats_host->string, ':'); if (p) port = atoi(p+1); /*************************/ //MF_PrintSrvConsole("Host: %s (%d) Port: %d", host, strcspn(csx_sqlstats_host->string, ":"), port); int error = 0; if (!mysql_real_connect(mysql, csx_sqlstats_host->string, csx_sqlstats_username->string, csx_sqlstats_password->string, NULL, port, NULL, 0)) { error = Error(mysql); if (error) { MF_Log("DB Connection failed (%d): %s", error, mysql_error(mysql)); mysql_close(mysql); return; } } if (mysql_select_db(mysql, csx_sqlstats_db->string) != 0) { error = Error(mysql); if (error) { MF_Log("DB Select DB failed (%d): %s", error, mysql_error(mysql)); mysql_close(mysql); return; } } // Query char query[2048]; snprintf(query, 2047, "CREATE TABLE IF NOT EXISTS `%s` (`timestamp` int(11) NOT NULL default '0', `stats_authid` varchar(100) NOT NULL default '', `stats_name` varchar(100) NOT NULL default '', `stats_tks` int(11) NOT NULL default '0', `stats_damage` int(11) NOT NULL default '0', `stats_deaths` int(11) NOT NULL default '0', `stats_frags` int(11) NOT NULL default '0', `stats_shots` int(11) NOT NULL default '0', `stats_hits` int(11) NOT NULL default '0', `stats_hs` int(11) NOT NULL default '0', `stats_defusions` int(11) NOT NULL default '0', `stats_defused` int(11) NOT NULL default '0', `stats_plants` int(11) NOT NULL default '0', `stats_explosions` int(11) NOT NULL default '0', `stats_bodyhits0` int(11) NOT NULL default '0', `stats_bodyhits1` int(11) NOT NULL default '0', `stats_bodyhits2` int(11) NOT NULL default '0', `stats_bodyhits3` int(11) NOT NULL default '0', `stats_bodyhits4` int(11) NOT NULL default '0', `stats_bodyhits5` int(11) NOT NULL default '0', `stats_bodyhits6` int(11) NOT NULL default '0', `stats_bodyhits7` int(11) NOT NULL default '0', `stats_bodyhits8` int(11) NOT NULL default '0', `stats_score` int(11) NOT NULL default '0') TYPE=MyISAM", csx_sqlstats_table->string); int queryResult = mysql_query(mysql, query); if (queryResult != MYSQL_QUERY_IS_A_OKAY) { error = Error(mysql); MF_Log("DB Query Create Table If Not Exists failed (%d): %s", error, mysql_error(mysql)); mysql_close(mysql); return; } int exportedRecords = 0; RankSystem::iterator a = front(); char *authid, *name; int tks, damage, deaths, kills, shots, hits, hs, defusions, defused, plants, explosions, *bodyHits, score; time_t now = time(NULL); while ( a ) { if ( (*a).score != (1<<31) ) // score must be different than mincell { authid = (*a).unique; if (strcmp(authid, "BOT") == 0 || strcmp(authid, "STEAM_ID_PENDING") == 0) { --a; continue; } exportedRecords++; name = (*a).name; tks = (*a).tks; damage = (*a).damage; deaths = (*a).deaths; kills = (*a).kills; shots = (*a).shots; hits = (*a).hits; hs = (*a).hs; defusions = (*a).bDefusions; defused = (*a).bDefused; plants = (*a).bPlants; explosions = (*a).bExplosions; bodyHits = ((*a).bodyHits); score = (*a).score; snprintf(query, 2047, "UPDATE `%s` SET `timestamp` = %d, `stats_name` = \"%s\", `stats_tks` = \"%d\", `stats_damage` = \"%d\", `stats_deaths` = \"%d\", `stats_frags` = \"%d\", `stats_shots` = \"%d\", `stats_hits` = \"%d\", `stats_hs` = \"%d\", `stats_defusions` = \"%d\", `stats_defused` = \"%d\", `stats_plants` = \"%d\", `stats_explosions` = \"%d\", `stats_bodyhits0` = \"%d\", `stats_bodyhits1` = \"%d\", `stats_bodyhits2` = \"%d\", `stats_bodyhits3` = \"%d\", `stats_bodyhits4` = \"%d\", `stats_bodyhits5` = \"%d\", `stats_bodyhits6` = \"%d\", `stats_bodyhits7` = \"%d\", `stats_bodyhits8` = \"%d\", `stats_score` = \"%d\" WHERE `stats_authid` = \"%s\" LIMIT 1", csx_sqlstats_table->string, now, name, tks, damage, deaths, kills, shots, hits, hs, defusions, defused, plants, explosions, bodyHits[0], bodyHits[1], bodyHits[2], bodyHits[3], bodyHits[4], bodyHits[5], bodyHits[6], bodyHits[7], bodyHits[8], score, authid); // int queryResult = mysql_query(mysql, query); if (queryResult != MYSQL_QUERY_IS_A_OKAY) { error = Error(mysql); MF_Log("DB Query Update failed (%d): %s", error, mysql_error(mysql)); mysql_close(mysql); return; } if (mysql_affected_rows(mysql) == 0) { // New player, do insert snprintf(query, 2047, "INSERT INTO `%s` (`timestamp`, `stats_authid`, `stats_name`, `stats_tks`, `stats_damage`, `stats_deaths`, `stats_frags`, `stats_shots`, `stats_hits`, `stats_hs`, `stats_defusions`, `stats_defused`, `stats_plants`, `stats_explosions`, `stats_bodyhits0`, `stats_bodyhits1`, `stats_bodyhits2`, `stats_bodyhits3`, `stats_bodyhits4`, `stats_bodyhits5`, `stats_bodyhits6`, `stats_bodyhits7`, `stats_bodyhits8`, `stats_score`) VALUES (\"%d\", \"%s\", \"%s\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\")", csx_sqlstats_table->string, now, authid, name, tks, damage, deaths, kills, shots, hits, hs, defusions, defused, plants, explosions, bodyHits[0], bodyHits[1], bodyHits[2], bodyHits[3], bodyHits[4], bodyHits[5], bodyHits[6], bodyHits[7], bodyHits[8], score ); int queryResult = mysql_query(mysql, query); if (queryResult != MYSQL_QUERY_IS_A_OKAY) { error = Error(mysql); MF_Log("DB Query Insert failed (%d): %s", error, mysql_error(mysql)); mysql_close(mysql); return; } } } --a; } // Disconnect mysql_close(mysql); clock_t stopTime = clock(); MF_PrintSrvConsole("...done! (exported %d records in %.2f seconds)\n", exportedRecords, (double)(stopTime - startTime) / (double)CLOCKS_PER_SEC); }