tmp commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
ecf8c2664c
commit
b9b2f76ae0
@ -1,13 +1,8 @@
|
|||||||
use super::cstr_to_string;
|
use super::cstr_to_string;
|
||||||
use crate::flutter::{self, APP_TYPE_CM, APP_TYPE_MAIN, SESSIONS};
|
use crate::flutter::{self, APP_TYPE_CM, APP_TYPE_MAIN, SESSIONS};
|
||||||
use hbb_common::{lazy_static, libc, log, message_proto::Plugin, ResultType};
|
use hbb_common::{lazy_static, log, message_proto::Plugin};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::{
|
use std::{collections::HashMap, ffi::c_char, sync::Arc};
|
||||||
collections::HashMap,
|
|
||||||
ffi::{c_char, CStr},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
const MSG_TO_PEER_TARGET: &str = "peer";
|
const MSG_TO_PEER_TARGET: &str = "peer";
|
||||||
const MSG_TO_UI_TARGET: &str = "ui";
|
const MSG_TO_UI_TARGET: &str = "ui";
|
||||||
@ -85,7 +80,7 @@ pub fn callback_msg(
|
|||||||
let content = std::string::String::from_utf8(content_slice[2..].to_vec())
|
let content = std::string::String::from_utf8(content_slice[2..].to_vec())
|
||||||
.unwrap_or("".to_string());
|
.unwrap_or("".to_string());
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert("name", "plugin");
|
m.insert("name", "plugin_event");
|
||||||
m.insert("peer", &peer);
|
m.insert("peer", &peer);
|
||||||
m.insert("content", &content);
|
m.insert("content", &content);
|
||||||
let event = serde_json::to_string(&m).unwrap_or("".to_string());
|
let event = serde_json::to_string(&m).unwrap_or("".to_string());
|
||||||
@ -99,7 +94,7 @@ pub fn callback_msg(
|
|||||||
|| channel & MSG_TO_UI_FLUTTER_CHANNEL_FORWARD != 0
|
|| channel & MSG_TO_UI_FLUTTER_CHANNEL_FORWARD != 0
|
||||||
{
|
{
|
||||||
let _res = flutter::push_session_event(
|
let _res = flutter::push_session_event(
|
||||||
APP_TYPE_CM,
|
&peer,
|
||||||
"plugin",
|
"plugin",
|
||||||
vec![("peer", &peer), ("content", &content)],
|
vec![("peer", &peer), ("content", &content)],
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
use super::desc::ConfigItem;
|
||||||
|
use hbb_common::{bail, config::Config as HbbConfig, lazy_static, ResultType};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
{collections::HashMap, path::PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref CONFIG_LOCAL: Arc<Mutex<HashMap<String, LocalConfig>>> = Default::default();
|
||||||
|
static ref CONFIG_LOCAL_ITEMS: Arc<Mutex<HashMap<String, Vec<ConfigItem>>>> = Default::default();
|
||||||
|
static ref CONFIG_PEERS: Arc<Mutex<HashMap<String, PeersConfig>>> = Default::default();
|
||||||
|
static ref CONFIG_PEER_ITEMS: Arc<Mutex<HashMap<String, Vec<ConfigItem>>>> = Default::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
|
struct LocalConfig(HashMap<String, String>);
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
|
struct PeerConfig(HashMap<String, String>);
|
||||||
|
type PeersConfig = HashMap<String, PeerConfig>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn path_plugins(id: &str) -> PathBuf {
|
||||||
|
HbbConfig::path("plugins").join(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for LocalConfig {
|
||||||
|
type Target = HashMap<String, String>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for LocalConfig {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for PeerConfig {
|
||||||
|
type Target = HashMap<String, String>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for PeerConfig {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalConfig {
|
||||||
|
#[inline]
|
||||||
|
fn path(id: &str) -> PathBuf {
|
||||||
|
path_plugins(id).join("local.toml")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn load(id: &str) {
|
||||||
|
let mut conf = hbb_common::config::load_path::<LocalConfig>(Self::path(id));
|
||||||
|
if let Some(items) = CONFIG_LOCAL_ITEMS.lock().unwrap().get(id) {
|
||||||
|
for item in items {
|
||||||
|
if !conf.contains_key(&item.key) {
|
||||||
|
conf.insert(item.key.to_owned(), item.default.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CONFIG_LOCAL.lock().unwrap().insert(id.to_owned(), conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn save(id: &str) -> ResultType<()> {
|
||||||
|
match CONFIG_LOCAL.lock().unwrap().get(id) {
|
||||||
|
Some(config) => hbb_common::config::store_path(Self::path(id), config),
|
||||||
|
None => bail!("No such plugin {}", id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get(id: &str, key: &str) -> Option<String> {
|
||||||
|
if let Some(conf) = CONFIG_LOCAL.lock().unwrap().get(id) {
|
||||||
|
return conf.get(key).map(|s| s.to_owned());
|
||||||
|
}
|
||||||
|
Self::load(id);
|
||||||
|
CONFIG_LOCAL
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get(id)?
|
||||||
|
.get(key)
|
||||||
|
.map(|s| s.to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set(id: &str, key: &str, value: &str) -> ResultType<()> {
|
||||||
|
match CONFIG_LOCAL.lock().unwrap().get_mut(id) {
|
||||||
|
Some(config) => {
|
||||||
|
config.insert(key.to_owned(), value.to_owned());
|
||||||
|
hbb_common::config::store_path(Self::path(id), config)
|
||||||
|
}
|
||||||
|
None => bail!("No such plugin {}", id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PeerConfig {
|
||||||
|
#[inline]
|
||||||
|
fn path(id: &str, peer: &str) -> PathBuf {
|
||||||
|
path_plugins(id)
|
||||||
|
.join("peers")
|
||||||
|
.join(format!("{}.toml", peer))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn load(id: &str, peer: &str) {
|
||||||
|
let mut conf = hbb_common::config::load_path::<PeerConfig>(Self::path(id, peer));
|
||||||
|
if let Some(items) = CONFIG_PEER_ITEMS.lock().unwrap().get(id) {
|
||||||
|
for item in items {
|
||||||
|
if !conf.contains_key(&item.key) {
|
||||||
|
conf.insert(item.key.to_owned(), item.default.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match CONFIG_PEERS.lock().unwrap().get_mut(id) {
|
||||||
|
Some(peers) => {
|
||||||
|
peers.insert(peer.to_owned(), conf);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut peers = HashMap::new();
|
||||||
|
peers.insert(peer.to_owned(), conf);
|
||||||
|
CONFIG_PEERS.lock().unwrap().insert(id.to_owned(), peers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn save(id: &str, peer: &str) -> ResultType<()> {
|
||||||
|
match CONFIG_PEERS.lock().unwrap().get(id) {
|
||||||
|
Some(peers) => match peers.get(peer) {
|
||||||
|
Some(config) => hbb_common::config::store_path(Self::path(id, peer), config),
|
||||||
|
None => bail!("No such peer {}", peer),
|
||||||
|
},
|
||||||
|
None => bail!("No such plugin {}", id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get(id: &str, peer: &str, key: &str) -> Option<String> {
|
||||||
|
if let Some(peers) = CONFIG_PEERS.lock().unwrap().get(id) {
|
||||||
|
if let Some(conf) = peers.get(peer) {
|
||||||
|
return conf.get(key).map(|s| s.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::load(id, peer);
|
||||||
|
CONFIG_PEERS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get(id)?
|
||||||
|
.get(peer)?
|
||||||
|
.get(key)
|
||||||
|
.map(|s| s.to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set(id: &str, peer: &str, key: &str, value: &str) -> ResultType<()> {
|
||||||
|
match CONFIG_PEERS.lock().unwrap().get_mut(id) {
|
||||||
|
Some(peers) => match peers.get_mut(peer) {
|
||||||
|
Some(config) => {
|
||||||
|
config.insert(key.to_owned(), value.to_owned());
|
||||||
|
hbb_common::config::store_path(Self::path(id, peer), config)
|
||||||
|
}
|
||||||
|
None => bail!("No such peer {}", peer),
|
||||||
|
},
|
||||||
|
None => bail!("No such plugin {}", id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn set_local_items(id: &str, items: &Vec<ConfigItem>) {
|
||||||
|
CONFIG_LOCAL_ITEMS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id.to_owned(), items.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn set_peer_items(id: &str, items: &Vec<ConfigItem>) {
|
||||||
|
CONFIG_PEER_ITEMS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id.to_owned(), items.clone());
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
use hbb_common::ResultType;
|
use hbb_common::ResultType;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::{c_char, CStr};
|
use std::ffi::{c_char, CStr};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct UiButton {
|
pub struct UiButton {
|
||||||
key: String,
|
key: String,
|
||||||
text: String,
|
text: String,
|
||||||
@ -13,7 +13,7 @@ pub struct UiButton {
|
|||||||
action: String, // The action to be triggered when the button is clicked.
|
action: String, // The action to be triggered when the button is clicked.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct UiCheckbox {
|
pub struct UiCheckbox {
|
||||||
key: String,
|
key: String,
|
||||||
text: String,
|
text: String,
|
||||||
@ -21,7 +21,7 @@ pub struct UiCheckbox {
|
|||||||
action: String, // The action to be triggered when the checkbox is checked or unchecked.
|
action: String, // The action to be triggered when the checkbox is checked or unchecked.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(tag = "t", content = "c")]
|
#[serde(tag = "t", content = "c")]
|
||||||
pub enum UiType {
|
pub enum UiType {
|
||||||
Button(UiButton),
|
Button(UiButton),
|
||||||
@ -30,28 +30,21 @@ pub enum UiType {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
core: String,
|
pub ui: HashMap<String, UiType>,
|
||||||
ui: HashMap<String, UiType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct ConfigItem {
|
pub struct ConfigItem {
|
||||||
key: String,
|
pub key: String,
|
||||||
value: String,
|
pub value: String,
|
||||||
default: String,
|
pub default: String,
|
||||||
description: String,
|
pub description: String,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct Configs {
|
|
||||||
pub local: Vec<ConfigItem>,
|
|
||||||
pub session: Vec<ConfigItem>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub host: Configs,
|
pub local: Vec<ConfigItem>,
|
||||||
pub client: Configs,
|
pub peer: Vec<ConfigItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use hbb_common::{dlopen::symbor::Library, log, ResultType};
|
use hbb_common::ResultType;
|
||||||
use std::{
|
use std::ffi::{c_char, CStr};
|
||||||
ffi::{c_char, CStr},
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod callback_msg;
|
mod callback_msg;
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::{c_char, CStr},
|
ffi::c_char,
|
||||||
path::PathBuf,
|
path::Path,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{callback_msg, desc::Desc};
|
use super::{callback_msg, desc::Desc};
|
||||||
use hbb_common::{
|
use crate::flutter;
|
||||||
anyhow::Error,
|
use hbb_common::{bail, dlopen::symbor::Library, lazy_static, libc, log, ResultType};
|
||||||
bail,
|
|
||||||
dlopen::symbor::Library,
|
|
||||||
lazy_static, libc, log,
|
|
||||||
log::{debug, error},
|
|
||||||
ResultType,
|
|
||||||
};
|
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref PLUGINS: Arc<RwLock<HashMap<String, Plugin>>> = Default::default();
|
pub static ref PLUGINS: Arc<RwLock<HashMap<String, Plugin>>> = Default::default();
|
||||||
@ -109,7 +103,7 @@ make_plugin!(
|
|||||||
fn_call: PluginFuncCall
|
fn_call: PluginFuncCall
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn load_plugins(dir: &str) -> ResultType<()> {
|
pub fn load_plugins<P: AsRef<Path>>(dir: P) -> ResultType<()> {
|
||||||
for entry in std::fs::read_dir(dir)? {
|
for entry in std::fs::read_dir(dir)? {
|
||||||
match entry {
|
match entry {
|
||||||
Ok(entry) => {
|
Ok(entry) => {
|
||||||
@ -156,7 +150,39 @@ fn load_plugin(path: &str) -> ResultType<()> {
|
|||||||
let desc = desc_res?;
|
let desc = desc_res?;
|
||||||
let id = desc.id().to_string();
|
let id = desc.id().to_string();
|
||||||
(plugin.fn_set_cb_msg)(callback_msg::callback_msg);
|
(plugin.fn_set_cb_msg)(callback_msg::callback_msg);
|
||||||
|
update_config(&desc);
|
||||||
|
reload_ui(&desc);
|
||||||
plugin.desc = Some(desc);
|
plugin.desc = Some(desc);
|
||||||
PLUGINS.write().unwrap().insert(id, plugin);
|
PLUGINS.write().unwrap().insert(id, plugin);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_config(desc: &Desc) {
|
||||||
|
super::config::set_local_items(desc.id(), &desc.config().local);
|
||||||
|
super::config::set_peer_items(desc.id(), &desc.config().peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reload_ui(desc: &Desc) {
|
||||||
|
for (location, ui) in desc.location().ui.iter() {
|
||||||
|
let v: Vec<&str> = location.split('|').collect();
|
||||||
|
// The first element is the "client" or "host".
|
||||||
|
// The second element is the "main", "remote", "cm", "file transfer", "port forward".
|
||||||
|
if v.len() >= 2 {
|
||||||
|
let available_channels = vec![
|
||||||
|
flutter::APP_TYPE_MAIN,
|
||||||
|
flutter::APP_TYPE_DESKTOP_REMOTE,
|
||||||
|
flutter::APP_TYPE_CM,
|
||||||
|
flutter::APP_TYPE_DESKTOP_FILE_TRANSFER,
|
||||||
|
flutter::APP_TYPE_DESKTOP_PORT_FORWARD,
|
||||||
|
];
|
||||||
|
if available_channels.contains(&v[1]) {
|
||||||
|
if let Ok(ui) = serde_json::to_string(&ui) {
|
||||||
|
let mut m = HashMap::new();
|
||||||
|
m.insert("name", "plugin_reload");
|
||||||
|
m.insert("ui", &ui);
|
||||||
|
flutter::push_global_event(v[1], serde_json::to_string(&m).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user