From 0a1014ddededc02659a904429055a8905aa1baaa Mon Sep 17 00:00:00 2001 From: dijunkun Date: Thu, 15 May 2025 17:52:40 +0800 Subject: [PATCH] [fix] use serialize and deserialize function to process RemoteAction::HostInfo --- .../windows/screen_capturer_wgc.cpp | 2 +- src/single_window/render.cpp | 83 ++++++++++++++++++- src/single_window/render.h | 9 +- src/single_window/render_callback_func.cpp | 29 ++++--- 4 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/screen_capturer/windows/screen_capturer_wgc.cpp b/src/screen_capturer/windows/screen_capturer_wgc.cpp index 7da17a1..4c8c711 100644 --- a/src/screen_capturer/windows/screen_capturer_wgc.cpp +++ b/src/screen_capturer/windows/screen_capturer_wgc.cpp @@ -216,7 +216,7 @@ int ScreenCapturerWgc::Stop() { int ScreenCapturerWgc::SwitchTo(int monitor_index) { if (monitor_index_ == monitor_index) { - LOG_INFO("Already on monitor {}:{}", monitor_index_, + LOG_INFO("Already on monitor {}:{}", monitor_index_ + 1, display_info_list_[monitor_index_].name); return 0; } diff --git a/src/single_window/render.cpp b/src/single_window/render.cpp index 17b4cd4..e36f554 100644 --- a/src/single_window/render.cpp +++ b/src/single_window/render.cpp @@ -21,6 +21,77 @@ #define STREAM_FRASH (SDL_USEREVENT + 1) +std::vector Render::SerializeRemoteAction(const RemoteAction& action) { + std::vector buffer; + buffer.push_back(static_cast(action.type)); + if (action.type == ControlType::host_infomation) { + size_t name_len = action.i.host_name_size; + buffer.insert(buffer.end(), reinterpret_cast(&name_len), + reinterpret_cast(&name_len) + sizeof(size_t)); + buffer.insert(buffer.end(), action.i.host_name, + action.i.host_name + name_len); + size_t display_num = action.i.display_num; + buffer.insert(buffer.end(), reinterpret_cast(&display_num), + reinterpret_cast(&display_num) + sizeof(size_t)); + for (size_t i = 0; i < display_num; ++i) { + const char* name = action.i.display_list[i]; + size_t len = strlen(name); + buffer.insert(buffer.end(), reinterpret_cast(&len), + reinterpret_cast(&len) + sizeof(size_t)); + buffer.insert(buffer.end(), reinterpret_cast(name), + reinterpret_cast(name) + len); + } + } + return buffer; +} + +bool Render::DeserializeRemoteAction(const char* data, size_t size, + RemoteAction& out) { + size_t offset = 0; + if (size < 1) return false; + out.type = static_cast(data[offset]); + offset += 1; + if (out.type == ControlType::host_infomation) { + if (offset + sizeof(size_t) > size) return false; + size_t host_name_len = *reinterpret_cast(data + offset); + offset += sizeof(size_t); + if (offset + host_name_len > size || + host_name_len >= sizeof(out.i.host_name)) + return false; + memcpy(out.i.host_name, data + offset, host_name_len); + out.i.host_name[host_name_len] = '\0'; + out.i.host_name_size = host_name_len; + offset += host_name_len; + if (offset + sizeof(size_t) > size) return false; + size_t display_num = *reinterpret_cast(data + offset); + out.i.display_num = display_num; + offset += sizeof(size_t); + out.i.display_list = (char**)malloc(display_num * sizeof(char*)); + for (size_t i = 0; i < display_num; ++i) { + if (offset + sizeof(size_t) > size) return false; + size_t len = *reinterpret_cast(data + offset); + offset += sizeof(size_t); + if (offset + len > size) return false; + out.i.display_list[i] = (char*)malloc(len + 1); + memcpy(out.i.display_list[i], data + offset, len); + out.i.display_list[i][len] = '\0'; + offset += len; + } + } + return true; +} + +void Render::FreeRemoteAction(RemoteAction& action) { + if (action.type == ControlType::host_infomation) { + for (size_t i = 0; i < action.i.display_num; ++i) { + free(action.i.display_list[i]); + } + free(action.i.display_list); + action.i.display_list = nullptr; + action.i.display_num = 0; + } +} + SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, const SDL_Point* area, void* data) { Render* render = (Render*)data; @@ -841,7 +912,7 @@ void Render::MainLoop() { CreateConnection(peer_, client_id_, password_saved_) ? false : true; } - if (!host_info_sent_ && screen_width_ > 0 && screen_height_ > 0) { + if (need_to_send_host_info_) { RemoteAction remote_action; if (screen_capturer_) { display_info_list_ = screen_capturer_->GetDisplayInfoList(); @@ -864,11 +935,15 @@ void Render::MainLoop() { std::string host_name = GetHostName(); remote_action.type = ControlType::host_infomation; memcpy(&remote_action.i.host_name, host_name.data(), host_name.size()); + remote_action.i.host_name[host_name.size()] = '\0'; remote_action.i.host_name_size = host_name.size(); - int ret = SendDataFrame(peer_, (const char*)&remote_action, - sizeof(remote_action), data_label_.c_str()); + + std::vector serialized = SerializeRemoteAction(remote_action); + int ret = SendDataFrame(peer_, serialized.data(), serialized.size(), + data_label_.c_str()); + FreeRemoteAction(remote_action); if (0 == ret) { - host_info_sent_ = true; + need_to_send_host_info_ = false; } } } diff --git a/src/single_window/render.h b/src/single_window/render.h index 1ae3ef0..927f40a 100644 --- a/src/single_window/render.h +++ b/src/single_window/render.h @@ -192,6 +192,13 @@ class Render { static SDL_HitTestResult HitTestCallback(SDL_Window *window, const SDL_Point *area, void *data); + static std::vector SerializeRemoteAction(const RemoteAction &action); + + static bool DeserializeRemoteAction(const char *data, size_t size, + RemoteAction &out); + + static void FreeRemoteAction(RemoteAction &action); + private: int SendKeyCommand(int key_code, bool is_down); int ProcessMouseEvent(SDL_Event &event); @@ -320,7 +327,7 @@ class Render { bool need_to_rejoin_ = false; bool just_created_ = false; std::string controlled_remote_id_ = ""; - bool host_info_sent_ = false; + bool need_to_send_host_info_ = false; SDL_Event last_mouse_event; // stream window render diff --git a/src/single_window/render_callback_func.cpp b/src/single_window/render_callback_func.cpp index 00790fc..c06debe 100644 --- a/src/single_window/render_callback_func.cpp +++ b/src/single_window/render_callback_func.cpp @@ -285,18 +285,26 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, render->client_properties_.end()) { // local auto props = render->client_properties_.find(remote_id)->second; - if (ControlType::host_infomation == remote_action.type) { + RemoteAction host_info; + if (DeserializeRemoteAction(data, size, host_info)) { + if (ControlType::host_infomation == host_info.type) { + props->remote_host_name_ = + std::string(host_info.i.host_name, host_info.i.host_name_size); + LOG_INFO("Remote hostname: [{}]", props->remote_host_name_); + + for (int i = 0; i < host_info.i.display_num; i++) { + props->display_names_.push_back( + std::string(host_info.i.display_list[i])); + LOG_INFO("Remote display [{}:{}]", i + 1, props->display_names_[i]); + } + } + } else { props->remote_host_name_ = std::string(remote_action.i.host_name, remote_action.i.host_name_size); LOG_INFO("Remote hostname: [{}]", props->remote_host_name_); - - props->display_names_ = restore_display_list(remote_action.i.display_list, - remote_action.i.display_num); - - for (int i = 0; i < props->display_names_.size(); i++) { - LOG_INFO("Remote display [{}:{}]", i + 1, props->display_names_[i]); - } + LOG_ERROR("No remote display detected"); } + FreeRemoteAction(host_info); } else { // remote if (ControlType::mouse == remote_action.type && render->mouse_controller_) { @@ -409,7 +417,6 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, render->start_mouse_controller_ = false; render->start_keyboard_capturer_ = false; render->control_mouse_ = false; - render->host_info_sent_ = false; props->connection_established_ = false; props->mouse_control_button_pressed_ = false; if (props->dst_buffer_) { @@ -444,7 +451,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, switch (status) { case ConnectionStatus::Connected: - render->host_info_sent_ = false; + render->need_to_send_host_info_ = true; render->start_screen_capturer_ = true; render->start_mouse_controller_ = true; break; @@ -452,7 +459,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, render->start_screen_capturer_ = false; render->start_mouse_controller_ = false; render->start_keyboard_capturer_ = false; - render->host_info_sent_ = false; + render->need_to_send_host_info_ = false; if (props) props->connection_established_ = false; if (render->audio_capture_) { render->StopSpeakerCapturer();