mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
plugin_framework, test install plugin
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
@@ -1498,7 +1498,7 @@ pub fn plugin_reload(_id: String) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn plugin_enable(_id: String, _v: bool) {
|
||||
pub fn plugin_enable(_id: String, _v: bool) -> SyncReturn<()> {
|
||||
#[cfg(feature = "plugin_framework")]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
{
|
||||
@@ -1512,6 +1512,7 @@ pub fn plugin_enable(_id: String, _v: bool) {
|
||||
} else {
|
||||
crate::plugin::unload_plugin(&_id);
|
||||
}
|
||||
SyncReturn(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ pub enum UiType {
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Location {
|
||||
pub ui: HashMap<String, UiType>,
|
||||
pub ui: HashMap<String, Vec<UiType>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@@ -152,7 +152,7 @@ async fn set_manager_plugin_config_async(id: &str, name: &str, value: String) ->
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn load_plugin_async(id: &str) -> ResultType<()> {
|
||||
pub async fn load_plugin_async(id: &str) -> ResultType<()> {
|
||||
let mut c = connect(1000, "").await?;
|
||||
c.send(&Data::Plugin(Plugin::Load(id.to_owned()))).await?;
|
||||
Ok(())
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
use super::{desc::Meta as PluginMeta, ipc::InstallStatus, *};
|
||||
use crate::flutter;
|
||||
#[cfg(not(debug_assertions))]
|
||||
use hbb_common::toml;
|
||||
use hbb_common::{allow_err, bail, config::load_path, log, tokio};
|
||||
use hbb_common::{allow_err, bail, log, tokio, toml};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::{
|
||||
@@ -48,42 +46,15 @@ pub struct PluginInfo {
|
||||
|
||||
static PLUGIN_SOURCE_LOCAL: &str = "local";
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn get_plugin_source_list() -> Vec<PluginSource> {
|
||||
// Only one source for now.
|
||||
vec![PluginSource {
|
||||
name: "rustdesk".to_string(),
|
||||
url: "https://github.com/fufesou/rustdesk-plugins".to_string(),
|
||||
url: "https://raw.githubusercontent.com/fufesou/rustdesk-plugins/main".to_string(),
|
||||
description: "".to_string(),
|
||||
}]
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
fn get_source_plugins() -> HashMap<String, PluginInfo> {
|
||||
let meta_file = super::get_plugins_dir().unwrap().join("meta.toml");
|
||||
let mut plugins = HashMap::new();
|
||||
let manager_meta = load_path::<ManagerMeta>(meta_file);
|
||||
let source = PluginSource {
|
||||
name: "rustdesk".to_string(),
|
||||
url: "https://github.com/fufesou/rustdesk-plugins".to_string(),
|
||||
description: "".to_string(),
|
||||
};
|
||||
for meta in manager_meta.plugins.iter() {
|
||||
plugins.insert(
|
||||
meta.id.clone(),
|
||||
PluginInfo {
|
||||
source: source.clone(),
|
||||
meta: meta.clone(),
|
||||
installed_version: "".to_string(),
|
||||
install_time: "".to_string(),
|
||||
invalid_reason: "".to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
plugins
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn get_source_plugins() -> HashMap<String, PluginInfo> {
|
||||
let mut plugins = HashMap::new();
|
||||
for source in get_plugin_source_list().into_iter() {
|
||||
@@ -142,7 +113,8 @@ pub fn load_plugin_list() {
|
||||
for (id, info) in super::plugins::get_plugin_infos().read().unwrap().iter() {
|
||||
if let Some(p) = plugins.get_mut(id) {
|
||||
p.install_time = info.install_time.clone();
|
||||
p.invalid_reason = info.desc.meta().version.clone();
|
||||
p.installed_version = info.desc.meta().version.clone();
|
||||
p.invalid_reason = "".to_string();
|
||||
} else {
|
||||
plugins.insert(
|
||||
id.to_string(),
|
||||
@@ -171,9 +143,10 @@ pub fn install_plugin(id: &str) -> ResultType<()> {
|
||||
"{}/plugins/{}/{}_{}.zip",
|
||||
plugin.source.url, plugin.meta.id, plugin.meta.id, plugin.meta.version
|
||||
);
|
||||
// to-do: Support args with space in quotes. 'arg 1' and "arg 2"
|
||||
#[cfg(windows)]
|
||||
let _res =
|
||||
crate::platform::elevate(&format!("--plugin-install '{}' '{}'", id, _plugin_url))?;
|
||||
crate::platform::elevate(&format!("--plugin-install {} {}", id, _plugin_url))?;
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
@@ -223,7 +196,8 @@ async fn handle_conn(mut stream: crate::ipc::Connection) {
|
||||
}
|
||||
InstallStatus::Finished => {
|
||||
allow_err!(super::plugins::load_plugin(&id));
|
||||
allow_err!(super::ipc::load_plugin(id));
|
||||
allow_err!(super::ipc::load_plugin_async(id).await);
|
||||
load_plugin_list();
|
||||
push_install_event(&id, "finished");
|
||||
}
|
||||
InstallStatus::FailedCreating => {
|
||||
@@ -373,15 +347,31 @@ pub(super) mod install {
|
||||
}
|
||||
|
||||
let filename = plugin_dir.join(format!("{}.zip", id));
|
||||
|
||||
// download
|
||||
if !download_file(id, url, &filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
let filename_to_remove = filename.clone();
|
||||
let _call_on_ret = crate::common::SimpleCallOnReturn {
|
||||
b: true,
|
||||
f: Box::new(move || {
|
||||
if let Err(e) = std::fs::remove_file(&filename_to_remove) {
|
||||
log::error!("Failed to remove plugin file: {}", e);
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
// install
|
||||
send_install_status(id, InstallStatus::Installing);
|
||||
if let Err(e) = do_install_file(&filename, &plugin_dir) {
|
||||
log::error!("Failed to install plugin: {}", e);
|
||||
send_install_status(id, InstallStatus::FailedInstalling);
|
||||
return;
|
||||
}
|
||||
|
||||
// finished
|
||||
send_install_status(id, InstallStatus::Finished);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ pub use plugins::{
|
||||
reload_plugin, sync_ui, unload_plugin, unload_plugins,
|
||||
};
|
||||
|
||||
const MSG_TO_UI_TYPE_PLUGIN_DESC: &str = "plugin_desc";
|
||||
const MSG_TO_UI_TYPE_PLUGIN_EVENT: &str = "plugin_event";
|
||||
const MSG_TO_UI_TYPE_PLUGIN_RELOAD: &str = "plugin_reload";
|
||||
const MSG_TO_UI_TYPE_PLUGIN_OPTION: &str = "plugin_option";
|
||||
@@ -90,12 +89,12 @@ impl PluginReturn {
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
std::thread::spawn(move || manager::start_ipc());
|
||||
if is_server() {
|
||||
if !is_server() {
|
||||
std::thread::spawn(move || manager::start_ipc());
|
||||
} else {
|
||||
manager::remove_plugins();
|
||||
allow_err!(plugins::load_plugins());
|
||||
}
|
||||
load_plugin_list();
|
||||
allow_err!(plugins::load_plugins());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -134,10 +133,10 @@ fn str_to_cstr_ret(s: &str) -> *const c_char {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn free_c_ptr(ret: *mut c_void) {
|
||||
if !ret.is_null() {
|
||||
fn free_c_ptr(p: *mut c_void) {
|
||||
if !p.is_null() {
|
||||
unsafe {
|
||||
libc::free(ret);
|
||||
libc::free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ struct InitData {
|
||||
impl Drop for InitData {
|
||||
fn drop(&mut self) {
|
||||
free_c_ptr(self.version as _);
|
||||
free_c_ptr(self.info as _);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,18 +351,9 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
|
||||
let init_info = serde_json::to_string(&InitInfo {
|
||||
is_server: crate::common::is_server(),
|
||||
})?;
|
||||
let ptr_info = str_to_cstr_ret(&init_info);
|
||||
let ptr_version = str_to_cstr_ret(crate::VERSION);
|
||||
let _call_on_ret = crate::common::SimpleCallOnReturn {
|
||||
b: true,
|
||||
f: Box::new(move || {
|
||||
free_c_ptr(ptr_info as _);
|
||||
free_c_ptr(ptr_version as _);
|
||||
}),
|
||||
};
|
||||
let init_data = InitData {
|
||||
version: ptr_version as _,
|
||||
info: ptr_info as _,
|
||||
version: str_to_cstr_ret(crate::VERSION),
|
||||
info: str_to_cstr_ret(&init_info) as _,
|
||||
cbs: Callbacks {
|
||||
msg: callback_msg::cb_msg,
|
||||
get_conf: config::cb_get_conf,
|
||||
@@ -378,7 +370,6 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
|
||||
|
||||
// update ui
|
||||
// Ui may be not ready now, so we need to update again once ui is ready.
|
||||
update_ui_plugin_desc(&desc, None);
|
||||
reload_ui(&desc, None);
|
||||
|
||||
let install_time = PathBuf::from(path)
|
||||
@@ -404,7 +395,6 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
|
||||
|
||||
pub fn sync_ui(sync_to: String) {
|
||||
for plugin in PLUGIN_INFO.read().unwrap().values() {
|
||||
update_ui_plugin_desc(&plugin.desc, Some(&sync_to));
|
||||
reload_ui(&plugin.desc, Some(&sync_to));
|
||||
}
|
||||
}
|
||||
@@ -640,27 +630,6 @@ fn reload_ui(desc: &Desc, sync_to: Option<&str>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_ui_plugin_desc(desc: &Desc, sync_to: Option<&str>) {
|
||||
// This function is rarely used. There's no need to care about serialization efficiency here.
|
||||
if let Ok(desc_str) = serde_json::to_string(desc) {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("name", MSG_TO_UI_TYPE_PLUGIN_DESC);
|
||||
m.insert("desc", &desc_str);
|
||||
let event = serde_json::to_string(&m).unwrap_or("".to_owned());
|
||||
match sync_to {
|
||||
Some(channel) => {
|
||||
let _res = flutter::push_global_event(channel, event.clone());
|
||||
}
|
||||
None => {
|
||||
let _res = flutter::push_global_event(flutter::APP_TYPE_MAIN, event.clone());
|
||||
let _res =
|
||||
flutter::push_global_event(flutter::APP_TYPE_DESKTOP_REMOTE, event.clone());
|
||||
let _res = flutter::push_global_event(flutter::APP_TYPE_CM, event.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_plugin_infos() -> Arc<RwLock<HashMap<String, PluginInfo>>> {
|
||||
PLUGIN_INFO.clone()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user