diff --git a/Cargo.lock b/Cargo.lock index cb04a91..633ca70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,7 +499,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -542,6 +561,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -549,7 +579,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -575,9 +628,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.25", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -589,6 +642,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.3", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -596,12 +669,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.28", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -638,6 +747,7 @@ dependencies = [ "hex", "md-5", "pyo3", + "reqwest 0.12.2", "rust_socketio", "serde", "serde_json", @@ -935,6 +1045,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1118,11 +1248,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.3.25", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -1149,6 +1279,48 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.3", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.2.0", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rust_engineio" version = "0.4.4" @@ -1160,9 +1332,9 @@ dependencies = [ "base64 0.21.7", "bytes", "futures-util", - "http", + "http 0.2.12", "native-tls", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -1657,6 +1829,28 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -1669,6 +1863,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1736,7 +1931,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "native-tls", diff --git a/ica-rs/Cargo.toml b/ica-rs/Cargo.toml index f263ac3..e7ada63 100644 --- a/ica-rs/Cargo.toml +++ b/ica-rs/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [features] default = ["ica", "tailchat"] ica = ["dep:ed25519", "dep:ed25519-dalek", "dep:hex", "dep:rust_socketio"] -tailchat = ["dep:rust_socketio", "dep:md-5"] +tailchat = ["dep:rust_socketio", "dep:md-5", "dep:reqwest"] [dependencies] @@ -18,6 +18,7 @@ ed25519-dalek = { version = "2.1", optional = true } hex = { version = "0.4", optional = true } # tailchat +reqwest = { version = "0.12.2", optional = true } md-5 = { version = "0.10.6", optional = true } # ica & tailchat (socketio) diff --git a/ica-rs/src/error.rs b/ica-rs/src/error.rs index f1bf26f..e87225b 100644 --- a/ica-rs/src/error.rs +++ b/ica-rs/src/error.rs @@ -4,6 +4,16 @@ pub type ClientResult = Result; pub enum IcaError { /// Socket IO 链接错误 SocketIoError(rust_socketio::error::Error), + /// 登录失败 + LoginFailed(String), +} + +#[derive(Debug)] +pub enum TailchatError { + /// Socket IO 链接错误 + SocketIoError(rust_socketio::error::Error), + /// 登录失败 + LoginFailed(String), } #[derive(Debug)] @@ -29,6 +39,16 @@ impl std::fmt::Display for IcaError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { IcaError::SocketIoError(e) => write!(f, "Socket IO 链接错误: {}", e), + IcaError::LoginFailed(e) => write!(f, "登录失败: {}", e), + } + } +} + +impl std::fmt::Display for TailchatError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TailchatError::SocketIoError(e) => write!(f, "Socket IO 链接错误: {}", e), + TailchatError::LoginFailed(e) => write!(f, "登录失败: {}", e), } } } @@ -56,6 +76,16 @@ impl std::error::Error for IcaError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { IcaError::SocketIoError(e) => Some(e), + IcaError::LoginFailed(_) => None, + } + } +} + +impl std::error::Error for TailchatError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + TailchatError::SocketIoError(e) => Some(e), + TailchatError::LoginFailed(_) => None, } } } @@ -66,7 +96,7 @@ impl std::error::Error for PyPluginError { PyPluginError::FuncNotFound(_, _) => None, PyPluginError::CouldNotGetFunc(e, _, _) => Some(e), PyPluginError::FuncNotCallable(_, _) => None, - PyPluginError::FuncCallError(_, _) => None, + PyPluginError::FuncCallError(e, _, _) => Some(e), } } } diff --git a/ica-rs/src/ica/client.rs b/ica-rs/src/ica/client.rs index 09f4877..f7ab959 100644 --- a/ica-rs/src/ica/client.rs +++ b/ica-rs/src/ica/client.rs @@ -1,4 +1,5 @@ use crate::data_struct::ica::messages::{DeleteMessage, SendMessage}; +use crate::error::{ClientResult, IcaError}; use crate::MainStatus; use colored::Colorize; @@ -43,24 +44,24 @@ pub async fn delete_message(client: &Client, message: &DeleteMessage) -> bool { // #[allow(dead_code)] // pub async fn fetch_history(client: &Client, roomd_id: RoomId) -> bool { false } -pub async fn sign_callback(payload: Payload, client: Client) { +async fn inner_sign(payload: Payload, client: Client) -> ClientResult<(), IcaError> { let span = span!(Level::INFO, "signing icalingua"); let _guard = span.enter(); // 获取数据 let require_data = match payload { - Payload::Text(json_value) => Some(json_value), - _ => None, - } - .expect("Payload should be Json data"); + Payload::Text(json_value) => Ok(json_value), + _ => Err(IcaError::LoginFailed("Got a invalid payload".to_string())), + }?; let (auth_key, version) = (&require_data[0], &require_data[1]); + debug!("auth_key: {:?}, server_version: {:?}", auth_key, version); + let auth_key = match &require_data.first() { - Some(Value::String(auth_key)) => Some(auth_key), - _ => None, - } - .expect("auth_key should be string"); + Some(Value::String(auth_key)) => Ok(auth_key), + _ => Err(IcaError::LoginFailed("Got a invalid auth_key".to_string())), + }?; let salt = hex::decode(auth_key).expect("Got an invalid salt from the server"); // 签名 @@ -76,4 +77,11 @@ pub async fn sign_callback(payload: Payload, client: Client) { // 发送签名 let sign = signature.to_bytes().to_vec(); client.emit("auth", sign).await.expect("Faild to send signin data"); + Ok(()) +} + +/// 签名回调 +/// 失败的时候得 panic +pub async fn sign_callback(payload: Payload, client: Client) { + inner_sign(payload, client).await.expect("Faild to sign"); } diff --git a/ica-rs/src/py/call.rs b/ica-rs/src/py/call.rs index d484197..fc4dbb3 100644 --- a/ica-rs/src/py/call.rs +++ b/ica-rs/src/py/call.rs @@ -95,13 +95,19 @@ pub const ICA_DELETE_MESSAGE_FUNC: &str = "on_ica_delete_message"; pub const TAILCHAT_NEW_MESSAGE_FUNC: &str = "on_tailchat_message"; +macro_rules! call_py_func { + ($args:expr, $func_name:expr, $client:expr) => { + + }; +} + /// 执行 new message 的 python 插件 pub async fn ica_new_message_py(message: &ica::messages::NewMessage, client: &Client) { // 验证插件是否改变 verify_plugins(); let plugins = PyStatus::get_files(); - for (_path, plugin) in plugins.iter() { + for (path, plugin) in plugins.iter() { let msg = class::ica::NewMessagePy::new(message); let client = class::ica::IcaClientPy::new(client); let args = (msg, client); @@ -110,8 +116,12 @@ pub async fn ica_new_message_py(message: &ica::messages::NewMessage, client: &Cl Python::with_gil(|py| { if let Ok(py_func) = get_func(plugin.py_module.bind(py), ICA_NEW_MESSAGE_FUNC) { if let Err(e) = py_func.call1(args) { - let e = PyPluginError::FuncCallError(e, ICA_NEW_MESSAGE_FUNC.to_string()); - // warn!("failed to call function<{}>: {:?}", ICA_NEW_MESSAGE_FUNC, e); + let e = PyPluginError::FuncCallError( + e, + ICA_NEW_MESSAGE_FUNC.to_string(), + path.to_string_lossy().to_string(), + ); + warn!("failed to call function<{}>: {:?}", ICA_NEW_MESSAGE_FUNC, e); } } }) @@ -123,7 +133,7 @@ pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) { verify_plugins(); let plugins = PyStatus::get_files(); - for (_path, plugin) in plugins.iter() { + for (path, plugin) in plugins.iter() { let msg_id = msg_id.clone(); let client = class::ica::IcaClientPy::new(client); let args = (msg_id.clone(), client); @@ -131,6 +141,11 @@ pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) { Python::with_gil(|py| { if let Ok(py_func) = get_func(plugin.py_module.bind(py), ICA_DELETE_MESSAGE_FUNC) { if let Err(e) = py_func.call1(args) { + let e = PyPluginError::FuncCallError( + e, + ICA_DELETE_MESSAGE_FUNC.to_string(), + path.to_string_lossy().to_string(), + ); warn!("failed to call function<{}>: {:?}", ICA_DELETE_MESSAGE_FUNC, e); } } @@ -139,4 +154,6 @@ pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) { } } -// pub async fn tailchat_new_message_py(message: ) +pub async fn tailchat_new_message_py(message: tailchat::messages::ReciveMessage, client: &Client) { + +} diff --git a/ica-rs/src/tailchat.rs b/ica-rs/src/tailchat.rs index 8b13789..239581e 100644 --- a/ica-rs/src/tailchat.rs +++ b/ica-rs/src/tailchat.rs @@ -1 +1,23 @@ +pub mod events; + +use futures_util::FutureExt; +use rust_socketio::asynchronous::{Client, ClientBuilder}; +use rust_socketio::{Event, Payload, TransportType}; +use tracing::{event, span, Level}; + +// use crate::config::IcaConfig; +use crate::error::{ClientResult, TailchatError}; + +pub async fn start_tailchat() -> ClientResult<(), TailchatError> { + let span = span!(Level::INFO, "Tailchat Client"); + let _enter = span.enter(); + + event!(Level::INFO, "tailchat-async-rs v{} initing", crate::TAILCHAT_VERSION); + + // let socket = match ClientBuilder::new() { + + // }; + + Ok(()) +} diff --git a/ica-rs/src/tailchat/events.rs b/ica-rs/src/tailchat/events.rs new file mode 100644 index 0000000..e69de29