diff --git a/src/cmd/package.rs b/src/cmd/package.rs index a66d2d6fb30947ee175f604d66f2ab1f2df07725..097e4a19ce9ca11bd77a7868ffd8cb1a499a4da4 100644 --- a/src/cmd/package.rs +++ b/src/cmd/package.rs @@ -16,6 +16,21 @@ pub struct CmdPackage { } impl CmdPackage { + #[allow(dead_code)] + pub fn has_command(&self, user_cmd: &Vec<String>) -> bool { + match user_cmd.split_first() { + None => false, + Some((name, args)) => match self + .commands + .iter() + .find(|x| x.matches(name, &args.to_vec())) + { + None => false, + Some(_) => true, + }, + } + } + #[allow(dead_code)] pub fn handle(&self, room: &JoinedRoom, user_id: &UserId, user_cmd: Vec<String>) -> String { match CmdAcl::action_permited(&self.admin_register, &self.acl, room, user_id) { diff --git a/src/main.rs b/src/main.rs index 6d6be28c79dc41dc6ea7fb24633546781932d427..607249d6448c8dd17b8d661721d288534db89942 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![feature(clone_closures)] +#![feature(new_uninit, once_cell)] mod cmd; mod config; diff --git a/src/matrix.rs b/src/matrix.rs index 84d27f19955cda13b56dcbded3703b84f63a49ad..030ccb621f248eacfe21326015017f7e22668e6f 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -10,13 +10,13 @@ use matrix_sdk::{ member::MemberEventContent, message::{MessageEventContent, MessageType, TextMessageEventContent}, }, - SyncMessageEvent, SyncStateEvent, + AnyMessageEventContent, SyncMessageEvent, SyncStateEvent, }, UserId, }, Client, Result, SyncSettings, }; -use std::{convert::TryFrom, process::abort, sync::Arc}; +use std::{convert::TryFrom, lazy::SyncLazy, process::abort, sync::Arc, sync::Mutex}; use tokio::time::{sleep, Duration}; async fn join_room(room: &Invited) { @@ -80,15 +80,14 @@ async fn startup_and_log_rooms(client: &Client) { join_all(list_to_wait_for).await; } +static GLOBAL_PKG: SyncLazy<Arc<Mutex<Vec<CmdPackage>>>> = + SyncLazy::new(|| Arc::new(Mutex::new(Vec::<CmdPackage>::new()))); + pub async fn connect_and_handle(config: Config) -> Result<()> { // TODO: Refactor let pkg_commands_vec = vec![ Cmd::new_simple(format!("ping"), 0, Arc::new(|_x| true)), - Cmd::new_echo( - format!("bot_name"), - 0, - Arc::new(move |_x| format!("toto")), - ), + Cmd::new_echo(format!("bot_name"), 0, Arc::new(move |_x| format!("toto"))), ]; let pkg = match config.section("basic") { Some(section) => CmdPackage::from_config(§ion, pkg_commands_vec), @@ -97,6 +96,59 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { } }; + GLOBAL_PKG.lock().unwrap().push(pkg); + + let on_msg_room_event = + move |ev: SyncMessageEvent<MessageEventContent>, + room: Room, + _encryption_info: Option<EncryptionInfo>| async move { + let sender_id = ev.sender; + if sender_id.as_str() == room.own_user_id().as_str() { + return; + } + + if room.name().is_none() { + warn!("Unsupported rooms without names"); + return; + } + + if let Room::Joined(joined) = room { + if let MessageType::Text(TextMessageEventContent { body, .. }) = ev.content.msgtype + { + if body.starts_with("%") { + let args = vec![]; + let mut res: String = format!("Command not found"); + if let Some(pkg) = GLOBAL_PKG + .lock() + .unwrap() + .iter() + .find(|x| x.has_command(&args)) + { + res = pkg.handle(&joined, &sender_id, args); + } + + joined + .send( + AnyMessageEventContent::RoomMessage( + MessageEventContent::text_plain(res), + ), + None, + ) + .await + .unwrap(); + } + } + } + + // if let Room::Invited(_) = room { + // warn!("Bot was invited by {sender_id} to room {room_id} a.k.a. {room_name}",); + // } + + // if let Room::Left(_) = room { + // error!("Bot left room {room_id} a.k.a. {room_name}") + // } + }; + let alice = UserId::try_from(config.user_name)?; let client = Client::new(config.homeserver_url)?; @@ -120,45 +172,7 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { warn!("Ignore state member events"); } - client - .register_event_handler( - move |ev: SyncMessageEvent<MessageEventContent>, - room: Room, - _encryption_info: Option<EncryptionInfo>| async { - let sender_id = ev.sender; - if sender_id.as_str() == room.own_user_id().as_str() { - return; - } - - if room.name().is_none() { - warn!("Unsupported rooms without names"); - return; - } - - if let Room::Joined(joined) = room { - let room_id = joined.room_id(); - let room_name = joined.name().unwrap(); - if let MessageType::Text(TextMessageEventContent { body, .. }) = - ev.content.msgtype - { - if body.starts_with("%") { - info!("Got message from {sender_id} in {room_id} a.k.a. {room_name}"); - let args = vec![]; - let locked_pkg = pkg.handle(&joined, &sender_id, args); - } - } - } - - // if let Room::Invited(_) = room { - // warn!("Bot was invited by {sender_id} to room {room_id} a.k.a. {room_name}",); - // } - - // if let Room::Left(_) = room { - // error!("Bot left room {room_id} a.k.a. {room_name}") - // } - }, - ) - .await; + client.register_event_handler(on_msg_room_event).await; info!("Entering sync loop"); let token = client.sync_token().await.unwrap();