Merge pull request #4386 from fufesou/feat/plugin_framework

Feat/plugin framework
This commit is contained in:
RustDesk
2023-05-16 15:26:04 +08:00
committed by GitHub
Unverified
4 changed files with 210 additions and 33 deletions

View File

@@ -17,6 +17,8 @@ use std::{
sync::{Arc, RwLock},
};
pub const METHOD_HANDLE_STATUS: &[u8; 14] = b"handle_status\0";
pub const METHOD_HANDLE_SIGNATURE_VERIFICATION: &[u8; 30] = b"handle_signature_verification\0";
const METHOD_HANDLE_UI: &[u8; 10] = b"handle_ui\0";
const METHOD_HANDLE_PEER: &[u8; 12] = b"handle_peer\0";
pub const METHOD_HANDLE_LISTEN_EVENT: &[u8; 20] = b"handle_listen_event\0";
@@ -93,19 +95,21 @@ type CallbackNative = extern "C" fn(
raw: *const c_void,
raw_len: usize,
) -> super::native::NativeReturnValue;
/// The main function of the plugin on the client(self) side.
/// The main function of the plugin.
///
/// method: The method. "handle_ui" or "handle_peer"
/// peer: The peer id.
/// args: The arguments.
/// len: The length of the arguments.
type PluginFuncClientCall = extern "C" fn(
type PluginFuncCall = extern "C" fn(
method: *const c_char,
peer: *const c_char,
args: *const c_void,
len: usize,
) -> PluginReturn;
/// The main function of the plugin on the server(remote) side.
/// The main function of the plugin.
/// This function is called mainly for handling messages from the peer,
/// and then send messages back to the peer.
///
/// method: The method. "handle_ui" or "handle_peer"
/// peer: The peer id.
@@ -114,7 +118,7 @@ type PluginFuncClientCall = extern "C" fn(
/// out: The output.
/// The plugin allocate memory with `libc::malloc` and return the pointer.
/// out_len: The length of the output.
type PluginFuncServerCall = extern "C" fn(
type PluginFuncCallWithOutData = extern "C" fn(
method: *const c_char,
peer: *const c_char,
args: *const c_void,
@@ -138,6 +142,7 @@ struct Callbacks {
}
#[derive(Serialize)]
#[repr(C)]
struct InitInfo {
is_server: bool,
}
@@ -247,8 +252,8 @@ make_plugin!(
reset: PluginFuncReset,
clear: PluginFuncClear,
desc: PluginFuncDesc,
client_call: PluginFuncClientCall,
server_call: PluginFuncServerCall
call: PluginFuncCall,
call_with_out_data: PluginFuncCallWithOutData
);
#[derive(Serialize)]
@@ -295,6 +300,7 @@ pub(super) fn load_plugins(uninstalled_ids: &HashSet<String>) -> ResultType<()>
}
fn load_plugin_dir(dir: &PathBuf) {
log::debug!("Begin load plugin dir: {}", dir.display());
if let Ok(rd) = std::fs::read_dir(dir) {
for entry in rd {
match entry {
@@ -348,6 +354,8 @@ pub fn reload_plugin(id: &str) -> ResultType<()> {
}
fn load_plugin_path(path: &str) -> ResultType<()> {
log::info!("Begin load plugin {}", path);
let plugin = Plugin::new(path)?;
let desc = plugin.desc()?;
@@ -392,7 +400,7 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
// add plugins
PLUGINS.write().unwrap().insert(id.clone(), plugin);
log::info!("Plugin {} loaded", id);
log::info!("Plugin {} loaded, {}", id, path);
Ok(())
}
@@ -408,30 +416,43 @@ pub fn load_plugin(id: &str) -> ResultType<()> {
Ok(())
}
#[inline]
fn handle_event(method: &[u8], id: &str, peer: &str, event: &[u8]) -> ResultType<()> {
let mut peer: String = peer.to_owned();
peer.push('\0');
plugin_call(id, method, &peer, event)
}
pub fn plugin_call(id: &str, method: &[u8], peer: &str, event: &[u8]) -> ResultType<()> {
let mut ret = plugin_call_get_return(id, method, peer, event)?;
if ret.is_success() {
Ok(())
} else {
let (code, msg) = ret.get_code_msg();
bail!(
"Failed to handle plugin event, id: {}, method: {}, code: {}, msg: {}",
id,
std::string::String::from_utf8(method.to_vec()).unwrap_or_default(),
code,
msg
);
}
}
#[inline]
pub fn plugin_call_get_return(
id: &str,
method: &[u8],
peer: &str,
event: &[u8],
) -> ResultType<PluginReturn> {
match PLUGINS.read().unwrap().get(id) {
Some(plugin) => {
let mut ret = (plugin.client_call)(
method.as_ptr() as _,
peer.as_ptr() as _,
event.as_ptr() as _,
event.len(),
);
if ret.is_success() {
Ok(())
} else {
let (code, msg) = ret.get_code_msg();
bail!(
"Failed to handle plugin event, id: {}, method: {}, code: {}, msg: {}",
id,
std::string::String::from_utf8(method.to_vec()).unwrap_or_default(),
code,
msg
);
}
}
Some(plugin) => Ok((plugin.call)(
method.as_ptr() as _,
peer.as_ptr() as _,
event.as_ptr() as _,
event.len(),
)),
None => bail!("Plugin {} not found", id),
}
}
@@ -468,7 +489,7 @@ fn _handle_listen_event(event: String, peer: String) {
for id in plugins {
match PLUGINS.read().unwrap().get(&id) {
Some(plugin) => {
let mut ret = (plugin.client_call)(
let mut ret = (plugin.call)(
METHOD_HANDLE_LISTEN_EVENT.as_ptr() as _,
peer.as_ptr() as _,
evt_bytes.as_ptr() as _,
@@ -506,7 +527,7 @@ pub fn handle_client_event(id: &str, peer: &str, event: &[u8]) -> Message {
Some(plugin) => {
let mut out = std::ptr::null_mut();
let mut out_len: usize = 0;
let mut ret = (plugin.server_call)(
let mut ret = (plugin.call_with_out_data)(
METHOD_HANDLE_PEER.as_ptr() as _,
peer.as_ptr() as _,
event.as_ptr() as _,