From 4e9316ad49576c820564e03b1f479b6c8f73f89c Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:56:30 -0400 Subject: [PATCH] (init) experiment test module --- src/core/bot_actions.rs | 53 ++++- src/core/botmodules.rs | 89 +++++++- src/core/chat.rs | 6 +- src/custom/experimental.rs | 2 + src/custom/experimental/experiment003.rs | 277 +++++++++++++++++++++++ 5 files changed, 413 insertions(+), 14 deletions(-) create mode 100644 src/custom/experimental/experiment003.rs diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 8941654..8b88c2a 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -5,7 +5,7 @@ use tokio::sync::RwLock; use crate::core::botinstance::BotInstance; -use super::{botmodules::{BotAction, BotModule}, identity::ChatBadge}; +use super::{botinstance::Channel, botmodules::{BotAction, BotModule}, identity::ChatBadge}; pub type BotAR = Arc>; @@ -21,24 +21,63 @@ pub struct ExecBodyParams { impl ExecBodyParams { - pub async fn get_parent_module(&self) -> Option { + // pub async fn get_parent_module(&self) -> Option { + pub async fn get_parent_module(&self) -> BotModule { let parent_act = Arc::clone(&self.parent_act); let parent_act_lock = parent_act.read().await; let act = &(*parent_act_lock); match act { BotAction::C(c) => { - let temp = c.module.clone(); - Some(temp) + // let temp = c.module.clone(); + // Some(temp) + c.module.clone() }, BotAction::L(l) => { - let temp = l.module.clone(); - Some(temp) + // let temp = l.module.clone(); + // Some(temp) + l.module.clone() }, - _ => None + BotAction::R(r) => { + // let temp = r.module.clone(); + // Some(temp) + r.module.clone() + } + // _ => None } } + pub async fn get_routine_channel(&self) -> Option { + + // THIS IS INCORRECT - BELOW MAY BE PULLING THE PARENT BOTACTION + // NOT THE CURRENT BOT ACTION + + let parent_act = Arc::clone(&self.parent_act); + let parent_act_lock = parent_act.read().await; + let act = &(*parent_act_lock); + match act { + BotAction::C(_) => { + // let temp = c.module.clone(); + // Some(temp) + None + }, + BotAction::L(_) => { + // let temp = l.module.clone(); + // Some(temp) + // l.module.clone() + None + }, + BotAction::R(r) => { + // let temp = r.module.clone(); + // Some(temp) + Some(r.channel.clone()) + } + // _ => None + } + } + + + pub fn get_sender(&self) -> String { self.msg.sender.name.clone() } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index a752ad5..f327266 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -615,9 +615,9 @@ pub enum RoutineAttr { // #[derive(Debug)] pub struct Routine { pub name : String , - module : BotModule , // from() can determine this if passed parents_params + pub module : BotModule , // from() can determine this if passed parents_params // pub channel : Option , // Routines generally run by Channel ; but can be left None - channel : Channel , // Requiring some channel context + pub channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, // parent_params : Option , parent_params : ExecBodyParams , @@ -664,6 +664,7 @@ impl Routine { }) ; } + Err("NOT IMPLEMENTED".to_string()) } @@ -685,6 +686,7 @@ impl Routine { // [ ] & Assigns self.join_handle + let self_rw = Arc::new(RwLock::new(self)); let mut self_wr_lock = self_rw.write().await; @@ -746,15 +748,31 @@ impl Routine { ); + Log::flush(); })) } self_wr_lock.join_handle = innerhelper(self_rw.clone()) ; return Ok("Successfully Started Routine".to_string()); + } + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } @@ -767,27 +785,88 @@ impl Routine { ).await; } - pub fn stop(&self) -> Result + pub async fn stop(&self) -> Result { + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); + Err("NOT IMPLEMENTED".to_string()) } - pub fn restart( + pub async fn restart( &self, _force : bool ) -> Result { // force flag aborts the routine immediately (like cancel()) + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } - pub fn cancel(&self) -> Result + pub async fn cancel(&self) -> Result { // [ ] Likely calls abort() // Related : // https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html#method.abort + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } diff --git a/src/core/chat.rs b/src/core/chat.rs index bb938cc..d0b85e6 100644 --- a/src/core/chat.rs +++ b/src/core/chat.rs @@ -108,7 +108,8 @@ impl Chat { let botlock = botclone.read().await; let modmgr = Arc::clone(&botlock.botmodules); let modstatus = (*modmgr).modstatus( - parent_module.clone().expect("ERROR - Expected a module"), + // parent_module.clone().expect("ERROR - Expected a module"), + parent_module.clone(), Channel(channel_login.clone()) ).await; @@ -180,7 +181,8 @@ impl Chat { self.send_botmsg(BotMsgType::Notif( format!("uuh {:?} is disabled on {} : {:?}", - parent_module.clone().unwrap(), + // parent_module.clone().unwrap(), + parent_module.clone(), channel_login.clone(), lvl ), diff --git a/src/custom/experimental.rs b/src/custom/experimental.rs index 409abd1..7da2ecb 100644 --- a/src/custom/experimental.rs +++ b/src/custom/experimental.rs @@ -12,6 +12,7 @@ pub use crate::core::botmodules::ModulesManager; mod experiment001; mod experiment002; +mod experiment003; // [ ] init() function that accepts bot instance - this is passed to init() on submodules @@ -21,4 +22,5 @@ pub async fn init(mgr: Arc) { experiment001::init(Arc::clone(&mgr)).await; experiment002::init(Arc::clone(&mgr)).await; + experiment003::init(Arc::clone(&mgr)).await; } diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs new file mode 100644 index 0000000..0bb98b9 --- /dev/null +++ b/src/custom/experimental/experiment003.rs @@ -0,0 +1,277 @@ +/* + Custom Modules - + + Usage : + [ ] within the file's init(), define BotActions & Load them into the ModulesManager + [ ] Define Execution Bodies for these BotActions + [ ] Afterwards, add the following to parent modules.rs file + - mod ; + - within init(), ::init(mgr).await + +*/ + + +const OF_CMD_CHANNEL:Channel = Channel(String::new()); + + +use casual_logger::Log; +use rand::Rng; +use std::sync::Arc; + +use crate::core::bot_actions::ExecBodyParams; +use crate::core::botinstance::Channel; +use crate::core::botlog; + +use crate::core::bot_actions::actions_util; +use crate::core::botmodules::{BotAction, BotActionTrait, BotCommand, BotModule, Listener, ModulesManager, Routine, RoutineAttr}; + +use crate::core::identity::UserRole::*; + +use tokio::time::{sleep, Duration}; + +pub async fn init(mgr: Arc) { + + // 1. Define the BotAction + let botc1 = BotCommand { + module: BotModule(String::from("experiments003")), + command: String::from("test3"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(test3_body), + help: String::from("Test Command tester"), + required_roles: vec![ + BotAdmin, + Mod(OF_CMD_CHANNEL), + ], + }; + + // 2. Add the BotAction to ModulesManager + botc1.add_to_modmgr(Arc::clone(&mgr)).await; + + +} + + +async fn test3_body(params : ExecBodyParams) { + // println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "testy triggered!", + Some("Experiments003 > test3 command body".to_string()), + Some(¶ms.msg), + ); + + /* + Test Routine Start() by : + 1. In this single exec body , create a Routine + 2. Create a Routine Execution Body + 3. Pass the Execution Body & Routine Attributes to create the Routine + 4. Start the Routine + 5. For RunOnce , we should see it only trigger once, and then complete in the logs + + */ + + // [x] Get the module from params + + let parentmodule = params.get_parent_module().await; + let channel = params.get_routine_channel().await; + let routine_attr = vec![ + RoutineAttr::RunOnce + ]; + let exec_body = actions_util::asyncbox(rtestbody); + let parent_params = params.clone(); + + async fn rtestbody(params : ExecBodyParams) { + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg.clone(), + String::from("Inner Routine Loop Message"), + params.clone() + ).await; + } + + let a = Routine::from( + "Routine Test".to_string(), + parentmodule, + channel.unwrap(), + routine_attr, + exec_body, + parent_params + ); + + if let Ok(newr) = a { + let rslt = newr.start().await; + + + botlog::debug( + format!("TEST3_BODY RESULT : {:?}", + rslt + ).as_str(), + Some("experiment003 > test3_body".to_string()), + Some(¶ms.msg), + ); + + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + format!("Routine Result : {:?}",rslt), + params.clone() + ).await; + + + } + + + + + Log::flush(); +} + + + + + +async fn good_girl(params : ExecBodyParams) { + + // [ ] Uses gen_ratio() to output bool based on a ratio probability . + // - For example gen_ratio(2,3) is 2 out of 3 or 0.67% (numerator,denomitator) + // - More Info : https://rust-random.github.io/rand/rand/trait.Rng.html#method.gen_ratio + + if params.msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase() + || params.msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase() + { + botlog::debug( + "Good Girl Detected > Pausechamp", + Some("experiments > goodgirl()".to_string()), + Some(¶ms.msg), + ); + + let rollwin = rand::thread_rng().gen_ratio(1, 10); + + if rollwin { + botlog::debug( + "Oh that's a good girl!", + Some("experiments > goodgirl()".to_string()), + Some(¶ms.msg), + ); + + let bot = Arc::clone(¶ms.bot); + + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("GoodGirl xdd "), + params.clone() + ).await; + + + } + } +} + +async fn testy(params : ExecBodyParams) { + println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "testy triggered!", + Some("experiments > testy()".to_string()), + Some(¶ms.msg), + ); +} + + +async fn babygirl(params : ExecBodyParams) { + + + println!("babygirl triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "babygirl triggered!", + Some("experiments > babygirl()".to_string()), + Some(¶ms.msg), + ); + + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: cafdk"), + params.clone() + ).await; + + + sleep(Duration::from_secs_f64(0.5)).await; + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: have fun eating princess"), + params.clone() + ).await; + + + sleep(Duration::from_secs_f64(2.0)).await; + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: baby girl"), + params.clone() + ).await; + + + +} + + +async fn routinelike(params : ExecBodyParams) { + println!("routinelike triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "routinelike triggered!", + Some("experiments > routinelike()".to_string()), + Some(¶ms.msg), + ); + + // spawn an async block that runs independently from others + + tokio::spawn( async { + for _ in 0..5 { + println!(">> Innterroutine triggered!"); + sleep(Duration::from_secs_f64(5.0)).await; + } + } + ); + + // lines are executed after in conjunction to the spawn + +} +