From e8d7ec8dafb131e725c9899372722ecb9a223c79 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Tue, 22 Jul 2025 18:55:12 +0800 Subject: [PATCH] [feat] save log and cache files into user folder --- .../keyboard/windows/keyboard_capturer.cpp | 2 +- src/gui/main.cpp | 2 - src/log/rd_log.cpp | 71 +++++++++++++------ src/log/rd_log.h | 24 +++---- src/path_manager/path_manager.cpp | 18 ++++- src/path_manager/path_manager.h | 2 + src/single_window/render.cpp | 41 ++++++++--- src/single_window/render.h | 9 ++- src/single_window/thumbnail.cpp | 33 +++++---- src/single_window/thumbnail.h | 7 +- thirdparty/minirtc | 2 +- 11 files changed, 146 insertions(+), 65 deletions(-) diff --git a/src/device_controller/keyboard/windows/keyboard_capturer.cpp b/src/device_controller/keyboard/windows/keyboard_capturer.cpp index f9ea758..ace1520 100644 --- a/src/device_controller/keyboard/windows/keyboard_capturer.cpp +++ b/src/device_controller/keyboard/windows/keyboard_capturer.cpp @@ -30,7 +30,7 @@ int KeyboardCapturer::Hook(OnKeyAction on_key_action, void* user_ptr) { keyboard_hook_ = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0); if (!keyboard_hook_) { - LOG_ERROR("Failed to install keyboard hook!") + LOG_ERROR("Failed to install keyboard hook"); return -1; } return 0; diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 2f0e9c3..e2d2bd2 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -10,9 +10,7 @@ #include "render.h" int main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) { - LOG_INFO("Remote desk"); Render render; - render.Run(); return 0; diff --git a/src/log/rd_log.cpp b/src/log/rd_log.cpp index d6f2a20..e945000 100644 --- a/src/log/rd_log.cpp +++ b/src/log/rd_log.cpp @@ -1,37 +1,62 @@ #include "rd_log.h" -std::shared_ptr get_rd_logger() { - if (auto logger = spdlog::get(RD_LOGGER_NAME)) { - return logger; +#include +#include + +namespace { + +std::string g_log_dir = "logs"; +std::once_flag g_logger_once_flag; +std::shared_ptr g_logger; +std::atomic g_logger_created{false}; + +} // namespace + +void InitLogger(const std::string& log_dir) { + if (g_logger_created.load()) { + LOG_WARN( + "InitLogger called after logger initialized. Ignoring log_dir: {}, " + "using previous log_dir: {}", + log_dir, g_log_dir); + return; } - auto now = std::chrono::system_clock::now() + std::chrono::hours(8); - auto now_time = std::chrono::system_clock::to_time_t(now); + g_log_dir = log_dir; +} - std::tm tm_info; +std::shared_ptr get_logger() { + std::call_once(g_logger_once_flag, []() { + g_logger_created.store(true); + std::error_code ec; + std::filesystem::create_directories(g_log_dir, ec); + + auto now = std::chrono::system_clock::now() + std::chrono::hours(8); + auto now_time = std::chrono::system_clock::to_time_t(now); + + std::tm tm_info; #ifdef _WIN32 - gmtime_s(&tm_info, &now_time); + gmtime_s(&tm_info, &now_time); #else - gmtime_r(&now_time, &tm_info); + gmtime_r(&now_time, &tm_info); #endif - std::stringstream ss; - std::string filename; - ss << RD_LOGGER_NAME; - ss << std::put_time(&tm_info, "-%Y%m%d-%H%M%S.log"); - ss >> filename; + std::stringstream ss; + ss << LOGGER_NAME; + ss << std::put_time(&tm_info, "-%Y%m%d-%H%M%S.log"); - std::string path = "logs/" + filename; - std::vector sinks; - sinks.push_back(std::make_shared()); - sinks.push_back(std::make_shared( - path, 1048576 * 5, 3)); + std::string filename = g_log_dir + "/" + ss.str(); - auto combined_logger = std::make_shared( - RD_LOGGER_NAME, begin(sinks), end(sinks)); - combined_logger->flush_on(spdlog::level::info); - spdlog::register_logger(combined_logger); + std::vector sinks; + sinks.push_back(std::make_shared()); + sinks.push_back(std::make_shared( + filename, 5 * 1024 * 1024, 3)); - return combined_logger; + g_logger = std::make_shared(LOGGER_NAME, sinks.begin(), + sinks.end()); + g_logger->flush_on(spdlog::level::info); + spdlog::register_logger(g_logger); + }); + + return g_logger; } diff --git a/src/log/rd_log.h b/src/log/rd_log.h index 829e130..ff16364 100644 --- a/src/log/rd_log.h +++ b/src/log/rd_log.h @@ -1,7 +1,7 @@ /* * @Author: DI JUNKUN - * @Date: 2024-11-26 - * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved. + * @Date: 2025-07-21 + * Copyright (c) 2025 by DI JUNKUN, All Rights Reserved. */ #ifndef _RD_LOG_H_ @@ -10,8 +10,11 @@ #include #include #include +#include +#include #include #include +#include #include "spdlog/common.h" #include "spdlog/logger.h" @@ -20,20 +23,17 @@ #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/spdlog.h" -using namespace std::chrono; - #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO -constexpr auto RD_LOGGER_NAME = "rd"; +constexpr auto LOGGER_NAME = "crossdesk"; -std::shared_ptr get_rd_logger(); +void InitLogger(const std::string& log_dir); -#define LOG_INFO(...) SPDLOG_LOGGER_INFO(get_rd_logger(), __VA_ARGS__); +std::shared_ptr get_logger(); -#define LOG_WARN(...) SPDLOG_LOGGER_WARN(get_rd_logger(), __VA_ARGS__); - -#define LOG_ERROR(...) SPDLOG_LOGGER_ERROR(get_rd_logger(), __VA_ARGS__); - -#define LOG_FATAL(...) SPDLOG_LOGGER_CRITICAL(get_rd_logger(), __VA_ARGS__); +#define LOG_INFO(...) SPDLOG_LOGGER_INFO(get_logger(), __VA_ARGS__) +#define LOG_WARN(...) SPDLOG_LOGGER_WARN(get_logger(), __VA_ARGS__) +#define LOG_ERROR(...) SPDLOG_LOGGER_ERROR(get_logger(), __VA_ARGS__) +#define LOG_FATAL(...) SPDLOG_LOGGER_CRITICAL(get_logger(), __VA_ARGS__) #endif \ No newline at end of file diff --git a/src/path_manager/path_manager.cpp b/src/path_manager/path_manager.cpp index 62f53b7..745615d 100644 --- a/src/path_manager/path_manager.cpp +++ b/src/path_manager/path_manager.cpp @@ -16,7 +16,7 @@ std::filesystem::path PathManager::GetConfigPath() { std::filesystem::path PathManager::GetCachePath() { #ifdef _WIN32 - return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "Cache"; + return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "cache"; #elif __APPLE__ return GetEnvOrDefault("XDG_CACHE_HOME", GetHome() + "/.cache") / app_name_; #else @@ -26,7 +26,7 @@ std::filesystem::path PathManager::GetCachePath() { std::filesystem::path PathManager::GetLogPath() { #ifdef _WIN32 - return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "Logs"; + return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "logs"; #elif __APPLE__ return GetHome() + "/Library/Logs/" + app_name_; #else @@ -34,6 +34,20 @@ std::filesystem::path PathManager::GetLogPath() { #endif } +std::filesystem::path PathManager::GetCertPath() { +#ifdef _WIN32 + // %APPDATA%\AppName\Certs + return GetKnownFolder(FOLDERID_RoamingAppData) / app_name_ / "certs"; +#elif __APPLE__ + // $HOME/Library/Application Support/AppName/certs + return GetHome() + "/Library/Application Support/" + app_name_ + "/certs"; +#else + // $XDG_CONFIG_HOME/AppName/certs + return GetEnvOrDefault("XDG_CONFIG_HOME", GetHome() + "/.config") / + app_name_ / "certs"; +#endif +} + bool PathManager::CreateDirectories(const std::filesystem::path& p) { std::error_code ec; bool created = std::filesystem::create_directories(p, ec); diff --git a/src/path_manager/path_manager.h b/src/path_manager/path_manager.h index 8e4b366..ece0f09 100644 --- a/src/path_manager/path_manager.h +++ b/src/path_manager/path_manager.h @@ -24,6 +24,8 @@ class PathManager { std::filesystem::path GetLogPath(); + std::filesystem::path GetCertPath(); + bool CreateDirectories(const std::filesystem::path& p); private: diff --git a/src/single_window/render.cpp b/src/single_window/render.cpp index 64fafed..8e76520 100644 --- a/src/single_window/render.cpp +++ b/src/single_window/render.cpp @@ -171,7 +171,7 @@ Render::~Render() {} int Render::SaveSettingsIntoCacheFile() { cd_cache_mutex_.lock(); - std::ofstream cd_cache_file("cache.cd", std::ios::binary); + std::ofstream cd_cache_file(cache_path_ + "/cache.cd", std::ios::binary); if (!cd_cache_file) { cd_cache_mutex_.unlock(); return -1; @@ -212,7 +212,7 @@ int Render::SaveSettingsIntoCacheFile() { int Render::LoadSettingsFromCacheFile() { cd_cache_mutex_.lock(); - std::ifstream cd_cache_file("cache.cd", std::ios::binary); + std::ifstream cd_cache_file(cache_path_ + "/cache.cd", std::ios::binary); if (!cd_cache_file) { cd_cache_mutex_.unlock(); @@ -235,7 +235,7 @@ int Render::LoadSettingsFromCacheFile() { config_center_.SetTurn(enable_turn_); thumbnail_.reset(); - thumbnail_ = std::make_unique(); + thumbnail_ = std::make_unique(cache_path_ + "/thumbnails/"); thumbnail_->GetKeyAndIv(aes128_key_, aes128_iv_); thumbnail_->DeleteAllFilesInDirectory(); @@ -276,7 +276,8 @@ int Render::LoadSettingsFromCacheFile() { memcpy(aes128_iv_, cd_cache_.iv, sizeof(cd_cache_.iv)); thumbnail_.reset(); - thumbnail_ = std::make_unique(aes128_key_, aes128_iv_); + thumbnail_ = std::make_unique(cache_path_ + "/thumbnails/", + aes128_key_, aes128_iv_); language_button_value_ = cd_cache_.language; video_quality_button_value_ = cd_cache_.video_quality; @@ -351,7 +352,7 @@ int Render::ScreenCapturerInit() { int Render::StartScreenCapturer() { if (screen_capturer_) { - LOG_INFO("Start screen capturer") + LOG_INFO("Start screen capturer"); screen_capturer_->Start(); } @@ -360,7 +361,7 @@ int Render::StartScreenCapturer() { int Render::StopScreenCapturer() { if (screen_capturer_) { - LOG_INFO("Stop screen capturer") + LOG_INFO("Stop screen capturer"); screen_capturer_->Stop(); } @@ -407,7 +408,7 @@ int Render::StartMouseController() { int mouse_controller_init_ret = mouse_controller_->Init(display_info_list_); if (0 != mouse_controller_init_ret) { - LOG_INFO("Destroy mouse controller") + LOG_INFO("Destroy mouse controller"); mouse_controller_->Destroy(); mouse_controller_ = nullptr; } @@ -465,7 +466,9 @@ int Render::CreateConnectionPeer() { params_.turn_server_port = 3478; params_.turn_server_username = "dijunkun"; params_.turn_server_password = "dijunkunpw"; - params_.tls_cert_path = "certs/crossdesk.cn_root.crt"; + params_.tls_cert_path = + cert_path_.empty() ? "certs/crossdesk.cn_root.crt" : cert_path_.c_str(); + params_.log_path = dll_log_path_.empty() ? "logs" : dll_log_path_.c_str(); params_.hardware_acceleration = config_center_.IsHardwareVideoCodec(); params_.av1_encoding = config_center_.GetVideoEncodeFormat() == ConfigCenter::VIDEO_ENCODE_FORMAT::AV1 @@ -704,6 +707,10 @@ int Render::DestroyStreamWindow() { int Render::SetupFontAndStyle() { // Setup Dear ImGui style ImGuiIO& io = ImGui::GetIO(); + + imgui_cache_path_ = cache_path_ + "/crossdesk.ini"; + io.IniFilename = imgui_cache_path_.c_str(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= @@ -892,6 +899,16 @@ int Render::DrawStreamWindow() { } int Render::Run() { + path_manager_ = std::make_unique("CrossDesk"); + if (path_manager_) { + cert_path_ = + (path_manager_->GetCertPath() / "crossdesk.cn_root.crt").string(); + exec_log_path_ = path_manager_->GetLogPath().string(); + dll_log_path_ = path_manager_->GetLogPath().string(); + cache_path_ = path_manager_->GetCachePath().string(); + } + + InitializeLogger(); InitializeSettings(); InitializeSDL(); InitializeModules(); @@ -907,6 +924,14 @@ int Render::Run() { return 0; } +void Render::InitializeLogger() { + if (!exec_log_path_.empty()) { + InitLogger(exec_log_path_); + } else { + InitLogger("logs"); + } +} + void Render::InitializeSettings() { LoadSettingsFromCacheFile(); diff --git a/src/single_window/render.h b/src/single_window/render.h index 898b017..c36f528 100644 --- a/src/single_window/render.h +++ b/src/single_window/render.h @@ -25,6 +25,7 @@ #include "imgui_impl_sdlrenderer2.h" #include "imgui_internal.h" #include "minirtc.h" +#include "path_manager.h" #include "screen_capturer_factory.h" #include "speaker_capturer_factory.h" #include "thumbnail.h" @@ -118,6 +119,7 @@ class Render { int Run(); private: + void InitializeLogger(); void InitializeSettings(); void InitializeSDL(); void InitializeModules(); @@ -254,10 +256,15 @@ class Render { ConfigCenter config_center_; ConfigCenter::LANGUAGE localization_language_ = ConfigCenter::LANGUAGE::CHINESE; + std::unique_ptr path_manager_; + std::string cert_path_; + std::string exec_log_path_; + std::string dll_log_path_; + std::string cache_path_; + std::string imgui_cache_path_; int localization_language_index_ = -1; int localization_language_index_last_ = -1; bool modules_inited_ = false; - /* ------ all windows property start ------ */ float title_bar_width_ = 640; float title_bar_height_ = 30; diff --git a/src/single_window/thumbnail.cpp b/src/single_window/thumbnail.cpp index 99f8055..a46314b 100644 --- a/src/single_window/thumbnail.cpp +++ b/src/single_window/thumbnail.cpp @@ -127,16 +127,25 @@ void ScaleNv12ToABGR(char* src, int src_w, int src_h, int dst_w, int dst_h, } } -Thumbnail::Thumbnail() { +Thumbnail::Thumbnail(std::string save_path) { + if (!save_path.empty()) { + save_path_ = save_path; + } + RAND_bytes(aes128_key_, sizeof(aes128_key_)); RAND_bytes(aes128_iv_, sizeof(aes128_iv_)); - std::filesystem::create_directory(image_path_); + std::filesystem::create_directory(save_path_); } -Thumbnail::Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv) { +Thumbnail::Thumbnail(std::string save_path, unsigned char* aes128_key, + unsigned char* aes128_iv) { + if (!save_path.empty()) { + save_path_ = save_path; + } + memcpy(aes128_key_, aes128_key, sizeof(aes128_key_)); memcpy(aes128_iv_, aes128_iv, sizeof(aes128_iv_)); - std::filesystem::create_directory(image_path_); + std::filesystem::create_directory(save_path_); } Thumbnail::~Thumbnail() { @@ -177,7 +186,7 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height, std::string cipher_password = AES_encrypt(password, aes128_key_, aes128_iv_); image_file_name = remote_id + 'Y' + host_name + '@' + cipher_password; - std::string file_path = image_path_ + image_file_name; + std::string file_path = save_path_ + image_file_name; stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4, rgba_buffer_, thumbnail_width_ * 4); @@ -197,14 +206,14 @@ int Thumbnail::LoadThumbnail( recent_connections.clear(); std::vector image_paths = - FindThumbnailPath(image_path_); + FindThumbnailPath(save_path_); if (image_paths.size() == 0) { return -1; } else { for (int i = 0; i < image_paths.size(); i++) { size_t pos1 = image_paths[i].string().find('/') + 1; - std::string cipher_image_name = image_paths[i].string().substr(pos1); + std::string cipher_image_name = image_paths[i].filename().string(); std::string remote_id; std::string cipher_password; std::string remote_host_name; @@ -245,7 +254,7 @@ int Thumbnail::LoadThumbnail( AES_decrypt(cipher_password, aes128_key_, aes128_iv_); } - std::string image_path = image_path_ + cipher_image_name; + std::string image_path = save_path_ + cipher_image_name; recent_connections[original_image_name].texture = nullptr; LoadTextureFromFile(image_path.c_str(), renderer, &(recent_connections[original_image_name].texture), @@ -257,7 +266,7 @@ int Thumbnail::LoadThumbnail( } int Thumbnail::DeleteThumbnail(const std::string& filename_keyword) { - for (const auto& entry : std::filesystem::directory_iterator(image_path_)) { + for (const auto& entry : std::filesystem::directory_iterator(save_path_)) { if (entry.is_regular_file()) { const std::string filename = entry.path().filename().string(); std::string id_hostname = filename_keyword.substr(0, filename.find('@')); @@ -295,9 +304,9 @@ std::vector Thumbnail::FindThumbnailPath( } int Thumbnail::DeleteAllFilesInDirectory() { - if (std::filesystem::exists(image_path_) && - std::filesystem::is_directory(image_path_)) { - for (const auto& entry : std::filesystem::directory_iterator(image_path_)) { + if (std::filesystem::exists(save_path_) && + std::filesystem::is_directory(save_path_)) { + for (const auto& entry : std::filesystem::directory_iterator(save_path_)) { if (std::filesystem::is_regular_file(entry.status())) { std::filesystem::remove(entry.path()); } diff --git a/src/single_window/thumbnail.h b/src/single_window/thumbnail.h index 431a087..edb4983 100644 --- a/src/single_window/thumbnail.h +++ b/src/single_window/thumbnail.h @@ -25,8 +25,9 @@ class Thumbnail { }; public: - Thumbnail(); - explicit Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv); + Thumbnail(std::string save_path); + explicit Thumbnail(std::string save_path, unsigned char* aes128_key, + unsigned char* aes128_iv); ~Thumbnail(); public: @@ -74,7 +75,7 @@ class Thumbnail { int thumbnail_width_ = 160; int thumbnail_height_ = 90; char* rgba_buffer_ = nullptr; - std::string image_path_ = "thumbnails/"; + std::string save_path_ = "thumbnails/"; unsigned char aes128_key_[16]; unsigned char aes128_iv_[16]; diff --git a/thirdparty/minirtc b/thirdparty/minirtc index 74c8e10..1b84440 160000 --- a/thirdparty/minirtc +++ b/thirdparty/minirtc @@ -1 +1 @@ -Subproject commit 74c8e1062af9e7998b14cd43049a415abbef2c26 +Subproject commit 1b84440745963ff465b95e1f20310bc3235d8e4c