#pragma once #include "dps/config.hpp" #include "dps/http.hpp" #include "dps/json.hpp" #include #include #include #include #include #include #include namespace dps { struct User { int id = 0; std::string username; std::string password; int gold = 0; int level = 1; std::string qq; std::string name; std::string img; std::string client_key; std::string server_key; }; struct UserAndServer { std::string user_name; std::string server_ip; std::string account; std::string password; std::string port; }; struct UserServerProject { std::string server_ip; std::string project_name; std::string user_name; std::string expiration_date; int open = 1; }; struct ProjectDefinition { std::string name; std::vector script_paths; std::map info; int price = 0; bool is_private = false; std::string img_path; }; class LegacyCrypto { public: explicit LegacyCrypto(std::string jwt_secret); std::string issue_jwt(const std::string &username, long long expiration_seconds) const; std::optional validate_jwt(const std::string &token) const; std::string hash_password(const std::string &password) const; bool verify_password(const std::string &password, const std::string &encoded) const; std::string rsa_private_encrypt_tool(const std::string &plain) const; std::string rsa_private_encrypt_script(const std::string &plain) const; std::string gzip_base64(const std::string &plain) const; std::vector makecode(std::vector bytes, const std::vector &key) const; std::string xor_encrypt(const std::string &plain, const std::string &key) const; private: std::string base64_url_encode(const std::string &input) const; std::string base64_url_decode(const std::string &input) const; std::string hmac_sha256(const std::string &message) const; std::string sha256_hex(const std::string &message) const; std::string bcrypt_hash(const std::string &password) const; std::string rsa_private_encrypt_der_b64(const std::string &der_b64, const std::string &plain) const; std::string jwt_secret_; }; class Database { public: explicit Database(const DatabaseConfig &config); ~Database(); bool connect(); bool is_connected() const; std::string last_error() const; std::string escape(const std::string &value) const; bool execute(const std::string &sql); std::vector> query(const std::string &sql); long long last_insert_id() const; private: struct Impl; std::unique_ptr impl_; }; class ProjectCatalog { public: explicit ProjectCatalog(const PathConfig &paths); void reload(); std::optional get_project(const std::string &name, const std::string &version = "") const; Json public_project_info() const; Json all_project_info() const; int project_price(const std::string &name) const; std::string project_img_path(const std::string &name) const; std::vector base_script_contents(const std::string &version, bool cs_mode) const; std::vector project_script_contents(const std::string &project_name, const std::string &version) const; std::vector custom_client_scripts(const std::string &ip, const std::string &version) const; std::vector> dps_service_scripts(const std::string &ip) const; std::vector> dps_service_scripts_new(const std::string &ip, const std::string &version) const; std::string newest_version() const; long long base_update_time(const std::string &version) const; private: struct VersionData { std::string name; std::map projects; std::vector base_scripts; std::vector cs_base_scripts; std::map> project_scripts; std::map> custom_client_scripts; Json dps_manifest; }; const VersionData *find_version(const std::string &requested) const; std::vector read_script_list(const std::string &root, const std::vector &items) const; std::vector> read_named_scripts(const std::string &root, const std::vector &items) const; void load_client_versions(); void load_custom_client_scripts(VersionData &data); Json parse_json_file(const std::string &path) const; PathConfig paths_; std::map versions_; std::string newest_version_; }; class Application { public: explicit Application(AppConfig config); int run(); private: using Row = std::map; void register_routes(); Response handle_login(const Request &request); Response handle_register(const Request &request); Response handle_change_password(const Request &request); Response handle_get_info(const Request &request); Response handle_add_server(const Request &request); Response handle_delete_server(const Request &request); Response handle_get_server_list(const Request &request); Response handle_get_server(const Request &request); Response handle_get_project_info_list(const Request &request); Response handle_get_user_project_list(const Request &request); Response handle_get_server_project_list(const Request &request); Response handle_buy(const Request &request); Response handle_add_gold(const Request &request); Response handle_transfer(const Request &request); Response handle_set_key(const Request &request); Response handle_set_project_open(const Request &request); Response handle_rindro_download(const Request &request); Response handle_static_download(const std::string &disk_path, const std::string &download_name) const; Response handle_get_image(const Request &request, bool thumbnail); Response handle_get_mp42(const Request &request); Response handle_get_version(const Request &request); Response handle_dps_version(const std::string &relative_file) const; Response handle_dps_list(const std::string &relative_dir, const std::string &metadata_file) const; Response handle_dps_download(const Request &request, const std::string &base_dir) const; Response handle_script_client(const Request &request); Response handle_script_client2(const Request &request); Response handle_script_getzdy(const Request &request); Response handle_script_getpro(const Request &request); Response handle_script_getservice(const Request &request); Response handle_script_base_update_time(const Request &request); Response handle_script_base_sut(const Request &request); Response handle_script_getservice_new(const Request &request); Response handle_video_placeholder(const Request &request); Response handle_payment_placeholder(const Request &request); std::optional find_user_by_username(const std::string &username); bool username_exists(const std::string &username); bool create_user(const std::string &username, const std::string &password, const std::string &qq); bool update_password(const std::string &username, const std::string &qq, const std::string &password); bool update_user_row(const User &user); std::vector servers_for_user(const std::string &username); std::optional find_server(const std::string &username, const std::string &ip); bool upsert_server(const UserAndServer &server); bool delete_server(const std::string &username, const std::string &ip); std::vector projects_for_ip(const std::string &ip, bool require_open = false); std::vector projects_for_user(const std::string &username); std::optional find_project_binding(const std::string &ip, const std::string &project_name); bool add_or_extend_project(const std::string &ip, const std::string &project_name, int days, const std::string &username); bool update_project_open(const std::string &ip, const std::string &project_name, int open_value); bool insert_log(const std::string &username, int type, const std::string &content); Response json_response(int status, const Json &body) const; Response common_success(const Json &data, const std::string &message = "操作成功", int status = 200) const; Response common_failed(int code, const std::string &message, int http_status = 200) const; Response file_response(const std::filesystem::path &path, const std::string &download_name = "") const; std::string request_ip(const Request &request) const; std::vector random_key() const; std::string format_date_now() const; std::string add_days(const std::string &iso_date, int days) const; std::string make_random_name() const; Json parse_body_or_empty(const Request &request) const; std::optional current_user(const Request &request) const; AppConfig config_; Router router_; LegacyCrypto crypto_; Database database_; ProjectCatalog catalog_; mutable std::mutex transfer_mutex_; mutable std::mutex script_mutex_; std::map ip_and_mac_; }; } // namespace dps