From b3ac5b5d6c36ec819715b39025f4a81a71277593 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 22:58:12 -0300 Subject: [PATCH 1/6] Refactor database: Extracted into tfs::db namespace --- src/ban.cpp | 15 +-- src/database.cpp | 173 +++++++++++++++++-------------- src/database.h | 189 ++++++++++++++-------------------- src/databasemanager.cpp | 45 ++++---- src/databasetasks.cpp | 10 +- src/databasetasks.h | 2 - src/game.cpp | 10 +- src/guild.cpp | 11 +- src/house.cpp | 3 +- src/http/cacheinfo.cpp | 4 +- src/http/login.cpp | 18 ++-- src/http/tests/test_login.cpp | 21 ++-- src/iologindata.cpp | 178 ++++++++++++++------------------ src/iomapserialize.cpp | 54 ++++------ src/iomarket.cpp | 28 +++-- src/luascript.cpp | 40 +++---- src/otserv.cpp | 4 +- src/protocolgame.cpp | 13 ++- src/protocollogin.cpp | 18 ++-- 19 files changed, 376 insertions(+), 460 deletions(-) diff --git a/src/ban.cpp b/src/ban.cpp index 1cc261fa1c..42d4dbbab7 100644 --- a/src/ban.cpp +++ b/src/ban.cpp @@ -13,9 +13,7 @@ namespace IOBan { const std::optional getAccountBanInfo(uint32_t accountId) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `reason`, `expires_at`, `banned_at`, `banned_by`, (SELECT `name` FROM `players` WHERE `id` = `banned_by`) AS `name` FROM `account_bans` WHERE `account_id` = {:d}", accountId)); if (!result) { @@ -27,8 +25,8 @@ const std::optional getAccountBanInfo(uint32_t accountId) // Move the ban to history if it has expired g_databaseTasks.addTask(fmt::format( "INSERT INTO `account_ban_history` (`account_id`, `reason`, `banned_at`, `expired_at`, `banned_by`) VALUES ({:d}, {:s}, {:d}, {:d}, {:d})", - accountId, db.escapeString(result->getString("reason")), result->getNumber("banned_at"), expiresAt, - result->getNumber("banned_by"))); + accountId, tfs::db::escape_string(result->getString("reason")), result->getNumber("banned_at"), + expiresAt, result->getNumber("banned_by"))); g_databaseTasks.addTask(fmt::format("DELETE FROM `account_bans` WHERE `account_id` = {:d}", accountId)); return std::nullopt; } @@ -51,9 +49,7 @@ const std::optional getIpBanInfo(const Connection::Address& clientIP) return std::nullopt; } - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `reason`, `expires_at`, (SELECT `name` FROM `players` WHERE `id` = `banned_by`) AS `name` FROM `ip_bans` WHERE `ip` = INET6_ATON('{:s}')", clientIP.to_string())); if (!result) { @@ -81,8 +77,7 @@ const std::optional getIpBanInfo(const Connection::Address& clientIP) bool isPlayerNamelocked(uint32_t playerId) { - return Database::getInstance() - .storeQuery(fmt::format("SELECT 1 FROM `player_namelocks` WHERE `player_id` = {:d}", playerId)) + return tfs::db::store_query(fmt::format("SELECT 1 FROM `player_namelocks` WHERE `player_id` = {:d}", playerId)) .get(); } diff --git a/src/database.cpp b/src/database.cpp index 91f644ce8e..9fc73292eb 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -9,21 +9,37 @@ #include -static tfs::detail::Mysql_ptr connectToDatabase(const bool retryIfError) +namespace { + +std::recursive_mutex database_lock; +tfs::db::detail::Mysql_ptr handle = nullptr; +uint64_t packet_size = 1048576; + +// Do not retry queries if we are in the middle of a transaction +bool retry_queries = true; + +bool is_lost_connection_error(const unsigned error) { - bool isFirstAttemptToConnect = true; + return error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR || error == CR_CONN_HOST_ERROR || + error == 1053 /*ER_SERVER_SHUTDOWN*/ || error == CR_CONNECTION_ERROR; +} + +tfs::db::detail::Mysql_ptr connect_to_database(const bool retryIfError) +{ + auto is_first_attempt_to_connect = true; retry: - if (!isFirstAttemptToConnect) { + if (!is_first_attempt_to_connect) { std::this_thread::sleep_for(std::chrono::seconds(1)); } - isFirstAttemptToConnect = false; + is_first_attempt_to_connect = false; - tfs::detail::Mysql_ptr handle{mysql_init(nullptr)}; + tfs::db::detail::Mysql_ptr handle{mysql_init(nullptr)}; if (!handle) { std::cout << std::endl << "Failed to initialize MySQL connection handle." << std::endl; goto error; } + // connects to database if (!mysql_real_connect(handle.get(), getString(ConfigManager::MYSQL_HOST).c_str(), getString(ConfigManager::MYSQL_USER).c_str(), getString(ConfigManager::MYSQL_PASS).c_str(), @@ -41,122 +57,91 @@ static tfs::detail::Mysql_ptr connectToDatabase(const bool retryIfError) return nullptr; } -static bool isLostConnectionError(const unsigned error) -{ - return error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR || error == CR_CONN_HOST_ERROR || - error == 1053 /*ER_SERVER_SHUTDOWN*/ || error == CR_CONNECTION_ERROR; -} - -static bool executeQuery(tfs::detail::Mysql_ptr& handle, std::string_view query, const bool retryIfLostConnection) +bool execute_query_handle(tfs::db::detail::Mysql_ptr& handle, std::string_view query, const bool retryIfLostConnection) { while (mysql_real_query(handle.get(), query.data(), query.length()) != 0) { std::cout << "[Error - mysql_real_query] Query: " << query.substr(0, 256) << std::endl << "Message: " << mysql_error(handle.get()) << std::endl; const unsigned error = mysql_errno(handle.get()); - if (!isLostConnectionError(error) || !retryIfLostConnection) { + if (!is_lost_connection_error(error) || !retryIfLostConnection) { return false; } - handle = connectToDatabase(true); + handle = connect_to_database(true); } return true; } -bool Database::connect() +} // namespace + +bool tfs::db::connect() { - auto newHandle = connectToDatabase(false); - if (!newHandle) { + auto new_handle = connect_to_database(false); + if (!new_handle) { return false; } - handle = std::move(newHandle); - DBResult_ptr result = storeQuery("SHOW VARIABLES LIKE 'max_allowed_packet'"); - if (result) { - maxPacketSize = result->getNumber("Value"); + handle = std::move(new_handle); + if (auto result = store_query("SHOW VARIABLES LIKE 'max_allowed_packet'")) { + packet_size = result->getNumber("Value"); } return true; } -bool Database::beginTransaction() +bool tfs::db::execute_query(std::string_view query) { - databaseLock.lock(); - const bool result = executeQuery("START TRANSACTION"); - retryQueries = !result; - if (!result) { - databaseLock.unlock(); - } - return result; -} + std::lock_guard lockGuard(database_lock); + auto success = ::execute_query_handle(handle, query, retry_queries); -bool Database::rollback() -{ - const bool result = executeQuery("ROLLBACK"); - retryQueries = true; - databaseLock.unlock(); - return result; -} - -bool Database::commit() -{ - const bool result = executeQuery("COMMIT"); - retryQueries = true; - databaseLock.unlock(); - return result; -} - -bool Database::executeQuery(const std::string& query) -{ - std::lock_guard lockGuard(databaseLock); - auto success = ::executeQuery(handle, query, retryQueries); - - // executeQuery can be called with command that produces result (e.g. SELECT) + // execute_query_handle can be called with command that produces result (e.g. SELECT) // we have to store that result, even though we do not need it, otherwise handle will get blocked - auto mysql_res = mysql_store_result(handle.get()); - mysql_free_result(mysql_res); + auto store_result = mysql_store_result(handle.get()); + mysql_free_result(store_result); return success; } -DBResult_ptr Database::storeQuery(std::string_view query) +DBResult_ptr tfs::db::store_query(std::string_view query) { - std::lock_guard lockGuard(databaseLock); + std::lock_guard lockGuard(database_lock); retry: - if (!::executeQuery(handle, query, retryQueries) && !retryQueries) { + if (!::execute_query_handle(handle, query, retry_queries) && !retry_queries) { return nullptr; } - // we should call that every time as someone would call executeQuery('SELECT...') + // we should call that every time as someone would call execute_query_handle('SELECT...') // as it is described in MySQL manual: "it doesn't hurt" :P - tfs::detail::MysqlResult_ptr res{mysql_store_result(handle.get())}; + tfs::db::detail::MysqlResult_ptr res{mysql_store_result(handle.get())}; if (!res) { std::cout << "[Error - mysql_store_result] Query: " << query << std::endl << "Message: " << mysql_error(handle.get()) << std::endl; const unsigned error = mysql_errno(handle.get()); - if (!isLostConnectionError(error) || !retryQueries) { + if (!is_lost_connection_error(error) || !retry_queries) { return nullptr; } goto retry; } // retrieving results of query - DBResult_ptr result = std::make_shared(std::move(res)); + auto result = std::make_shared(std::move(res)); if (!result->hasNext()) { return nullptr; } return result; } -std::string Database::escapeBlob(const char* s, uint32_t length) const -{ - // the worst case is 2n + 1 - size_t maxLength = (length * 2) + 1; +std::string tfs::db::escape_string(std::string_view s) { return escape_blob(s.data(), s.length()); } + +std::string tfs::db::escape_blob(const char* s, uint32_t length) +{ // the worst case is 2n + 1 + size_t max_length = (length * 2) + 1; std::string escaped; - escaped.reserve(maxLength + 2); + escaped.reserve(max_length + 2); escaped.push_back('\''); if (length != 0) { - char* output = new char[maxLength]; + char* output = new char[max_length]; mysql_real_escape_string(handle.get(), output, s, length); escaped.append(output); delete[] output; @@ -166,7 +151,40 @@ std::string Database::escapeBlob(const char* s, uint32_t length) const return escaped; } -DBResult::DBResult(tfs::detail::MysqlResult_ptr&& res) : handle{std::move(res)} +uint64_t tfs::db::last_insert_id() { return static_cast(mysql_insert_id(handle.get())); } + +const char* tfs::db::client_version() { return mysql_get_client_info(); } + +uint64_t tfs::db::max_packet_size() { return packet_size; } + +bool tfs::db::transaction::begin() +{ + database_lock.lock(); + const auto result = tfs::db::execute_query("START TRANSACTION"); + retry_queries = !result; + if (!result) { + database_lock.unlock(); + } + return result; +} + +bool tfs::db::transaction::rollback() +{ + const auto result = tfs::db::execute_query("ROLLBACK"); + retry_queries = true; + database_lock.unlock(); + return result; +} + +bool tfs::db::transaction::commit() +{ + const auto result = tfs::db::execute_query("COMMIT"); + retry_queries = true; + database_lock.unlock(); + return result; +} + +DBResult::DBResult(tfs::db::detail::MysqlResult_ptr&& res) : handle{std::move(res)} { size_t i = 0; @@ -209,19 +227,20 @@ DBInsert::DBInsert(std::string query) : query(std::move(query)) { this->length = bool DBInsert::addRow(const std::string& row) { // adds new row to buffer - const size_t rowLength = row.length(); - length += rowLength; - if (length > Database::getInstance().getMaxPacketSize() && !execute()) { + const size_t row_length = row.length(); + length += row_length; + + if (length > tfs::db::max_packet_size() && !execute()) { return false; } if (values.empty()) { - values.reserve(rowLength + 2); + values.reserve(row_length + 2); values.push_back('('); values.append(row); values.push_back(')'); } else { - values.reserve(values.length() + rowLength + 3); + values.reserve(values.length() + row_length + 3); values.push_back(','); values.push_back('('); values.append(row); @@ -232,9 +251,9 @@ bool DBInsert::addRow(const std::string& row) bool DBInsert::addRow(std::ostringstream& row) { - bool ret = addRow(row.str()); + auto result = addRow(row.str()); row.str(std::string()); - return ret; + return result; } bool DBInsert::execute() @@ -244,8 +263,8 @@ bool DBInsert::execute() } // executes buffer - bool res = Database::getInstance().executeQuery(query + values); + auto result = tfs::db::execute_query(query + values); values.clear(); length = query.length(); - return res; + return result; } diff --git a/src/database.h b/src/database.h index 199b69a7d6..c3db93e273 100644 --- a/src/database.h +++ b/src/database.h @@ -9,7 +9,79 @@ class DBResult; using DBResult_ptr = std::shared_ptr; -namespace tfs::detail { +namespace tfs::db { + +/// @brief Connects to the database. +/// @return true on successful connection, false on error. +bool connect(); + +/// @brief Executes a command that does not return results. +/// +/// This is used for queries such as INSERT, UPDATE, DELETE, etc. +/// @param {query} The SQL command to execute. +/// @return true on success, false on error. +bool execute_query(std::string_view query); + +/// @brief Queries the database and retrieves results. +/// +/// Executes a query that generates results, typically a SELECT statement. +/// @param {query} The SQL query to execute. +/// @return A DBResult_ptr object containing the results, or nullptr on error. +DBResult_ptr store_query(std::string_view query); + +/// @brief Escapes a string for use in an SQL query. +/// +/// Prepares a string to be safely included in SQL statements, adding necessary +/// escaping and quoting. +/// @param {s} The string to escape. +/// @return The escaped and quoted string. +std::string escape_string(std::string_view s); + +/// @brief Escapes a binary stream for use in an SQL query. +/// +/// Converts a binary stream into a format suitable for inclusion in SQL +/// statements. +/// @param {s} The binary stream to escape. +/// @param {length} The length of the binary stream. +/// @return The escaped and quoted string. +std::string escape_blob(const char* s, uint32_t length); + +/// @brief Retrieves the ID of the last inserted row. +/// +/// If the last query involved an auto-increment column, this retrieves the ID +/// of the row that was inserted. +/// @return The last inserted ID, or 0 if no rows were affected. +uint64_t last_insert_id(); + +/// @brief Gets the version of the database client engine. +/// +/// @return A string containing the database engine version. +const char* client_version(); + +/// @brief Retrieves the maximum packet size allowed by the database. +/// +/// @return The maximum packet size in bytes. +uint64_t max_packet_size(); + +} // namespace tfs::db + +namespace tfs::db::transaction { + +/// @brief Begins a database transaction. +/// @return true on success, false on error. +bool begin(); + +/// @brief Rolls back the current database transaction. +/// @return true on success, false on error. +bool rollback(); + +/// @brief Commits the current database transaction. +/// @return true on success, false on error. +bool commit(); + +} // namespace tfs::db::transaction + +namespace tfs::db::detail { struct MysqlDeleter { @@ -20,113 +92,12 @@ struct MysqlDeleter using Mysql_ptr = std::unique_ptr; using MysqlResult_ptr = std::unique_ptr; -} // namespace tfs::detail - -class Database -{ -public: - /** - * Singleton implementation. - * - * @return database connection handler singleton - */ - static Database& getInstance() - { - static Database instance; - return instance; - } - - /** - * Connects to the database - * - * @return true on successful connection, false on error - */ - bool connect(); - - /** - * Executes command. - * - * Executes query which doesn't generates results (eg. INSERT, UPDATE, - * DELETE...). - * - * @param query command - * @return true on success, false on error - */ - bool executeQuery(const std::string& query); - - /** - * Queries database. - * - * Executes query which generates results (mostly SELECT). - * - * @return results object (nullptr on error) - */ - DBResult_ptr storeQuery(std::string_view query); - - /** - * Escapes string for query. - * - * Prepares string to fit SQL queries including quoting it. - * - * @param s string to be escaped - * @return quoted string - */ - std::string escapeString(std::string_view s) const { return escapeBlob(s.data(), s.length()); } - - /** - * Escapes binary stream for query. - * - * Prepares binary stream to fit SQL queries. - * - * @param s binary stream - * @param length stream length - * @return quoted string - */ - std::string escapeBlob(const char* s, uint32_t length) const; - - /** - * Retrieve id of last inserted row - * - * @return id on success, 0 if last query did not result on any rows with - * auto_increment keys - */ - uint64_t getLastInsertId() const { return static_cast(mysql_insert_id(handle.get())); } - - /** - * Get database engine version - * - * @return the database engine version - */ - static const char* getClientVersion() { return mysql_get_client_info(); } - - uint64_t getMaxPacketSize() const { return maxPacketSize; } - -private: - /** - * Transaction related methods. - * - * Methods for starting, committing and rolling back transaction. Each of - * the returns boolean value. - * - * @return true on success, false on error - */ - bool beginTransaction(); - bool rollback(); - bool commit(); - - tfs::detail::Mysql_ptr handle = nullptr; - std::recursive_mutex databaseLock; - uint64_t maxPacketSize = 1048576; - // Do not retry queries if we are in the middle of a transaction - bool retryQueries = true; - - friend class DBTransaction; -}; +} // namespace tfs::db::detail class DBResult { public: - explicit DBResult(tfs::detail::MysqlResult_ptr&& res); + explicit DBResult(tfs::db::detail::MysqlResult_ptr&& res); // non-copyable DBResult(const DBResult&) = delete; @@ -155,12 +126,10 @@ class DBResult bool next(); private: - tfs::detail::MysqlResult_ptr handle; + tfs::db::detail::MysqlResult_ptr handle; MYSQL_ROW row; std::map listNames; - - friend class Database; }; /** @@ -188,7 +157,7 @@ class DBTransaction ~DBTransaction() { if (state == STATE_START) { - Database::getInstance().rollback(); + tfs::db::transaction::rollback(); } } @@ -199,7 +168,7 @@ class DBTransaction bool begin() { state = STATE_START; - return Database::getInstance().beginTransaction(); + return tfs::db::transaction::begin(); } bool commit() @@ -209,7 +178,7 @@ class DBTransaction } state = STATE_COMMIT; - return Database::getInstance().commit(); + return tfs::db::transaction::commit(); } private: diff --git a/src/databasemanager.cpp b/src/databasemanager.cpp index 76dc384a95..d9a9550f69 100644 --- a/src/databasemanager.cpp +++ b/src/databasemanager.cpp @@ -10,11 +10,9 @@ bool DatabaseManager::optimizeTables() { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = {:s} AND `DATA_FREE` > 0", - db.escapeString(getString(ConfigManager::MYSQL_DB)))); + tfs::db::escape_string(getString(ConfigManager::MYSQL_DB)))); if (!result) { return false; } @@ -23,7 +21,7 @@ bool DatabaseManager::optimizeTables() const auto tableName = result->getString("TABLE_NAME"); std::cout << "> Optimizing table " << tableName << "..." << std::flush; - if (db.executeQuery(fmt::format("OPTIMIZE TABLE `{:s}`", tableName))) { + if (tfs::db::execute_query(fmt::format("OPTIMIZE TABLE `{:s}`", tableName))) { std::cout << " [success]" << std::endl; } else { std::cout << " [failed]" << std::endl; @@ -34,30 +32,27 @@ bool DatabaseManager::optimizeTables() bool DatabaseManager::tableExists(const std::string& tableName) { - Database& db = Database::getInstance(); - return db - .storeQuery(fmt::format( - "SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = {:s} AND `TABLE_NAME` = {:s} LIMIT 1", - db.escapeString(getString(ConfigManager::MYSQL_DB)), db.escapeString(tableName))) + return tfs::db::store_query( + fmt::format( + "SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = {:s} AND `TABLE_NAME` = {:s} LIMIT 1", + tfs::db::escape_string(getString(ConfigManager::MYSQL_DB)), tfs::db::escape_string(tableName))) .get(); } bool DatabaseManager::isDatabaseSetup() { - Database& db = Database::getInstance(); - return db - .storeQuery(fmt::format("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = {:s}", - db.escapeString(getString(ConfigManager::MYSQL_DB)))) + return tfs::db::store_query( + fmt::format("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = {:s}", + tfs::db::escape_string(getString(ConfigManager::MYSQL_DB)))) .get(); } int32_t DatabaseManager::getDatabaseVersion() { if (!tableExists("server_config")) { - Database& db = Database::getInstance(); - db.executeQuery( + tfs::db::execute_query( "CREATE TABLE `server_config` (`config` VARCHAR(50) NOT NULL, `value` VARCHAR(256) NOT NULL DEFAULT '', UNIQUE(`config`)) ENGINE = InnoDB"); - db.executeQuery("INSERT INTO `server_config` VALUES ('db_version', 0)"); + tfs::db::execute_query("INSERT INTO `server_config` VALUES ('db_version', 0)"); return 0; } @@ -125,10 +120,8 @@ void DatabaseManager::updateDatabase() bool DatabaseManager::getDatabaseConfig(const std::string& config, int32_t& value) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery( - fmt::format("SELECT `value` FROM `server_config` WHERE `config` = {:s}", db.escapeString(config))); + auto result = tfs::db::store_query( + fmt::format("SELECT `value` FROM `server_config` WHERE `config` = {:s}", tfs::db::escape_string(config))); if (!result) { return false; } @@ -139,15 +132,13 @@ bool DatabaseManager::getDatabaseConfig(const std::string& config, int32_t& valu void DatabaseManager::registerDatabaseConfig(const std::string& config, int32_t value) { - Database& db = Database::getInstance(); - int32_t tmp; if (!getDatabaseConfig(config, tmp)) { - db.executeQuery( - fmt::format("INSERT INTO `server_config` VALUES ({:s}, '{:d}')", db.escapeString(config), value)); + tfs::db::execute_query( + fmt::format("INSERT INTO `server_config` VALUES ({:s}, '{:d}')", tfs::db::escape_string(config), value)); } else { - db.executeQuery(fmt::format("UPDATE `server_config` SET `value` = '{:d}' WHERE `config` = {:s}", value, - db.escapeString(config))); + tfs::db::execute_query(fmt::format("UPDATE `server_config` SET `value` = '{:d}' WHERE `config` = {:s}", value, + tfs::db::escape_string(config))); } } diff --git a/src/databasetasks.cpp b/src/databasetasks.cpp index 86f0aae79e..c965febac9 100644 --- a/src/databasetasks.cpp +++ b/src/databasetasks.cpp @@ -9,12 +9,6 @@ extern Dispatcher g_dispatcher; -void DatabaseTasks::start() -{ - db.connect(); - ThreadHolder::start(); -} - void DatabaseTasks::threadMain() { std::unique_lock taskLockUnique(taskLock, std::defer_lock); @@ -56,11 +50,11 @@ void DatabaseTasks::runTask(const DatabaseTask& task) bool success; DBResult_ptr result; if (task.store) { - result = db.storeQuery(task.query); + result = tfs::db::store_query(task.query); success = true; } else { result = nullptr; - success = db.executeQuery(task.query); + success = tfs::db::execute_query(task.query); } if (task.callback) { diff --git a/src/databasetasks.h b/src/databasetasks.h index f27805eb70..bba4e470ff 100644 --- a/src/databasetasks.h +++ b/src/databasetasks.h @@ -22,7 +22,6 @@ class DatabaseTasks : public ThreadHolder { public: DatabaseTasks() = default; - void start(); void flush(); void shutdown(); @@ -33,7 +32,6 @@ class DatabaseTasks : public ThreadHolder private: void runTask(const DatabaseTask& task); - Database db; std::thread thread; std::list tasks; std::mutex taskLock; diff --git a/src/game.cpp b/src/game.cpp index fe99a45dc8..5a0e00082e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4913,20 +4913,16 @@ void Game::checkPlayersRecord() void Game::updatePlayersRecord() const { - Database& db = Database::getInstance(); - db.executeQuery( + tfs::db::execute_query( fmt::format("UPDATE `server_config` SET `value` = '{:d}' WHERE `config` = 'players_record'", playersRecord)); } void Game::loadPlayersRecord() { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `config` = 'players_record'"); - if (result) { + if (auto result = tfs::db::store_query("SELECT `value` FROM `server_config` WHERE `config` = 'players_record'")) { playersRecord = result->getNumber("value"); } else { - db.executeQuery("INSERT INTO `server_config` (`config`, `value`) VALUES ('players_record', '0')"); + tfs::db::execute_query("INSERT INTO `server_config` (`config`, `value`) VALUES ('players_record', '0')"); } } diff --git a/src/guild.cpp b/src/guild.cpp index e4e3680d90..ecf537720a 100644 --- a/src/guild.cpp +++ b/src/guild.cpp @@ -58,14 +58,13 @@ GuildRank_ptr Guild::getRankByLevel(uint8_t level) const Guild_ptr IOGuild::loadGuild(uint32_t guildId) { - Database& db = Database::getInstance(); - DBResult_ptr result = db.storeQuery(fmt::format("SELECT `name` FROM `guilds` WHERE `id` = {:d}", guildId)); + auto result = tfs::db::store_query(fmt::format("SELECT `name` FROM `guilds` WHERE `id` = {:d}", guildId)); if (!result) { return nullptr; } const auto& guild = std::make_shared(guildId, result->getString("name")); - if ((result = db.storeQuery( + if ((result = tfs::db::store_query( fmt::format("SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = {:d}", guildId)))) { do { guild->addRank(result->getNumber("id"), result->getString("name"), @@ -77,10 +76,8 @@ Guild_ptr IOGuild::loadGuild(uint32_t guildId) uint32_t IOGuild::getGuildIdByName(const std::string& name) { - Database& db = Database::getInstance(); - - DBResult_ptr result = - db.storeQuery(fmt::format("SELECT `id` FROM `guilds` WHERE `name` = {:s}", db.escapeString(name))); + auto result = tfs::db::store_query( + fmt::format("SELECT `id` FROM `guilds` WHERE `name` = {:s}", tfs::db::escape_string(name))); if (!result) { return 0; } diff --git a/src/house.cpp b/src/house.cpp index 46d203d019..77c3a41361 100644 --- a/src/house.cpp +++ b/src/house.cpp @@ -26,8 +26,7 @@ void House::addTile(HouseTile* tile) void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, Player* player /* = nullptr*/) { if (updateDatabase && owner != guid) { - Database& db = Database::getInstance(); - db.executeQuery(fmt::format( + tfs::db::execute_query(fmt::format( "UPDATE `houses` SET `owner` = {:d}, `bid` = 0, `bid_end` = 0, `last_bid` = 0, `highest_bidder` = 0 WHERE `id` = {:d}", guid, id)); } diff --git a/src/http/cacheinfo.cpp b/src/http/cacheinfo.cpp index 3e7b8f3214..ace262475f 100644 --- a/src/http/cacheinfo.cpp +++ b/src/http/cacheinfo.cpp @@ -11,11 +11,9 @@ using boost::beast::http::status; std::pair tfs::http::handle_cacheinfo(const json::object&, std::string_view) { - thread_local auto& db = Database::getInstance(); - auto result = db.storeQuery("SELECT COUNT(*) AS `count` FROM `players_online`"); + auto result = tfs::db::store_query("SELECT COUNT(*) AS `count` FROM `players_online`"); if (!result) { return make_error_response(); } - return {status::ok, {{"playersonline", result->getNumber("count")}}}; } diff --git a/src/http/login.cpp b/src/http/login.cpp index bd22458930..de82d1856d 100644 --- a/src/http/login.cpp +++ b/src/http/login.cpp @@ -49,10 +49,9 @@ std::pair tfs::http::handle_login(const json::object& body, {.code = 3, .message = "Tibia account email address or Tibia password is not correct."}); } - thread_local auto& db = Database::getInstance(); - auto result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `id`, UNHEX(`password`) AS `password`, `secret`, `premium_ends_at` FROM `accounts` WHERE `email` = {:s}", - db.escapeString(emailField->get_string()))); + tfs::db::escape_string(emailField->get_string()))); if (!result) { return make_error_response( {.code = 3, .message = "Tibia account email address or Tibia password is not correct."}); @@ -85,19 +84,18 @@ std::pair tfs::http::handle_login(const json::object& body, auto premiumEndsAt = result->getNumber("premium_ends_at"); std::string sessionKey = randomBytes(16); - if (!db.executeQuery( + if (!tfs::db::execute_query( fmt::format("INSERT INTO `sessions` (`token`, `account_id`, `ip`) VALUES ({:s}, {:d}, INET6_ATON({:s}))", - db.escapeString(sessionKey), accountId, db.escapeString(ip)))) { + tfs::db::escape_string(sessionKey), accountId, tfs::db::escape_string(ip)))) { return make_error_response(); } - result = db.storeQuery(fmt::format( - "SELECT `id`, `name`, `level`, `vocation`, `lastlogin`, `sex`, `looktype`, `lookhead`, `lookbody`, `looklegs`, `lookfeet`, `lookaddons` FROM `players` WHERE `account_id` = {:d}", - accountId)); - json::array characters; uint32_t lastLogin = 0; - if (result) { + + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `id`, `name`, `level`, `vocation`, `lastlogin`, `sex`, `looktype`, `lookhead`, `lookbody`, `looklegs`, `lookfeet`, `lookaddons` FROM `players` WHERE `account_id` = {:d}", + accountId))) { do { auto vocation = g_vocations.getVocation(result->getNumber("vocation")); assert(vocation); diff --git a/src/http/tests/test_login.cpp b/src/http/tests/test_login.cpp index b35c00e8d1..6eb260f14c 100644 --- a/src/http/tests/test_login.cpp +++ b/src/http/tests/test_login.cpp @@ -129,7 +129,7 @@ struct LoginFixture auto is = vocationsXml(); g_vocations.loadFromXml(is, ":memory:"); - db.connect(); + tfs::db::connect(); transaction.begin(); } @@ -137,10 +137,9 @@ struct LoginFixture { // `players_online` is a memory table and does not support transactions, so we need to clear it manually // do NOT run this test against a running server's database - db.executeQuery("TRUNCATE `players_online`"); + tfs::db::execute_query("TRUNCATE `players_online`"); } - Database& db = Database::getInstance(); DBTransaction transaction; std::string_view ip = "74.125.224.72"; @@ -176,7 +175,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_missing_password, LoginFixture) BOOST_FIXTURE_TEST_CASE(test_login_invalid_password, LoginFixture) { - BOOST_TEST(db.executeQuery( + BOOST_TEST(tfs::db::execute_query( "INSERT INTO `accounts` (`name`, `email`, `password`) VALUES ('abc', 'foo@example.com', SHA1('bar'))")); auto&& [status, body] = @@ -188,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_invalid_password, LoginFixture) BOOST_FIXTURE_TEST_CASE(test_login_missing_token, LoginFixture) { - BOOST_TEST(db.executeQuery( + BOOST_TEST(tfs::db::execute_query( "INSERT INTO `accounts` (`name`, `email`, `password`, `secret`) VALUES ('abcd', 'fooba@example.com', SHA1('bar'), UNHEX('48656c6c6f21dead'))")); auto now = duration_cast(system_clock::now().time_since_epoch()); @@ -207,7 +206,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_missing_token, LoginFixture) BOOST_FIXTURE_TEST_CASE(test_login_success_no_players, LoginFixture) { - BOOST_TEST(db.executeQuery( + BOOST_TEST(tfs::db::execute_query( "INSERT INTO `accounts` (`name`, `email`, `password`) VALUES ('defg', 'foobar@example.com', SHA1('bar'))")); auto&& [status, body] = @@ -222,15 +221,15 @@ BOOST_FIXTURE_TEST_CASE(test_login_success, LoginFixture) { auto premiumEndsAt = now + days(30); - auto result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "INSERT INTO `accounts` (`name`, `email`, `password`, `premium_ends_at`) VALUES ('ghij', 'ghij@example.com', SHA1('bar'), {:d}) RETURNING `id`", premiumEndsAt.count())); auto id = result->getNumber("id"); DBInsert insert( "INSERT INTO `players` (`account_id`, `name`, `level`, `vocation`, `lastlogin`, `sex`, `looktype`, `lookhead`, `lookbody`, `looklegs`, `lookfeet`, `lookaddons`) VALUES"); - insert.addRow(fmt::format("{:d}, \"{:s}\", {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}", id, - "Test", 2597, 6, 1715719401, 1, 1094, 78, 132, 114, 0, 1)); + insert.addRow(fmt::format("{:d}, \"{:s}\", {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d}", id, "Test", + 2597, 6, 1715719401, 1, 1094, 78, 132, 114, 0, 1)); BOOST_TEST(insert.execute()); auto&& [status, body] = @@ -243,7 +242,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_success, LoginFixture) BOOST_TEST(session.at("ispremium").as_bool() == true); BOOST_TEST(session.at("premiumuntil").as_int64() == premiumEndsAt.count()); - result = db.storeQuery( + result = tfs::db::store_query( fmt::format("SELECT `token`, INET6_NTOA(`ip`) AS `ip` FROM `sessions` WHERE `account_id` = {:d}", id)); BOOST_TEST(result, "Session not found in database."); BOOST_TEST(result->getString("token") == tfs::base64::decode(session.at("sessionkey").as_string())); @@ -277,7 +276,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_success, LoginFixture) BOOST_FIXTURE_TEST_CASE(test_login_success_with_token, LoginFixture) { - auto result = db.storeQuery( + auto result = tfs::db::store_query( "INSERT INTO `accounts` (`name`, `email`, `password`, `secret`) VALUES ('nbdj', 'nbdj@example.com', SHA1('bar'), UNHEX('')) RETURNING `id`"); auto id = result->getNumber("id"); diff --git a/src/iologindata.cpp b/src/iologindata.cpp index 5d90e837b6..ef913809cc 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -16,10 +16,8 @@ extern Game g_game; uint32_t IOLoginData::getAccountIdByPlayerName(const std::string& playerName) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery( - fmt::format("SELECT `account_id` FROM `players` WHERE `name` = {:s}", db.escapeString(playerName))); + auto result = tfs::db::store_query( + fmt::format("SELECT `account_id` FROM `players` WHERE `name` = {:s}", tfs::db::escape_string(playerName))); if (!result) { return 0; } @@ -28,9 +26,7 @@ uint32_t IOLoginData::getAccountIdByPlayerName(const std::string& playerName) uint32_t IOLoginData::getAccountIdByPlayerId(uint32_t playerId) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format("SELECT `account_id` FROM `players` WHERE `id` = {:d}", playerId)); + auto result = tfs::db::store_query(fmt::format("SELECT `account_id` FROM `players` WHERE `id` = {:d}", playerId)); if (!result) { return 0; } @@ -39,8 +35,7 @@ uint32_t IOLoginData::getAccountIdByPlayerId(uint32_t playerId) AccountType_t IOLoginData::getAccountType(uint32_t accountId) { - DBResult_ptr result = - Database::getInstance().storeQuery(fmt::format("SELECT `type` FROM `accounts` WHERE `id` = {:d}", accountId)); + auto result = tfs::db::store_query(fmt::format("SELECT `type` FROM `accounts` WHERE `id` = {:d}", accountId)); if (!result) { return ACCOUNT_TYPE_NORMAL; } @@ -49,8 +44,8 @@ AccountType_t IOLoginData::getAccountType(uint32_t accountId) void IOLoginData::setAccountType(uint32_t accountId, AccountType_t accountType) { - Database::getInstance().executeQuery(fmt::format("UPDATE `accounts` SET `type` = {:d} WHERE `id` = {:d}", - static_cast(accountType), accountId)); + tfs::db::execute_query(fmt::format("UPDATE `accounts` SET `type` = {:d} WHERE `id` = {:d}", + static_cast(accountType), accountId)); } void IOLoginData::updateOnlineStatus(uint32_t guid, bool login) @@ -60,18 +55,15 @@ void IOLoginData::updateOnlineStatus(uint32_t guid, bool login) } if (login) { - Database::getInstance().executeQuery(fmt::format("INSERT INTO `players_online` VALUES ({:d})", guid)); + tfs::db::execute_query(fmt::format("INSERT INTO `players_online` VALUES ({:d})", guid)); } else { - Database::getInstance().executeQuery( - fmt::format("DELETE FROM `players_online` WHERE `player_id` = {:d}", guid)); + tfs::db::execute_query(fmt::format("DELETE FROM `players_online` WHERE `player_id` = {:d}", guid)); } } bool IOLoginData::preloadPlayer(Player* player) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `p`.`name`, `p`.`account_id`, `p`.`group_id`, `a`.`type`, `a`.`premium_ends_at` FROM `players` AS `p` JOIN `accounts` AS `a` ON `a`.`id` = `p`.`account_id` WHERE `p`.`id` = {:d} AND `p`.`deletion` = 0", player->getGUID())); if (!result) { @@ -94,27 +86,25 @@ bool IOLoginData::preloadPlayer(Player* player) bool IOLoginData::loadPlayerById(Player* player, uint32_t id) { - Database& db = Database::getInstance(); return loadPlayer( player, - db.storeQuery(fmt::format( + tfs::db::store_query(fmt::format( "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `lookmount`, `lookmounthead`, `lookmountbody`, `lookmountlegs`, `lookmountfeet`, `currentmount`, `randomizemount`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries`, `direction` FROM `players` WHERE `id` = {:d}", id))); } bool IOLoginData::loadPlayerByName(Player* player, const std::string& name) { - Database& db = Database::getInstance(); return loadPlayer( player, - db.storeQuery(fmt::format( + tfs::db::store_query(fmt::format( "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `lookmount`, `lookmounthead`, `lookmountbody`, `lookmountlegs`, `lookmountfeet`, `currentmount`, `randomizemount`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries`, `direction` FROM `players` WHERE `name` = {:s}", - db.escapeString(name)))); + tfs::db::escape_string(name)))); } static GuildWarVector getWarList(uint32_t guildId) { - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = {:d} OR `guild2` = {:d}) AND `ended` = 0 AND `status` = 1", guildId, guildId)); if (!result) { @@ -139,12 +129,10 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) return false; } - Database& db = Database::getInstance(); - uint32_t accountId = result->getNumber("account_id"); - auto account = - db.storeQuery(fmt::format("SELECT `type`, `premium_ends_at` FROM `accounts` WHERE `id` = {:d}", accountId)); + auto account = tfs::db::store_query( + fmt::format("SELECT `type`, `premium_ends_at` FROM `accounts` WHERE `id` = {:d}", accountId)); if (!account) { return false; } @@ -302,7 +290,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->skills[i].percent = Player::getBasisPointLevel(skillTries, nextSkillTries); } - if ((result = db.storeQuery( + if ((result = tfs::db::store_query( fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", player->getGUID())))) { uint32_t guildId = result->getNumber("guild_id"); @@ -324,7 +312,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guild = guild; auto rank = guild->getRankById(playerRankId); if (!rank) { - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId)))) { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); @@ -339,15 +327,15 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guildRank = rank; player->guildWarVector = getWarList(guildId); - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId)))) { guild->setMemberCount(result->getNumber("members")); } } } - if ((result = db.storeQuery(fmt::format("SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", - player->getGUID())))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->learnedInstantSpellList.emplace_front(result->getString("name")); } while (result->next()); @@ -357,7 +345,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) ItemMap itemMap; std::map openContainersList; - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", player->getGUID())))) { loadItems(itemMap, result); @@ -399,7 +387,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load depot items itemMap.clear(); - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", player->getGUID())))) { loadItems(itemMap, result); @@ -431,7 +419,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load inbox items itemMap.clear(); - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", player->getGUID())))) { loadItems(itemMap, result); @@ -461,7 +449,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load store inbox items itemMap.clear(); - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", player->getGUID())))) { loadItems(itemMap, result); @@ -489,7 +477,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } // load storage map - if ((result = db.storeQuery( + if ((result = tfs::db::store_query( fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->setStorageValue(result->getNumber("key"), result->getNumber("value"), true); @@ -497,15 +485,15 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } // load vip list - if ((result = db.storeQuery(fmt::format("SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", - player->getAccount())))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount())))) { do { player->addVIPInternal(result->getNumber("player_id")); } while (result->next()); } // load outfits & addons - if ((result = db.storeQuery(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->addOutfit(result->getNumber("outfit_id"), result->getNumber("addons")); @@ -513,7 +501,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } // load mounts - if ((result = db.storeQuery( + if ((result = tfs::db::store_query( fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->tameMount(result->getNumber("mount_id")); @@ -536,7 +524,6 @@ bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, int32_t runningId = 100; const auto& openContainers = player->getOpenContainers(); - Database& db = Database::getInstance(); for (const auto& it : itemList) { int32_t pid = it.first; Item* item = it.second; @@ -567,7 +554,7 @@ bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, if (!query_insert.addRow(fmt::format("{:d}, {:d}, {:d}, {:d}, {:d}, {:s}", player->getGUID(), pid, runningId, item->getID(), item->getSubType(), - db.escapeString(propWriteStream.getStream())))) { + tfs::db::escape_string(propWriteStream.getStream())))) { return false; } } @@ -606,7 +593,7 @@ bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, if (!query_insert.addRow(fmt::format("{:d}, {:d}, {:d}, {:d}, {:d}, {:s}", player->getGUID(), parentId, runningId, item->getID(), item->getSubType(), - db.escapeString(propWriteStream.getStream())))) { + tfs::db::escape_string(propWriteStream.getStream())))) { return false; } } @@ -620,16 +607,14 @@ bool IOLoginData::savePlayer(Player* player) player->changeHealth(1); } - Database& db = Database::getInstance(); - - DBResult_ptr result = - db.storeQuery(fmt::format("SELECT `save` FROM `players` WHERE `id` = {:d}", player->getGUID())); + auto result = + tfs::db::store_query(fmt::format("SELECT `save` FROM `players` WHERE `id` = {:d}", player->getGUID())); if (!result) { return false; } if (result->getNumber("save") == 0) { - return db.executeQuery( + return tfs::db::execute_query( fmt::format("UPDATE `players` SET `lastlogin` = {:d}, `lastip` = INET6_ATON('{:s}') WHERE `id` = {:d}", player->lastLoginSaved, player->lastIP.to_string(), player->getGUID())); } @@ -688,7 +673,7 @@ bool IOLoginData::savePlayer(Player* player) query << "`lastip` = INET6_ATON('" << player->lastIP.to_string() << "'),"; } - query << "`conditions` = " << db.escapeString(propWriteStream.getStream()) << ','; + query << "`conditions` = " << tfs::db::escape_string(propWriteStream.getStream()) << ','; if (g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) { int64_t skullTime = 0; @@ -740,18 +725,19 @@ bool IOLoginData::savePlayer(Player* player) return false; } - if (!db.executeQuery(query.str())) { + if (!tfs::db::execute_query(query.str())) { return false; } // learned spells - if (!db.executeQuery(fmt::format("DELETE FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } DBInsert spellsQuery("INSERT INTO `player_spells` (`player_id`, `name`) VALUES "); for (const std::string& spellName : player->learnedInstantSpellList) { - if (!spellsQuery.addRow(fmt::format("{:d}, {:s}", player->getGUID(), db.escapeString(spellName)))) { + if (!spellsQuery.addRow(fmt::format("{:d}, {:s}", player->getGUID(), tfs::db::escape_string(spellName)))) { return false; } } @@ -761,7 +747,8 @@ bool IOLoginData::savePlayer(Player* player) } // item saving - if (!db.executeQuery(fmt::format("DELETE FROM `player_items` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_items` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -781,7 +768,8 @@ bool IOLoginData::savePlayer(Player* player) } // save depot items - if (!db.executeQuery(fmt::format("DELETE FROM `player_depotitems` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_depotitems` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -800,7 +788,8 @@ bool IOLoginData::savePlayer(Player* player) } // save inbox items - if (!db.executeQuery(fmt::format("DELETE FROM `player_inboxitems` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_inboxitems` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -817,7 +806,7 @@ bool IOLoginData::savePlayer(Player* player) } // save store inbox items - if (!db.executeQuery( + if (!tfs::db::execute_query( fmt::format("DELETE FROM `player_storeinboxitems` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -834,7 +823,8 @@ bool IOLoginData::savePlayer(Player* player) return false; } - if (!db.executeQuery(fmt::format("DELETE FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -851,7 +841,8 @@ bool IOLoginData::savePlayer(Player* player) } // save outfits & addons - if (!db.executeQuery(fmt::format("DELETE FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -868,7 +859,8 @@ bool IOLoginData::savePlayer(Player* player) } // save mounts - if (!db.executeQuery(fmt::format("DELETE FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID()))) { + if (!tfs::db::execute_query( + fmt::format("DELETE FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID()))) { return false; } @@ -890,8 +882,7 @@ bool IOLoginData::savePlayer(Player* player) std::string IOLoginData::getNameByGuid(uint32_t guid) { - DBResult_ptr result = - Database::getInstance().storeQuery(fmt::format("SELECT `name` FROM `players` WHERE `id` = {:d}", guid)); + auto result = tfs::db::store_query(fmt::format("SELECT `name` FROM `players` WHERE `id` = {:d}", guid)); if (!result) { return {}; } @@ -902,10 +893,8 @@ std::string IOLoginData::getNameByGuid(uint32_t guid) uint32_t IOLoginData::getGuidByName(const std::string& name) { - Database& db = Database::getInstance(); - - DBResult_ptr result = - db.storeQuery(fmt::format("SELECT `id` FROM `players` WHERE `name` = {:s}", db.escapeString(name))); + auto result = tfs::db::store_query( + fmt::format("SELECT `id` FROM `players` WHERE `name` = {:s}", tfs::db::escape_string(name))); if (!result) { return 0; } @@ -914,10 +903,9 @@ uint32_t IOLoginData::getGuidByName(const std::string& name) bool IOLoginData::getGuidByNameEx(uint32_t& guid, bool& specialVip, std::string& name) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( - "SELECT `name`, `id`, `group_id`, `account_id` FROM `players` WHERE `name` = {:s}", db.escapeString(name))); + auto result = tfs::db::store_query( + fmt::format("SELECT `name`, `id`, `group_id`, `account_id` FROM `players` WHERE `name` = {:s}", + tfs::db::escape_string(name))); if (!result) { return false; } @@ -926,23 +914,15 @@ bool IOLoginData::getGuidByNameEx(uint32_t& guid, bool& specialVip, std::string& guid = result->getNumber("id"); Group* group = g_game.groups.getGroup(result->getNumber("group_id")); - uint64_t flags; - if (group) { - flags = group->flags; - } else { - flags = 0; - } - + auto flags = group ? group->flags : 0; specialVip = (flags & PlayerFlag_SpecialVIP) != 0; return true; } bool IOLoginData::formatPlayerName(std::string& name) { - Database& db = Database::getInstance(); - - DBResult_ptr result = - db.storeQuery(fmt::format("SELECT `name` FROM `players` WHERE `name` = {:s}", db.escapeString(name))); + auto result = tfs::db::store_query( + fmt::format("SELECT `name` FROM `players` WHERE `name` = {:s}", tfs::db::escape_string(name))); if (!result) { return false; } @@ -954,17 +934,16 @@ bool IOLoginData::formatPlayerName(std::string& name) void IOLoginData::loadItems(ItemMap& itemMap, DBResult_ptr result) { do { - uint32_t sid = result->getNumber("sid"); - uint32_t pid = result->getNumber("pid"); - uint16_t type = result->getNumber("itemtype"); - uint16_t count = result->getNumber("count"); - + auto sid = result->getNumber("sid"); + auto pid = result->getNumber("pid"); + auto type = result->getNumber("itemtype"); + auto count = result->getNumber("count"); auto attr = result->getString("attributes"); + PropStream propStream; propStream.init(attr.data(), attr.size()); - Item* item = Item::CreateItem(type, count); - if (item) { + if (auto item = Item::CreateItem(type, count)) { if (!item->unserializeAttr(propStream)) { std::cout << "WARNING: Serialize error in IOLoginData::loadItems" << std::endl; } @@ -977,23 +956,24 @@ void IOLoginData::loadItems(ItemMap& itemMap, DBResult_ptr result) void IOLoginData::increaseBankBalance(uint32_t guid, uint64_t bankBalance) { - Database::getInstance().executeQuery( + tfs::db::execute_query( fmt::format("UPDATE `players` SET `balance` = `balance` + {:d} WHERE `id` = {:d}", bankBalance, guid)); } bool IOLoginData::hasBiddedOnHouse(uint32_t guid) { - Database& db = Database::getInstance(); - return db.storeQuery(fmt::format("SELECT `id` FROM `houses` WHERE `highest_bidder` = {:d} LIMIT 1", guid)).get(); + return tfs::db::store_query(fmt::format("SELECT `id` FROM `houses` WHERE `highest_bidder` = {:d} LIMIT 1", guid)) + .get(); } std::forward_list IOLoginData::getVIPEntries(uint32_t accountId) { std::forward_list entries; - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `player_id`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `name`, `description`, `icon`, `notify` FROM `account_viplist` WHERE `account_id` = {:d}", accountId)); + if (result) { do { entries.emplace_front(result->getNumber("player_id"), result->getString("name"), @@ -1007,29 +987,27 @@ std::forward_list IOLoginData::getVIPEntries(uint32_t accountId) void IOLoginData::addVIPEntry(uint32_t accountId, uint32_t guid, const std::string& description, uint32_t icon, bool notify) { - Database& db = Database::getInstance(); - db.executeQuery(fmt::format( + tfs::db::execute_query(fmt::format( "INSERT INTO `account_viplist` (`account_id`, `player_id`, `description`, `icon`, `notify`) VALUES ({:d}, {:d}, {:s}, {:d}, {:d})", - accountId, guid, db.escapeString(description), icon, notify)); + accountId, guid, tfs::db::escape_string(description), icon, notify)); } void IOLoginData::editVIPEntry(uint32_t accountId, uint32_t guid, const std::string& description, uint32_t icon, bool notify) { - Database& db = Database::getInstance(); - db.executeQuery(fmt::format( + tfs::db::execute_query(fmt::format( "UPDATE `account_viplist` SET `description` = {:s}, `icon` = {:d}, `notify` = {:d} WHERE `account_id` = {:d} AND `player_id` = {:d}", - db.escapeString(description), icon, notify, accountId, guid)); + tfs::db::escape_string(description), icon, notify, accountId, guid)); } void IOLoginData::removeVIPEntry(uint32_t accountId, uint32_t guid) { - Database::getInstance().executeQuery( + tfs::db::execute_query( fmt::format("DELETE FROM `account_viplist` WHERE `account_id` = {:d} AND `player_id` = {:d}", accountId, guid)); } void IOLoginData::updatePremiumTime(uint32_t accountId, time_t endTime) { - Database::getInstance().executeQuery( + tfs::db::execute_query( fmt::format("UPDATE `accounts` SET `premium_ends_at` = {:d} WHERE `id` = {:d}", endTime, accountId)); } diff --git a/src/iomapserialize.cpp b/src/iomapserialize.cpp index df7c752961..61adf337fe 100644 --- a/src/iomapserialize.cpp +++ b/src/iomapserialize.cpp @@ -15,7 +15,7 @@ void IOMapSerialize::loadHouseItems(Map* map) { int64_t start = OTSYS_TIME(); - DBResult_ptr result = Database::getInstance().storeQuery("SELECT `data` FROM `tile_store`"); + auto result = tfs::db::store_query("SELECT `data` FROM `tile_store`"); if (!result) { return; } @@ -51,7 +51,6 @@ void IOMapSerialize::loadHouseItems(Map* map) bool IOMapSerialize::saveHouseItems() { int64_t start = OTSYS_TIME(); - Database& db = Database::getInstance(); // Start the transaction DBTransaction transaction; @@ -60,7 +59,7 @@ bool IOMapSerialize::saveHouseItems() } // clear old tile data - if (!db.executeQuery("DELETE FROM `tile_store`")) { + if (!tfs::db::execute_query("DELETE FROM `tile_store`")) { return false; } @@ -74,7 +73,7 @@ bool IOMapSerialize::saveHouseItems() saveTile(stream, tile); if (auto attributes = stream.getStream(); !attributes.empty()) { - if (!stmt.addRow(fmt::format("{:d}, {:s}", house->getId(), db.escapeString(attributes)))) { + if (!stmt.addRow(fmt::format("{:d}, {:s}", house->getId(), tfs::db::escape_string(attributes)))) { return false; } stream.clear(); @@ -252,27 +251,22 @@ void IOMapSerialize::saveTile(PropWriteStream& stream, const Tile* tile) bool IOMapSerialize::loadHouseInfo() { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`"); + auto result = tfs::db::store_query("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`"); if (!result) { return false; } do { - House* house = g_game.map.houses.getHouse(result->getNumber("id")); - if (house) { + if (auto house = g_game.map.houses.getHouse(result->getNumber("id"))) { house->setOwner(result->getNumber("owner"), false); house->setPaidUntil(result->getNumber("paid")); house->setPayRentWarnings(result->getNumber("warnings")); } } while (result->next()); - result = db.storeQuery("SELECT `house_id`, `listid`, `list` FROM `house_lists`"); - if (result) { + if (auto result = tfs::db::store_query("SELECT `house_id`, `listid`, `list` FROM `house_lists`")) { do { - House* house = g_game.map.houses.getHouse(result->getNumber("house_id")); - if (house) { + if (auto house = g_game.map.houses.getHouse(result->getNumber("house_id"))) { house->setAccessList(result->getNumber("listid"), result->getString("list")); } } while (result->next()); @@ -282,32 +276,30 @@ bool IOMapSerialize::loadHouseInfo() bool IOMapSerialize::saveHouseInfo() { - Database& db = Database::getInstance(); - DBTransaction transaction; if (!transaction.begin()) { return false; } - if (!db.executeQuery("DELETE FROM `house_lists`")) { + if (!tfs::db::execute_query("DELETE FROM `house_lists`")) { return false; } for (const auto& it : g_game.map.houses.getHouses()) { House* house = it.second; - DBResult_ptr result = db.storeQuery(fmt::format("SELECT `id` FROM `houses` WHERE `id` = {:d}", house->getId())); - if (result) { - db.executeQuery(fmt::format( + if (auto result = + tfs::db::store_query(fmt::format("SELECT `id` FROM `houses` WHERE `id` = {:d}", house->getId()))) { + tfs::db::execute_query(fmt::format( "UPDATE `houses` SET `owner` = {:d}, `paid` = {:d}, `warnings` = {:d}, `name` = {:s}, `town_id` = {:d}, `rent` = {:d}, `size` = {:d}, `beds` = {:d} WHERE `id` = {:d}", house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), - db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getTiles().size(), - house->getBedCount(), house->getId())); + tfs::db::escape_string(house->getName()), house->getTownId(), house->getRent(), + house->getTiles().size(), house->getBedCount(), house->getId())); } else { - db.executeQuery(fmt::format( + tfs::db::execute_query(fmt::format( "INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES ({:d}, {:d}, {:d}, {:d}, {:s}, {:d}, {:d}, {:d}, {:d})", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), - db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getTiles().size(), - house->getBedCount())); + tfs::db::escape_string(house->getName()), house->getTownId(), house->getRent(), + house->getTiles().size(), house->getBedCount())); } } @@ -319,7 +311,7 @@ bool IOMapSerialize::saveHouseInfo() std::string listText; if (house->getAccessList(GUEST_LIST, listText) && !listText.empty()) { if (!stmt.addRow(fmt::format("{:d}, {:d}, {:s}", house->getId(), tfs::to_underlying(GUEST_LIST), - db.escapeString(listText)))) { + tfs::db::escape_string(listText)))) { return false; } @@ -328,17 +320,17 @@ bool IOMapSerialize::saveHouseInfo() if (house->getAccessList(SUBOWNER_LIST, listText) && !listText.empty()) { if (!stmt.addRow(fmt::format("{:d}, {:d}, {:s}", house->getId(), tfs::to_underlying(SUBOWNER_LIST), - db.escapeString(listText)))) { + tfs::db::escape_string(listText)))) { return false; } listText.clear(); } - for (Door* door : house->getDoors()) { + for (auto door : house->getDoors()) { if (door->getAccessList(listText) && !listText.empty()) { if (!stmt.addRow(fmt::format("{:d}, {:d}, {:s}", house->getId(), door->getDoorId(), - db.escapeString(listText)))) { + tfs::db::escape_string(listText)))) { return false; } @@ -356,8 +348,6 @@ bool IOMapSerialize::saveHouseInfo() bool IOMapSerialize::saveHouse(House* house) { - Database& db = Database::getInstance(); - // Start the transaction DBTransaction transaction; if (!transaction.begin()) { @@ -367,7 +357,7 @@ bool IOMapSerialize::saveHouse(House* house) uint32_t houseId = house->getId(); // clear old tile data - if (!db.executeQuery(fmt::format("DELETE FROM `tile_store` WHERE `house_id` = {:d}", houseId))) { + if (!tfs::db::execute_query(fmt::format("DELETE FROM `tile_store` WHERE `house_id` = {:d}", houseId))) { return false; } @@ -378,7 +368,7 @@ bool IOMapSerialize::saveHouse(House* house) saveTile(stream, tile); if (auto attributes = stream.getStream(); attributes.size() > 0) { - if (!stmt.addRow(fmt::format("{:d}, {:s}", houseId, db.escapeString(attributes)))) { + if (!stmt.addRow(fmt::format("{:d}, {:s}", houseId, tfs::db::escape_string(attributes)))) { return false; } stream.clear(); diff --git a/src/iomarket.cpp b/src/iomarket.cpp index 79cb5fb5f0..5d54004cbc 100644 --- a/src/iomarket.cpp +++ b/src/iomarket.cpp @@ -18,14 +18,14 @@ MarketOfferList IOMarket::getActiveOffers(MarketAction_t action, uint16_t itemId { MarketOfferList offerList; - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `id`, `amount`, `price`, `created`, `anonymous`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `player_name` FROM `market_offers` WHERE `sale` = {:d} AND `itemtype` = {:d}", tfs::to_underlying(action), itemId)); if (!result) { return offerList; } - const int32_t marketOfferDuration = getNumber(ConfigManager::MARKET_OFFER_DURATION); + const auto marketOfferDuration = getNumber(ConfigManager::MARKET_OFFER_DURATION); do { MarketOffer offer; @@ -50,7 +50,7 @@ MarketOfferList IOMarket::getOwnOffers(MarketAction_t action, uint32_t playerId) const int32_t marketOfferDuration = getNumber(ConfigManager::MARKET_OFFER_DURATION); - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `id`, `amount`, `price`, `created`, `itemtype` FROM `market_offers` WHERE `player_id` = {:d} AND `sale` = {:d}", playerId, tfs::to_underlying(action))); if (!result) { @@ -73,7 +73,7 @@ HistoryMarketOfferList IOMarket::getOwnHistory(MarketAction_t action, uint32_t p { HistoryMarketOfferList offerList; - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `itemtype`, `amount`, `price`, `expires_at`, `state` FROM `market_history` WHERE `player_id` = {:d} AND `sale` = {:d}", playerId, tfs::to_underlying(action))); if (!result) { @@ -196,8 +196,8 @@ void IOMarket::checkExpiredOffers() uint32_t IOMarket::getPlayerOfferCount(uint32_t playerId) { - DBResult_ptr result = Database::getInstance().storeQuery( - fmt::format("SELECT COUNT(*) AS `count` FROM `market_offers` WHERE `player_id` = {:d}", playerId)); + auto result = tfs::db::store_query( + fmt::format("SELECT COUNT(*) AS `count` FROM `market_offers` WHERE `player_id` = {:d}", playerId)); if (!result) { return 0; } @@ -210,7 +210,7 @@ MarketOfferEx IOMarket::getOfferByCounter(uint32_t timestamp, uint16_t counter) const int32_t created = timestamp - getNumber(ConfigManager::MARKET_OFFER_DURATION); - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `id`, `sale`, `itemtype`, `amount`, `created`, `price`, `player_id`, `anonymous`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `player_name` FROM `market_offers` WHERE `created` = {:d} AND (`id` & 65535) = {:d} LIMIT 1", created, counter)); if (!result) { @@ -238,20 +238,20 @@ MarketOfferEx IOMarket::getOfferByCounter(uint32_t timestamp, uint16_t counter) void IOMarket::createOffer(uint32_t playerId, MarketAction_t action, uint32_t itemId, uint16_t amount, uint64_t price, bool anonymous) { - Database::getInstance().executeQuery(fmt::format( + tfs::db::execute_query(fmt::format( "INSERT INTO `market_offers` (`player_id`, `sale`, `itemtype`, `amount`, `price`, `created`, `anonymous`) VALUES ({:d}, {:d}, {:d}, {:d}, {:d}, {:d}, {:d})", playerId, tfs::to_underlying(action), itemId, amount, price, time(nullptr), anonymous)); } void IOMarket::acceptOffer(uint32_t offerId, uint16_t amount) { - Database::getInstance().executeQuery( + tfs::db::execute_query( fmt::format("UPDATE `market_offers` SET `amount` = `amount` - {:d} WHERE `id` = {:d}", amount, offerId)); } void IOMarket::deleteOffer(uint32_t offerId) { - Database::getInstance().executeQuery(fmt::format("DELETE FROM `market_offers` WHERE `id` = {:d}", offerId)); + tfs::db::execute_query(fmt::format("DELETE FROM `market_offers` WHERE `id` = {:d}", offerId)); } void IOMarket::appendHistory(uint32_t playerId, MarketAction_t action, uint16_t itemId, uint16_t amount, uint64_t price, @@ -267,16 +267,14 @@ bool IOMarket::moveOfferToHistory(uint32_t offerId, MarketOfferState_t state) { const int32_t marketOfferDuration = getNumber(ConfigManager::MARKET_OFFER_DURATION); - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `player_id`, `sale`, `itemtype`, `amount`, `price`, `created` FROM `market_offers` WHERE `id` = {:d}", offerId)); if (!result) { return false; } - if (!db.executeQuery(fmt::format("DELETE FROM `market_offers` WHERE `id` = {:d}", offerId))) { + if (!tfs::db::execute_query(fmt::format("DELETE FROM `market_offers` WHERE `id` = {:d}", offerId))) { return false; } @@ -289,7 +287,7 @@ bool IOMarket::moveOfferToHistory(uint32_t offerId, MarketOfferState_t state) void IOMarket::updateStatistics() { - DBResult_ptr result = Database::getInstance().storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `sale` AS `sale`, `itemtype` AS `itemtype`, COUNT(`price`) AS `num`, MIN(`price`) AS `min`, MAX(`price`) AS `max`, SUM(`price`) AS `sum` FROM `market_history` WHERE `state` = {:d} GROUP BY `itemtype`, `sale`", tfs::to_underlying(OFFERSTATE_ACCEPTED))); if (!result) { diff --git a/src/luascript.cpp b/src/luascript.cpp index e7a5e88ef1..9b5cae785a 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -411,9 +411,9 @@ void tfs::lua::removeTempItem(Item* item) std::erase_if(tempItems, [item](const auto& pair) { return pair.second == item; }); } -static uint32_t addResult(DBResult_ptr res) +static uint32_t addResult(DBResult_ptr result) { - tempResults[++lastResultId] = std::move(res); + tempResults[++lastResultId] = std::move(result); return lastResultId; } @@ -4257,7 +4257,7 @@ const luaL_Reg LuaScriptInterface::luaDatabaseTable[] = { int LuaScriptInterface::luaDatabaseExecute(lua_State* L) { // db.query(query) - tfs::lua::pushBoolean(L, Database::getInstance().executeQuery(tfs::lua::getString(L, -1))); + tfs::lua::pushBoolean(L, tfs::db::execute_query(tfs::lua::getString(L, -1))); return 1; } @@ -4295,8 +4295,8 @@ int LuaScriptInterface::luaDatabaseAsyncExecute(lua_State* L) int LuaScriptInterface::luaDatabaseStoreQuery(lua_State* L) { // db.storeQuery(query) - if (DBResult_ptr res = Database::getInstance().storeQuery(tfs::lua::getString(L, -1))) { - lua_pushnumber(L, addResult(res)); + if (auto result = tfs::db::store_query(tfs::lua::getString(L, -1))) { + lua_pushnumber(L, addResult(result)); } else { tfs::lua::pushBoolean(L, false); } @@ -4341,7 +4341,7 @@ int LuaScriptInterface::luaDatabaseAsyncStoreQuery(lua_State* L) int LuaScriptInterface::luaDatabaseEscapeString(lua_State* L) { // db.escapeString(s) - tfs::lua::pushString(L, Database::getInstance().escapeString(tfs::lua::getString(L, -1))); + tfs::lua::pushString(L, tfs::db::escape_string(tfs::lua::getString(L, -1))); return 1; } @@ -4349,14 +4349,14 @@ int LuaScriptInterface::luaDatabaseEscapeBlob(lua_State* L) { // db.escapeBlob(s, length) uint32_t length = tfs::lua::getNumber(L, 2); - tfs::lua::pushString(L, Database::getInstance().escapeBlob(tfs::lua::getString(L, 1).data(), length)); + tfs::lua::pushString(L, tfs::db::escape_blob(tfs::lua::getString(L, 1).data(), length)); return 1; } int LuaScriptInterface::luaDatabaseLastInsertId(lua_State* L) { // db.lastInsertId() - lua_pushnumber(L, Database::getInstance().getLastInsertId()); + lua_pushnumber(L, tfs::db::last_insert_id()); return 1; } @@ -4374,39 +4374,39 @@ const luaL_Reg LuaScriptInterface::luaResultTable[] = { int LuaScriptInterface::luaResultGetNumber(lua_State* L) { - DBResult_ptr res = getResultByID(tfs::lua::getNumber(L, 1)); - if (!res) { + auto result = getResultByID(tfs::lua::getNumber(L, 1)); + if (!result) { tfs::lua::pushBoolean(L, false); return 1; } const std::string& s = tfs::lua::getString(L, 2); - lua_pushnumber(L, res->getNumber(s)); + lua_pushnumber(L, result->getNumber(s)); return 1; } int LuaScriptInterface::luaResultGetString(lua_State* L) { - DBResult_ptr res = getResultByID(tfs::lua::getNumber(L, 1)); - if (!res) { + auto result = getResultByID(tfs::lua::getNumber(L, 1)); + if (!result) { tfs::lua::pushBoolean(L, false); return 1; } const std::string& s = tfs::lua::getString(L, 2); - tfs::lua::pushString(L, res->getString(s)); + tfs::lua::pushString(L, result->getString(s)); return 1; } int LuaScriptInterface::luaResultGetStream(lua_State* L) { - DBResult_ptr res = getResultByID(tfs::lua::getNumber(L, 1)); - if (!res) { + auto result = getResultByID(tfs::lua::getNumber(L, 1)); + if (!result) { tfs::lua::pushBoolean(L, false); return 1; } - auto stream = res->getString(tfs::lua::getString(L, 2)); + auto stream = result->getString(tfs::lua::getString(L, 2)); lua_pushlstring(L, stream.data(), stream.size()); lua_pushnumber(L, stream.size()); return 2; @@ -4414,13 +4414,13 @@ int LuaScriptInterface::luaResultGetStream(lua_State* L) int LuaScriptInterface::luaResultNext(lua_State* L) { - DBResult_ptr res = getResultByID(tfs::lua::getNumber(L, -1)); - if (!res) { + auto result = getResultByID(tfs::lua::getNumber(L, -1)); + if (!result) { tfs::lua::pushBoolean(L, false); return 1; } - tfs::lua::pushBoolean(L, res->next()); + tfs::lua::pushBoolean(L, result->next()); return 1; } diff --git a/src/otserv.cpp b/src/otserv.cpp index 88fa3a2f92..25f05745f8 100644 --- a/src/otserv.cpp +++ b/src/otserv.cpp @@ -114,12 +114,12 @@ void mainLoader(ServiceManager* services) std::cout << ">> Establishing database connection..." << std::flush; - if (!Database::getInstance().connect()) { + if (!tfs::db::connect()) { startupErrorMessage("Failed to connect to database."); return; } - std::cout << " MySQL " << Database::getClientVersion() << std::endl; + std::cout << " MySQL " << tfs::db::client_version() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; diff --git a/src/protocolgame.cpp b/src/protocolgame.cpp index 5955ad170d..0dc34d064b 100644 --- a/src/protocolgame.cpp +++ b/src/protocolgame.cpp @@ -407,8 +407,8 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) } auto characterName = msg.getString(); - uint32_t timeStamp = msg.get(); - uint8_t randNumber = msg.getByte(); + auto timeStamp = msg.get(); + auto randNumber = msg.getByte(); if (challengeTimestamp != timeStamp || challengeRandom != randNumber) { disconnect(); return; @@ -431,22 +431,21 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) return; } - Database& db = Database::getInstance(); - auto result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `a`.`id` AS `account_id`, INET6_NTOA(`s`.`ip`) AS `session_ip`, `p`.`id` AS `character_id` FROM `accounts` `a` JOIN `sessions` `s` ON `a`.`id` = `s`.`account_id` JOIN `players` `p` ON `a`.`id` = `p`.`account_id` WHERE `s`.`token` = {:s} AND `s`.`expired_at` IS NULL AND `p`.`name` = {:s} AND `p`.`deletion` = 0", - db.escapeString(sessionToken), db.escapeString(characterName))); + tfs::db::escape_string(sessionToken), tfs::db::escape_string(characterName))); if (!result) { disconnectClient("Account name or password is not correct."); return; } - uint32_t accountId = result->getNumber("account_id"); + auto accountId = result->getNumber("account_id"); if (accountId == 0) { disconnectClient("Account name or password is not correct."); return; } - Connection::Address sessionIP = boost::asio::ip::make_address(result->getString("session_ip")); + auto sessionIP = boost::asio::ip::make_address(result->getString("session_ip")); if (!sessionIP.is_loopback() && ip != sessionIP) { disconnectClient("Your game session is already locked to a different IP. Please log in again."); } diff --git a/src/protocollogin.cpp b/src/protocollogin.cpp index 7d741c3ed2..1da69e052f 100644 --- a/src/protocollogin.cpp +++ b/src/protocollogin.cpp @@ -62,11 +62,9 @@ void ProtocolLogin::disconnectClient(const std::string& message, uint16_t versio void ProtocolLogin::getCharacterList(const std::string& accountName, const std::string& password, const std::string& token, uint16_t version) { - Database& db = Database::getInstance(); - - DBResult_ptr result = db.storeQuery(fmt::format( + auto result = tfs::db::store_query(fmt::format( "SELECT `id`, UNHEX(`password`) AS `password`, `secret`, `premium_ends_at` FROM `accounts` WHERE `name` = {:s} OR `email` = {:s}", - db.escapeString(accountName), db.escapeString(accountName))); + tfs::db::escape_string(accountName), tfs::db::escape_string(accountName))); if (!result) { disconnectClient("Account name or password is not correct.", version); return; @@ -82,9 +80,9 @@ void ProtocolLogin::getCharacterList(const std::string& accountName, const std:: auto premiumEndsAt = result->getNumber("premium_ends_at"); std::vector characters = {}; - result = db.storeQuery(fmt::format( - "SELECT `name` FROM `players` WHERE `account_id` = {:d} AND `deletion` = 0 ORDER BY `name` ASC", id)); - if (result) { + + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `name` FROM `players` WHERE `account_id` = {:d} AND `deletion` = 0 ORDER BY `name` ASC", id))) { do { characters.emplace_back(result->getString("name")); } while (result->next()); @@ -115,10 +113,10 @@ void ProtocolLogin::getCharacterList(const std::string& accountName, const std:: output->addByte(0x28); output->addString(tfs::base64::encode({sessionKey.data(), sessionKey.size()})); - if (!db.executeQuery( + if (!tfs::db::execute_query( fmt::format("INSERT INTO `sessions` (`token`, `account_id`, `ip`) VALUES ({:s}, {:d}, INET6_ATON({:s}))", - db.escapeBlob(sessionKey.data(), sessionKey.size()), id, - db.escapeString(getConnection()->getIP().to_string())))) { + tfs::db::escape_blob(sessionKey.data(), sessionKey.size()), id, + tfs::db::escape_string(getConnection()->getIP().to_string())))) { disconnectClient("Failed to create session.\nPlease try again later.", version); return; } From 46a4763b07b69c1187e018c646f76681e815b4c6 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 23:01:13 -0300 Subject: [PATCH 2/6] Fix code style --- src/iomarket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iomarket.cpp b/src/iomarket.cpp index 5d54004cbc..5eab18031a 100644 --- a/src/iomarket.cpp +++ b/src/iomarket.cpp @@ -197,7 +197,7 @@ void IOMarket::checkExpiredOffers() uint32_t IOMarket::getPlayerOfferCount(uint32_t playerId) { auto result = tfs::db::store_query( - fmt::format("SELECT COUNT(*) AS `count` FROM `market_offers` WHERE `player_id` = {:d}", playerId)); + fmt::format("SELECT COUNT(*) AS `count` FROM `market_offers` WHERE `player_id` = {:d}", playerId)); if (!result) { return 0; } From 302d10789fc8b9a4f3501e7820f331d48d9385fe Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 23:12:07 -0300 Subject: [PATCH 3/6] Fix test and use auto result --- src/guild.cpp | 4 +-- src/http/tests/test_cacheinfo.cpp | 9 +++-- src/iologindata.cpp | 58 +++++++++++++++---------------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/guild.cpp b/src/guild.cpp index ecf537720a..93281b98e6 100644 --- a/src/guild.cpp +++ b/src/guild.cpp @@ -64,8 +64,8 @@ Guild_ptr IOGuild::loadGuild(uint32_t guildId) } const auto& guild = std::make_shared(guildId, result->getString("name")); - if ((result = tfs::db::store_query( - fmt::format("SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = {:d}", guildId)))) { + if (auto result = tfs::db::store_query( + fmt::format("SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = {:d}", guildId))) { do { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); diff --git a/src/http/tests/test_cacheinfo.cpp b/src/http/tests/test_cacheinfo.cpp index 68e26b81da..2606d6a252 100644 --- a/src/http/tests/test_cacheinfo.cpp +++ b/src/http/tests/test_cacheinfo.cpp @@ -20,7 +20,7 @@ struct CacheInfoFixture setString(ConfigManager::MYSQL_DB, "forgottenserver"); setNumber(ConfigManager::SQL_PORT, 3306); - db.connect(); + tfs::db::connect(); transaction.begin(); } @@ -28,10 +28,9 @@ struct CacheInfoFixture { // `players_online` is a memory table and does not support transactions, so we need to clear it manually // do NOT run this test against a running server's database - db.executeQuery("TRUNCATE `players_online`"); + tfs::db::execute_query("TRUNCATE `players_online`"); } - Database& db = Database::getInstance(); DBTransaction transaction; std::string_view ip = "74.125.224.72"; @@ -42,7 +41,7 @@ using status = boost::beast::http::status; BOOST_FIXTURE_TEST_CASE(test_login_success_with_token, CacheInfoFixture) { - auto result = db.storeQuery( + auto result = tfs::db::store_query( "INSERT INTO `accounts` (`name`, `email`, `password`, `secret`) VALUES ('foo', 'foo@example.com', SHA1('bar'), UNHEX('')) RETURNING `id`"); auto id = result->getNumber("id"); @@ -54,7 +53,7 @@ BOOST_FIXTURE_TEST_CASE(test_login_success_with_token, CacheInfoFixture) insertPlayers.addRow(fmt::format("{:d}, \"{:s}\"", id, "Bobeek")); BOOST_TEST(insertPlayers.execute()); - BOOST_TEST(db.executeQuery(fmt::format( + BOOST_TEST(tfs::db::execute_query(fmt::format( "INSERT INTO `players_online` (`player_id`) SELECT `id` FROM `players` WHERE `account_id` = {:d}", id))); auto&& [status, body] = tfs::http::handle_cacheinfo({{"type", "cacheinfo"}}, ip); diff --git a/src/iologindata.cpp b/src/iologindata.cpp index ef913809cc..58e1e65b64 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -290,9 +290,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->skills[i].percent = Player::getBasisPointLevel(skillTries, nextSkillTries); } - if ((result = tfs::db::store_query( - fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", - player->getGUID())))) { + if (auto result = tfs::db::store_query( + fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", + player->getGUID()))) { uint32_t guildId = result->getNumber("guild_id"); uint32_t playerRankId = result->getNumber("rank_id"); player->guildNick = result->getString("nick"); @@ -312,8 +312,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guild = guild; auto rank = guild->getRankById(playerRankId); if (!rank) { - if ((result = tfs::db::store_query(fmt::format( - "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId)))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId))) { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); } @@ -327,15 +327,15 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guildRank = rank; player->guildWarVector = getWarList(guildId); - if ((result = tfs::db::store_query(fmt::format( - "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId)))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId))) { guild->setMemberCount(result->getNumber("members")); } } } - if ((result = tfs::db::store_query(fmt::format( - "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID()))) { do { player->learnedInstantSpellList.emplace_front(result->getString("name")); } while (result->next()); @@ -345,9 +345,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) ItemMap itemMap; std::map openContainersList; - if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -387,9 +387,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load depot items itemMap.clear(); - if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -419,9 +419,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load inbox items itemMap.clear(); - if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -449,9 +449,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load store inbox items itemMap.clear(); - if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -477,32 +477,32 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } // load storage map - if ((result = tfs::db::store_query( - fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID())))) { + if (auto result = tfs::db::store_query( + fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID()))) { do { player->setStorageValue(result->getNumber("key"), result->getNumber("value"), true); } while (result->next()); } // load vip list - if ((result = tfs::db::store_query(fmt::format( - "SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount())))) { + if (auto result = tfs::db::store_query( + fmt::format("SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount()))) { do { player->addVIPInternal(result->getNumber("player_id")); } while (result->next()); } // load outfits & addons - if ((result = tfs::db::store_query(fmt::format( - "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID())))) { + if (auto result = tfs::db::store_query(fmt::format( + "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID()))) { do { player->addOutfit(result->getNumber("outfit_id"), result->getNumber("addons")); } while (result->next()); } // load mounts - if ((result = tfs::db::store_query( - fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID())))) { + if (auto result = tfs::db::store_query( + fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID()))) { do { player->tameMount(result->getNumber("mount_id")); } while (result->next()); From 2a0d007b6938f53754c0558693688207537109fb Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 23:28:06 -0300 Subject: [PATCH 4/6] Revert auto result --- src/iologindata.cpp | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/iologindata.cpp b/src/iologindata.cpp index 58e1e65b64..b696c2be97 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -290,9 +290,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->skills[i].percent = Player::getBasisPointLevel(skillTries, nextSkillTries); } - if (auto result = tfs::db::store_query( + if ((result = tfs::db::store_query( fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", - player->getGUID()))) { + player->getGUID())))) { uint32_t guildId = result->getNumber("guild_id"); uint32_t playerRankId = result->getNumber("rank_id"); player->guildNick = result->getString("nick"); @@ -312,8 +312,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guild = guild; auto rank = guild->getRankById(playerRankId); if (!rank) { - if (auto result = tfs::db::store_query(fmt::format( - "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId)))) { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); } @@ -327,15 +327,15 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guildRank = rank; player->guildWarVector = getWarList(guildId); - if (auto result = tfs::db::store_query(fmt::format( - "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId)))) { guild->setMemberCount(result->getNumber("members")); } } } - if (auto result = tfs::db::store_query(fmt::format( - "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID()))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->learnedInstantSpellList.emplace_front(result->getString("name")); } while (result->next()); @@ -345,9 +345,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) ItemMap itemMap; std::map openContainersList; - if (auto result = tfs::db::store_query(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID()))) { + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -387,9 +387,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load depot items itemMap.clear(); - if (auto result = tfs::db::store_query(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID()))) { + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -419,9 +419,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load inbox items itemMap.clear(); - if (auto result = tfs::db::store_query(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID()))) { + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -449,9 +449,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load store inbox items itemMap.clear(); - if (auto result = tfs::db::store_query(fmt::format( + if ((result = tfs::db::store_query(fmt::format( "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID()))) { + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -477,32 +477,32 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } // load storage map - if (auto result = tfs::db::store_query( - fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID()))) { + if ((result = tfs::db::store_query( + fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->setStorageValue(result->getNumber("key"), result->getNumber("value"), true); } while (result->next()); } // load vip list - if (auto result = tfs::db::store_query( - fmt::format("SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount()))) { + if ((result = tfs::db::store_query( + fmt::format("SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount())))) { do { player->addVIPInternal(result->getNumber("player_id")); } while (result->next()); } // load outfits & addons - if (auto result = tfs::db::store_query(fmt::format( - "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID()))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->addOutfit(result->getNumber("outfit_id"), result->getNumber("addons")); } while (result->next()); } // load mounts - if (auto result = tfs::db::store_query( - fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID()))) { + if ((result = tfs::db::store_query( + fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->tameMount(result->getNumber("mount_id")); } while (result->next()); From 317569a23fb0b20f27689597b6798d742c125819 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 23:31:13 -0300 Subject: [PATCH 5/6] Revert auto result --- src/guild.cpp | 4 ++-- src/http/login.cpp | 6 +++--- src/iomapserialize.cpp | 2 +- src/protocollogin.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/guild.cpp b/src/guild.cpp index 93281b98e6..ecf537720a 100644 --- a/src/guild.cpp +++ b/src/guild.cpp @@ -64,8 +64,8 @@ Guild_ptr IOGuild::loadGuild(uint32_t guildId) } const auto& guild = std::make_shared(guildId, result->getString("name")); - if (auto result = tfs::db::store_query( - fmt::format("SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = {:d}", guildId))) { + if ((result = tfs::db::store_query( + fmt::format("SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = {:d}", guildId)))) { do { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); diff --git a/src/http/login.cpp b/src/http/login.cpp index de82d1856d..4bdfca925e 100644 --- a/src/http/login.cpp +++ b/src/http/login.cpp @@ -93,9 +93,9 @@ std::pair tfs::http::handle_login(const json::object& body, json::array characters; uint32_t lastLogin = 0; - if (auto result = tfs::db::store_query(fmt::format( - "SELECT `id`, `name`, `level`, `vocation`, `lastlogin`, `sex`, `looktype`, `lookhead`, `lookbody`, `looklegs`, `lookfeet`, `lookaddons` FROM `players` WHERE `account_id` = {:d}", - accountId))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `id`, `name`, `level`, `vocation`, `lastlogin`, `sex`, `looktype`, `lookhead`, `lookbody`, `looklegs`, `lookfeet`, `lookaddons` FROM `players` WHERE `account_id` = {:d}", + accountId)))) { do { auto vocation = g_vocations.getVocation(result->getNumber("vocation")); assert(vocation); diff --git a/src/iomapserialize.cpp b/src/iomapserialize.cpp index 61adf337fe..cc3c5fd37b 100644 --- a/src/iomapserialize.cpp +++ b/src/iomapserialize.cpp @@ -264,7 +264,7 @@ bool IOMapSerialize::loadHouseInfo() } } while (result->next()); - if (auto result = tfs::db::store_query("SELECT `house_id`, `listid`, `list` FROM `house_lists`")) { + if ((result = tfs::db::store_query("SELECT `house_id`, `listid`, `list` FROM `house_lists`"))) { do { if (auto house = g_game.map.houses.getHouse(result->getNumber("house_id"))) { house->setAccessList(result->getNumber("listid"), result->getString("list")); diff --git a/src/protocollogin.cpp b/src/protocollogin.cpp index 1da69e052f..734b33a46a 100644 --- a/src/protocollogin.cpp +++ b/src/protocollogin.cpp @@ -81,8 +81,8 @@ void ProtocolLogin::getCharacterList(const std::string& accountName, const std:: std::vector characters = {}; - if (auto result = tfs::db::store_query(fmt::format( - "SELECT `name` FROM `players` WHERE `account_id` = {:d} AND `deletion` = 0 ORDER BY `name` ASC", id))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `name` FROM `players` WHERE `account_id` = {:d} AND `deletion` = 0 ORDER BY `name` ASC", id)))) { do { characters.emplace_back(result->getString("name")); } while (result->next()); From 737751d8e41885854d4364dad6f88e5949a965cf Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Sun, 24 Nov 2024 23:32:45 -0300 Subject: [PATCH 6/6] Fix code style --- src/iologindata.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/iologindata.cpp b/src/iologindata.cpp index b696c2be97..ef913809cc 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -291,8 +291,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) } if ((result = tfs::db::store_query( - fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", - player->getGUID())))) { + fmt::format("SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = {:d}", + player->getGUID())))) { uint32_t guildId = result->getNumber("guild_id"); uint32_t playerRankId = result->getNumber("rank_id"); player->guildNick = result->getString("nick"); @@ -313,7 +313,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) auto rank = guild->getRankById(playerRankId); if (!rank) { if ((result = tfs::db::store_query(fmt::format( - "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId)))) { + "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `id` = {:d}", playerRankId)))) { guild->addRank(result->getNumber("id"), result->getString("name"), result->getNumber("level")); } @@ -328,14 +328,14 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) player->guildWarVector = getWarList(guildId); if ((result = tfs::db::store_query(fmt::format( - "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId)))) { + "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = {:d}", guildId)))) { guild->setMemberCount(result->getNumber("members")); } } } if ((result = tfs::db::store_query(fmt::format( - "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID())))) { + "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->learnedInstantSpellList.emplace_front(result->getString("name")); } while (result->next()); @@ -346,8 +346,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) std::map openContainersList; if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -388,8 +388,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) itemMap.clear(); if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -420,8 +420,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) itemMap.clear(); if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -450,8 +450,8 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) itemMap.clear(); if ((result = tfs::db::store_query(fmt::format( - "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", - player->getGUID())))) { + "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_storeinboxitems` WHERE `player_id` = {:d} ORDER BY `sid` DESC", + player->getGUID())))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { @@ -478,15 +478,15 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load storage map if ((result = tfs::db::store_query( - fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID())))) { + fmt::format("SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->setStorageValue(result->getNumber("key"), result->getNumber("value"), true); } while (result->next()); } // load vip list - if ((result = tfs::db::store_query( - fmt::format("SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount())))) { + if ((result = tfs::db::store_query(fmt::format( + "SELECT `player_id` FROM `account_viplist` WHERE `account_id` = {:d}", player->getAccount())))) { do { player->addVIPInternal(result->getNumber("player_id")); } while (result->next()); @@ -494,7 +494,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load outfits & addons if ((result = tfs::db::store_query(fmt::format( - "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID())))) { + "SELECT `outfit_id`, `addons` FROM `player_outfits` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->addOutfit(result->getNumber("outfit_id"), result->getNumber("addons")); } while (result->next()); @@ -502,7 +502,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) // load mounts if ((result = tfs::db::store_query( - fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID())))) { + fmt::format("SELECT `mount_id` FROM `player_mounts` WHERE `player_id` = {:d}", player->getGUID())))) { do { player->tameMount(result->getNumber("mount_id")); } while (result->next());