From b6ad40feb9a5e7df4ea8774d7a0bd2f3712e9c45 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 25 Mar 2018 16:03:11 +0200 Subject: [PATCH] sqlite3 player backend support fixes #47 --- PlayerAttributes.cpp | 81 ++++++++++++++++++++++++++++++++------ include/PlayerAttributes.h | 22 ++++------- 2 files changed, 76 insertions(+), 27 deletions(-) diff --git a/PlayerAttributes.cpp b/PlayerAttributes.cpp index 865e115..4950bde 100644 --- a/PlayerAttributes.cpp +++ b/PlayerAttributes.cpp @@ -1,15 +1,9 @@ -/* - * ===================================================================== - * Version: 1.0 - * Created: 01.09.2012 14:38:05 - * Author: Miroslav Bendík - * Company: LinuxOS.sk - * ===================================================================== - */ - -#include #include #include +#include +#include +#include // for usleep +#include #include "config.h" #include "PlayerAttributes.h" @@ -17,10 +11,24 @@ using namespace std; -PlayerAttributes::PlayerAttributes(const std::string &sourceDirectory) +PlayerAttributes::PlayerAttributes(const std::string &worldDir) { + std::ifstream ifs((worldDir + "world.mt").c_str()); + if (!ifs.good()) + throw std::runtime_error("Failed to read world.mt"); + std::string backend = read_setting_default("player_backend", ifs, "files"); + ifs.close(); - string playersPath = sourceDirectory + "players"; + if (backend == "files") + readFiles(worldDir + "players"); + else if (backend == "sqlite3") + readSqlite(worldDir + "players.sqlite"); + else + throw std::runtime_error(((std::string) "Unknown player backend: ") + backend); +} + +void PlayerAttributes::readFiles(const std::string &playersPath) +{ DIR *dir; dir = opendir (playersPath.c_str()); if (dir == NULL) @@ -64,6 +72,55 @@ PlayerAttributes::PlayerAttributes(const std::string &sourceDirectory) closedir(dir); } +/**********/ + +#define SQLRES(f, good) \ + result = (sqlite3_##f); \ + if (result != good) { \ + throw std::runtime_error(sqlite3_errmsg(db));\ + } +#define SQLOK(f) SQLRES(f, SQLITE_OK) + +void PlayerAttributes::readSqlite(const std::string &db_name) +{ + int result; + sqlite3 *db; + sqlite3_stmt *stmt_get_player_pos; + + SQLOK(open_v2(db_name.c_str(), &db, SQLITE_OPEN_READONLY | + SQLITE_OPEN_PRIVATECACHE, 0)) + + SQLOK(prepare_v2(db, + "SELECT name, posX, posY, posZ FROM player", + -1, &stmt_get_player_pos, NULL)) + + while ((result = sqlite3_step(stmt_get_player_pos)) != SQLITE_DONE) { + if (result == SQLITE_BUSY) { // Wait some time and try again + usleep(10000); + } else if (result != SQLITE_ROW) { + throw std::runtime_error(sqlite3_errmsg(db)); + } + + Player player; + const unsigned char *name_ = sqlite3_column_text(stmt_get_player_pos, 0); + player.name = std::string(reinterpret_cast(name_)); + player.x = sqlite3_column_double(stmt_get_player_pos, 1); + player.y = sqlite3_column_double(stmt_get_player_pos, 2); + player.z = sqlite3_column_double(stmt_get_player_pos, 3); + + player.x /= 10.0; + player.y /= 10.0; + player.z /= 10.0; + + m_players.push_back(player); + } + + sqlite3_finalize(stmt_get_player_pos); + sqlite3_close(db); +} + +/**********/ + PlayerAttributes::Players::iterator PlayerAttributes::begin() { return m_players.begin(); diff --git a/include/PlayerAttributes.h b/include/PlayerAttributes.h index 3cd1a0c..5abc291 100644 --- a/include/PlayerAttributes.h +++ b/include/PlayerAttributes.h @@ -1,12 +1,3 @@ -/* - * ===================================================================== - * Version: 1.0 - * Created: 01.09.2012 14:38:08 - * Author: Miroslav Bendík - * Company: LinuxOS.sk - * ===================================================================== - */ - #ifndef PLAYERATTRIBUTES_H_D7THWFVV #define PLAYERATTRIBUTES_H_D7THWFVV @@ -16,23 +7,24 @@ struct Player { std::string name; - double x; - double y; - double z; -}; /* ----- end of struct Player ----- */ + double x, y, z; +}; class PlayerAttributes { public: typedef std::list Players; - PlayerAttributes(const std::string &sourceDirectory); + PlayerAttributes(const std::string &worldDir); Players::iterator begin(); Players::iterator end(); private: + void readFiles(const std::string &playersPath); + void readSqlite(const std::string &db_name); + Players m_players; -}; /* ----- end of class PlayerAttributes ----- */ +}; #endif /* end of include guard: PLAYERATTRIBUTES_H_D7THWFVV */