diff --git a/src/server/campaignd/server.cpp b/src/server/campaignd/server.cpp index 23285e0c225..8e93bf81de3 100644 --- a/src/server/campaignd/server.cpp +++ b/src/server/campaignd/server.cpp @@ -1196,6 +1196,9 @@ void server::handle_request_campaign(const server::request& req) if(req.cfg["increase_downloads"].to_bool(true) && !ignore_address_stats(req.addr)) { addon["downloads"] = 1 + addon["downloads"].to_int(); mark_dirty(name); + if(user_handler_) { + user_handler_->db_update_addon_download_count(server_id_, name, to); + } } } diff --git a/src/server/common/dbconn.cpp b/src/server/common/dbconn.cpp index f602b5a8351..98c8732d297 100644 --- a/src/server/common/dbconn.cpp +++ b/src/server/common/dbconn.cpp @@ -446,6 +446,19 @@ void dbconn::get_ips_for_user(const std::string& username, std::ostringstream* o } } +void dbconn::update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version) +{ + try + { + modify(connection_, "UPDATE `"+db_addon_info_table_+"` SET DOWNLOAD_COUNT = DOWNLOAD_COUNT+1 WHERE INSTANCE_VERSION = ? AND ADDON_ID = ? AND VERSION = ?", + instance_version, id, version); + } + catch(const mariadb::exception::base& e) + { + log_sql_exception("Unable to update download count for add-on "+id+" with version "+version+".", e); + } +} + // // handle complex query results // diff --git a/src/server/common/dbconn.hpp b/src/server/common/dbconn.hpp index db916fe9b9d..760d931aad4 100644 --- a/src/server/common/dbconn.hpp +++ b/src/server/common/dbconn.hpp @@ -174,6 +174,11 @@ class dbconn */ void get_ips_for_user(const std::string& username, std::ostringstream* out); + /** + * @see forum_user_handler::db_update_addon_download_count(). + */ + void update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version); + private: /** * The account used to connect to the database. diff --git a/src/server/common/forum_user_handler.cpp b/src/server/common/forum_user_handler.cpp index 037cb101f7c..ae785707e90 100644 --- a/src/server/common/forum_user_handler.cpp +++ b/src/server/common/forum_user_handler.cpp @@ -187,6 +187,10 @@ std::string fuh::get_user_email(const std::string& user) { return conn_.get_user_string(db_users_table_, "user_email", user); } +void fuh::db_update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version) { + return conn_.update_addon_download_count(instance_version, id, version); +} + std::time_t fuh::get_lastlogin(const std::string& user) { return std::time_t(conn_.get_user_int(db_extra_table_, "user_lastvisit", user)); } diff --git a/src/server/common/forum_user_handler.hpp b/src/server/common/forum_user_handler.hpp index e405d321906..92c0ca3ec7a 100644 --- a/src/server/common/forum_user_handler.hpp +++ b/src/server/common/forum_user_handler.hpp @@ -263,6 +263,15 @@ public: */ std::string get_user_email(const std::string& user); + /** + * Increments the download count for this add-on for the specific version. + * + * @param instance_version The version of campaignd the add-on was uploaded to. + * @param id The add-on's ID (aka directory name). + * @param version The version of the add-on being downloaded. May not be the most recent version. + */ + void db_update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version); + private: /** An instance of the class responsible for executing the queries and handling the database connection. */ dbconn conn_; diff --git a/src/server/common/user_handler.hpp b/src/server/common/user_handler.hpp index acb08c87c54..2018bca56f9 100644 --- a/src/server/common/user_handler.hpp +++ b/src/server/common/user_handler.hpp @@ -152,4 +152,5 @@ public: virtual void db_update_logout(unsigned long long login_id) = 0; virtual void get_users_for_ip(const std::string& ip, std::ostringstream* out) = 0; virtual void get_ips_for_user(const std::string& username, std::ostringstream* out) = 0; + virtual void db_update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version) = 0; }; diff --git a/utils/mp-server/query-scripts/25-addon-download-counts.sql b/utils/mp-server/query-scripts/25-addon-download-counts.sql new file mode 100644 index 00000000000..5c089b21a47 --- /dev/null +++ b/utils/mp-server/query-scripts/25-addon-download-counts.sql @@ -0,0 +1,3 @@ +select INSTANCE_VERSION, ADDON_ID, VERSION, UPLOADED_ON, DOWNLOAD_COUNT +from campaignd_addon_info +order by INSTANCE_VERSION, ADDON_ID, VERSION \ No newline at end of file diff --git a/utils/mp-server/table_definitions.sql b/utils/mp-server/table_definitions.sql index 64a1e7f7238..7c12731a298 100644 --- a/utils/mp-server/table_definitions.sql +++ b/utils/mp-server/table_definitions.sql @@ -134,6 +134,7 @@ create table game_content_info -- FORUM_AUTH: whether forum authentication is to be used when uploading -- UPLOADED_ON: when the addon was uploaded -- FEEDBACK_TOPIC: the forum topic ID where feedback for the addon can be posted, 0 if not set +-- DOWNLOAD_COUNT: the number of times the add-on has been downloaded by players (does not count downloads from https://addons.wesnoth.org) create table addon_info ( INSTANCE_VERSION VARCHAR(255) NOT NULL, @@ -144,6 +145,7 @@ create table addon_info FORUM_AUTH BIT(1) NOT NULL, UPLOADED_ON TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FEEDBACK_TOPIC INT UNSIGNED NOT NULL, + DOWNLOAD_COUNT INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (INSTANCE_VERSION, ADDON_ID, VERSION) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;