diff --git a/src/core.rs b/src/core.rs index ca51e65..7027176 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,7 +1,7 @@ pub mod botinstance; -pub mod ratelimiter; pub mod botmodules; pub mod identity; +pub mod ratelimiter; // pub fn init() -> () // { diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 1bc9d21..05cc69f 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -1,21 +1,20 @@ - // use futures::lock::Mutex; use tokio::sync::mpsc::UnboundedReceiver; use tokio::sync::RwLock; use twitch_irc::login::StaticLoginCredentials; -use twitch_irc::ClientConfig; -use twitch_irc::SecureTCPTransport; -use twitch_irc::TwitchIRCClient; use twitch_irc::message::PrivmsgMessage; use twitch_irc::message::ServerMessage; use twitch_irc::transport::tcp::TCPTransport; use twitch_irc::transport::tcp::TLS; +use twitch_irc::ClientConfig; +use twitch_irc::SecureTCPTransport; +use twitch_irc::TwitchIRCClient; // use std::borrow::Borrow; +use dotenv::dotenv; use std::borrow::BorrowMut; use std::boxed; use std::cell::Ref; use std::env; -use dotenv::dotenv; use std::collections::HashMap; @@ -27,16 +26,15 @@ use tokio::sync::Mutex; use crate::core::botmodules::BotAction; -use crate::core::botmodules::BotAction; -use crate::core::ratelimiter::RateLimiter; use crate::core::ratelimiter; +use crate::core::ratelimiter::RateLimiter; use crate::core::botmodules; use crate::core::botmodules::ModulesManager; -use crate::core::identity::{IdentityManager,Permissible,ChangeResult}; +use crate::core::identity::{ChangeResult, IdentityManager, Permissible}; -use std::rc::Rc; use std::cell::RefCell; +use std::rc::Rc; use std::sync::Arc; // use futures::lock::Mutex; @@ -48,20 +46,18 @@ use core::borrow::Borrow; // pub type BotAR = Arc>; use super::botmodules::bot_actions::actions_util::BotAR; - -use casual_logger::{Level,Log}; - +use casual_logger::{Level, Log}; pub mod botlog { - /* - Module intends to add some layers to logging with the module user only requiring to pass : + /* + Module intends to add some layers to logging with the module user only requiring to pass : - String Log message - Option - Code_Module - Option - this is used to parse out Chatter & Channel into the logs - */ + */ - use casual_logger::{Level,Log}; + use casual_logger::{Level, Log}; use twitch_irc::message::PrivmsgMessage; // trace, debug, info, notice, warn, error, fatal @@ -70,217 +66,222 @@ pub mod botlog { in main : Log::debug("Checking bot actions", Some("main()".to_string()), None); - in log : + in log : [blalba@timestmp] debug = "Checking bot actions", - + */ - pub fn trace(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () - { - - let (chnl,chatter) = match in_prvmsg { + pub fn trace( + in_msg: &str, + in_module: Option, + in_prvmsg: Option<&PrivmsgMessage>, + ) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::trace_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - - - } - pub fn debug(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { - - let (chnl,chatter) = match in_prvmsg { + pub fn debug( + in_msg: &str, + in_module: Option, + in_prvmsg: Option<&PrivmsgMessage>, + ) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::debug_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - } - pub fn info(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { - - let (chnl,chatter) = match in_prvmsg { + pub fn info(in_msg: &str, in_module: Option, in_prvmsg: Option<&PrivmsgMessage>) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::info_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - } - pub fn notice(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { - - let (chnl,chatter) = match in_prvmsg { + pub fn notice( + in_msg: &str, + in_module: Option, + in_prvmsg: Option<&PrivmsgMessage>, + ) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::notice_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - } - pub fn warn(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { - - let (chnl,chatter) = match in_prvmsg { + pub fn warn(in_msg: &str, in_module: Option, in_prvmsg: Option<&PrivmsgMessage>) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::warn_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - } - pub fn error(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { - - let (chnl,chatter) = match in_prvmsg { + pub fn error( + in_msg: &str, + in_module: Option, + in_prvmsg: Option<&PrivmsgMessage>, + ) -> () { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::error_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); - } - pub fn fatal<'a>(in_msg:&'a str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> &'a str { - - let (chnl,chatter) = match in_prvmsg { + pub fn fatal<'a>( + in_msg: &'a str, + in_module: Option, + in_prvmsg: Option<&PrivmsgMessage>, + ) -> &'a str { + let (chnl, chatter) = match in_prvmsg { Some(prvmsg) => { //Log::trace(&format!("(#{}) {}: {}", prvmsg.channel_login, prvmsg.sender.name, prvmsg.message_text)); - (Some(prvmsg.channel_login.clone()),Some(prvmsg.sender.name.clone())) // <-- Clone fine atm while we're just working with Strings - } - None => { - (None,None) + ( + Some(prvmsg.channel_login.clone()), + Some(prvmsg.sender.name.clone()), + ) // <-- Clone fine atm while we're just working with Strings } + None => (None, None), }; Log::fatal_t( in_msg, casual_logger::Table::default() // - .str("Channel",&format!("{:?}",chnl)) - .str("Chatter",&format!("{:?}",chatter)) - .str("Code_Module",&format!("{:?}",in_module)) + .str("Channel", &format!("{:?}", chnl)) + .str("Chatter", &format!("{:?}", chatter)) + .str("Code_Module", &format!("{:?}", in_module)), ); in_msg } - } - - #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { Channel(String), } - pub use ChType::Channel; #[derive(Clone)] pub struct Chat { - pub ratelimiters : Arc>>, // used to limit messages sent per channel - pub client : TwitchIRCClient,StaticLoginCredentials>, + pub ratelimiters: Arc>>, // used to limit messages sent per channel + pub client: TwitchIRCClient, StaticLoginCredentials>, } impl Chat { - - - pub fn init(ratelimiters:HashMap, - client:TwitchIRCClient, StaticLoginCredentials>) -> Chat { - Chat{ - ratelimiters : Arc::new(Mutex::new(ratelimiters)), - client : client, - } + pub fn init( + ratelimiters: HashMap, + client: TwitchIRCClient, StaticLoginCredentials>, + ) -> Chat { + Chat { + ratelimiters: Arc::new(Mutex::new(ratelimiters)), + client: client, + } } - pub async fn init_channel(&mut self, chnl:ChType) -> () { + pub async fn init_channel(&mut self, chnl: ChType) -> () { let n = RateLimiter::new(); - self.ratelimiters.lock().await.insert(chnl,n); - } + self.ratelimiters.lock().await.insert(chnl, n); + } - - - // pub async fn say_in_reply_to(&mut self, msg:& PrivmsgMessage , mut outmsg:String) -> () { - pub async fn say_in_reply_to(&self, msg:& PrivmsgMessage , mut outmsg:String) -> () { + // pub async fn say_in_reply_to(&mut self, msg:& PrivmsgMessage , mut outmsg:String) -> () { + pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, mut outmsg: String) -> () { /* - formats message before sending to TwitchIRC + formats message before sending to TwitchIRC - [x] Custom String Formatting (e.g., adding random black spaces) - [x] Ratelimiter Handling - [ ] Checkf if BotActions is Enabled & Caller is Allowed to Run */ - + let a = Arc::clone(&self.ratelimiters); let mut a = a.lock().await; @@ -288,132 +289,118 @@ impl Chat { // .get_mut() .get_mut(&Channel(String::from(&msg.channel_login))) .expect("ERROR: Issue with Rate limiters"); - + match contextratelimiter.check_limiter() { ratelimiter::LimiterResp::Allow => { let maxblanks = rand::thread_rng().gen_range(1..=20); - + for _i in 1..maxblanks { let blankspace: &str = "󠀀"; outmsg.push_str(blankspace); } - - self.client.say_in_reply_to(msg,outmsg).await.unwrap(); + + self.client.say_in_reply_to(msg, outmsg).await.unwrap(); // println!("(#{}) > {}", msg.channel_login, "rate limit counter increase"); // Log::trace(&format!("(#{}) > {}", msg.channel_login, "rate limit counter increase")); - botlog::trace(&format!("(#{}) > {}", msg.channel_login, "rate limit counter increase"), - Some("Chat > say_in_reply_to".to_string()) , - Some(&msg)); + botlog::trace( + &format!( + "(#{}) > {}", + msg.channel_login, "rate limit counter increase" + ), + Some("Chat > say_in_reply_to".to_string()), + Some(&msg), + ); contextratelimiter.increment_counter(); // println!("{:?}",self.ratelimiters); // Log::trace(&format!("{:?}",self.ratelimiters)); - botlog::trace(&format!("{:?}",self.ratelimiters), - Some("Chat > say_in_reply_to".to_string()) , - Some(&msg)); - }, + botlog::trace( + &format!("{:?}", self.ratelimiters), + Some("Chat > say_in_reply_to".to_string()), + Some(&msg), + ); + } ratelimiter::LimiterResp::Skip => { (); // do nothing otherwise } - - } + } Log::flush(); } - - async fn say(&self, _:String, _:String) -> () { - // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say - - - // self.client.say(msg,outmsg).await.unwrap(); - - - } - - - async fn me(&self, _:String, _:String) -> () { - // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say - - - // self.client.me(msg,outmsg).await.unwrap(); - - - } - - async fn me_in_reply_to(&self, _:String, _:String) -> () { - // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say - - - // self.client.me(msg,outmsg).await.unwrap(); - - - } + async fn say(&self, _: String, _: String) -> () { + // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say + // self.client.say(msg,outmsg).await.unwrap(); + } + + async fn me(&self, _: String, _: String) -> () { + // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say + + // self.client.me(msg,outmsg).await.unwrap(); + } + + async fn me_in_reply_to(&self, _: String, _: String) -> () { + // more info https://docs.rs/twitch-irc/latest/twitch_irc/client/struct.TwitchIRCClient.html#method.say + + // self.client.me(msg,outmsg).await.unwrap(); + } } - #[derive(Clone)] pub struct BotManagers { // pub botmodules : ModulesManager, - pub identity : Arc>, - pub chat : Chat, + pub identity: Arc>, + pub chat: Chat, } impl BotManagers { - - pub fn init(ratelimiters:HashMap, - client:TwitchIRCClient, StaticLoginCredentials>) - -> BotManagers { - + pub fn init( + ratelimiters: HashMap, + client: TwitchIRCClient, StaticLoginCredentials>, + ) -> BotManagers { BotManagers { - identity : Arc::new(RwLock::new(IdentityManager::init())), - chat : Chat::init(ratelimiters,client), + identity: Arc::new(RwLock::new(IdentityManager::init())), + chat: Chat::init(ratelimiters, client), } } pub fn rIdentity(self) -> Arc> { self.identity } - } - pub struct ArcBox(pub Arc>); -impl ArcBox{ +impl ArcBox { pub fn inst(&self) -> &Mutex { &self.0 } - } //#[derive(Clone)] // #[derive(Copy)] // <-- Cannot be derived -pub struct BotInstance -{ - pub prefix : char, - pub bot_channel : ChType, - pub incoming_messages : Arc>>, - pub botmodules : Arc, - pub twitch_oauth : String, - pub bot_channels : Vec, - pub botmgrs : BotManagers, - //modesmgr : ModesManager, // Silent/Quiet , uwu , frisky/horny - +pub struct BotInstance { + pub prefix: char, + pub bot_channel: ChType, + pub incoming_messages: Arc>>, + pub botmodules: Arc, + pub twitch_oauth: String, + pub bot_channels: Vec, + pub botmgrs: BotManagers, + //modesmgr : ModesManager, // Silent/Quiet , uwu , frisky/horny } - - -impl BotInstance -{ - - - pub async fn init() -> BotInstance - { +impl BotInstance { + pub async fn init() -> BotInstance { dotenv().ok(); let login_name = env::var("login_name").unwrap().to_owned(); let oauth_token = env::var("access_token").unwrap().to_owned(); - let prefix = env::var("prefix").unwrap().to_owned().chars().next().expect("ERROR : when defining prefix"); + let prefix = env::var("prefix") + .unwrap() + .to_owned() + .chars() + .next() + .expect("ERROR : when defining prefix"); /* Vector of channels to join @@ -426,12 +413,13 @@ impl BotInstance botchannels.push(Channel(String::from(chnl))); } - let config = ClientConfig::new_simple( - StaticLoginCredentials::new(login_name.to_owned(), Some(oauth_token.to_owned())) - ); + let config = ClientConfig::new_simple(StaticLoginCredentials::new( + login_name.to_owned(), + Some(oauth_token.to_owned()), + )); let (incoming_messages, client) = - TwitchIRCClient::::new(config); + TwitchIRCClient::::new(config); // hashmap for channels and their associated ratelimiters let mut ratelimiters = HashMap::new(); @@ -441,127 +429,125 @@ impl BotInstance client.join(chnl.to_owned()).unwrap(); - // ratelimiters are a hashmap of channel and a corresponding rate limiter + // ratelimiters are a hashmap of channel and a corresponding rate limiter let n = RateLimiter::new(); - ratelimiters.insert(Channel(String::from(chnl)),n); + ratelimiters.insert(Channel(String::from(chnl)), n); //self.chat.ratelimiters.insert(Channel(String::from(chnl)),n); } - - // let b = BotInstance { // prefix : prefix, // bot_channel : Channel(login_name) , // incoming_messages : Arc::new(RwLock::new(incoming_messages)), // botmodules : ModulesManager::init().await, // twitch_oauth : oauth_token, - // bot_channels : botchannels, + // bot_channels : botchannels, // botmgrs : BotManagers::init(ratelimiters,client), // }; BotInstance { - prefix : prefix, - bot_channel : Channel(login_name) , - incoming_messages : Arc::new(RwLock::new(incoming_messages)), - botmodules : ModulesManager::init().await, - twitch_oauth : oauth_token, - bot_channels : botchannels, - botmgrs : BotManagers::init(ratelimiters,client), + prefix: prefix, + bot_channel: Channel(login_name), + incoming_messages: Arc::new(RwLock::new(incoming_messages)), + botmodules: ModulesManager::init().await, + twitch_oauth: oauth_token, + bot_channels: botchannels, + botmgrs: BotManagers::init(ratelimiters, client), } // b } pub async fn runner(self) -> () { - let bot = Arc::new(RwLock::new(self)); - let join_handle = tokio::spawn(async move { - let a = bot.read().await; let mut a = a.incoming_messages.write().await; while let Some(message) = a.recv().await { - match message { ServerMessage::Notice(msg) => { - match &msg.channel_login { Some(chnl) => { // println!("NOTICE : (#{}) {}", chnl, msg.message_text) // Log::notice(&format!("NOTICE : (#{}) {}", chnl, msg.message_text)); - botlog::notice(&format!("NOTICE : (#{}) {}", chnl, msg.message_text), - Some("BotInstance > runner()".to_string()) , - None); - - }, + botlog::notice( + &format!("NOTICE : (#{}) {}", chnl, msg.message_text), + Some("BotInstance > runner()".to_string()), + None, + ); + } None => { // println!("NOTICE : {}", msg.message_text); // Log::notice(&format!("NOTICE : {}", msg.message_text)); - botlog::notice(&format!("NOTICE : {}", msg.message_text), - Some("BotInstance > runner()".to_string()) , - None); - }, + botlog::notice( + &format!("NOTICE : {}", msg.message_text), + Some("BotInstance > runner()".to_string()), + None, + ); + } } } ServerMessage::Privmsg(msg) => { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // Log::trace(&format!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text)); - botlog::debug(&format!("Twitch Chat > {} @ #{}: {}", msg.channel_login, msg.sender.name, msg.message_text), - Some("BotInstance > runner()".to_string()) , - Some(&msg)); + botlog::debug( + &format!( + "Twitch Chat > {} @ #{}: {}", + msg.channel_login, msg.sender.name, msg.message_text + ), + Some("BotInstance > runner()".to_string()), + Some(&msg), + ); // println!("Privmsg section"); // Log::debug(&format!("Privmsg section")); - botlog::trace(&format!("Privmsg section"), - Some("BotInstance > runner()".to_string()) , - Some(&msg)); + botlog::trace( + &format!("Privmsg section"), + Some("BotInstance > runner()".to_string()), + Some(&msg), + ); BotInstance::listener_main_prvmsg(Arc::clone(&bot), &msg).await; - - }, + } ServerMessage::Whisper(msg) => { // println!("(w) {}: {}", msg.sender.name, msg.message_text); // Log::trace(&format!("(w) {}: {}", msg.sender.name, msg.message_text)); - botlog::trace(&format!("(w) {}: {}", msg.sender.name, msg.message_text), - Some("BotInstance > runner()".to_string()) , - None); - }, + botlog::trace( + &format!("(w) {}: {}", msg.sender.name, msg.message_text), + Some("BotInstance > runner()".to_string()), + None, + ); + } ServerMessage::Join(msg) => { // println!("JOINED: {}", msg.channel_login); // Log::notice(&format!("JOINED: {}", msg.channel_login)); - botlog::notice(&format!("JOINED: {}", msg.channel_login), - Some("BotInstance > runner()".to_string()) , - None); - }, + botlog::notice( + &format!("JOINED: {}", msg.channel_login), + Some("BotInstance > runner()".to_string()), + None, + ); + } ServerMessage::Part(msg) => { // println!("PARTED: {}", msg.channel_login); // Log::notice(&format!("PARTED: {}", msg.channel_login)); - botlog::notice(&format!("PARTED: {}", msg.channel_login), - Some("BotInstance > runner()".to_string()) , - None); - }, + botlog::notice( + &format!("PARTED: {}", msg.channel_login), + Some("BotInstance > runner()".to_string()), + None, + ); + } _ => {} }; Log::flush(); } }); - - - - - + join_handle.await.unwrap(); - - } - - pub fn get_botmodules(self) -> Arc { - self.botmodules - } pub async fn get_botmgrs(self) -> BotManagers { @@ -569,31 +555,29 @@ impl BotInstance a } - pub fn get_identity(&self) -> Arc> { + pub fn get_identity(&self) -> Arc> { Arc::clone(&self.botmgrs.identity) } - pub fn get_prefix(&self) -> char { - (*self).prefix } + // ----------------- + // PRIVATE FUNCTIONS -// ----------------- -// PRIVATE FUNCTIONS - - - pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { + pub async fn listener_main_prvmsg(bot: BotAR, msg: &PrivmsgMessage) -> () { // println!(">> Inner listenermain_prvmsg()"); // Log::trace(">> Inner listenermain_prvmsg()"); - botlog::trace(">> Inner listenermain_prvmsg()", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + ">> Inner listenermain_prvmsg()", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); // let a = a; // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - + // // [ ] Need to run through all Listener Bodies for Enabled Modules for the context of the message (e.g., ModStatus is Enabled in the context for the channel) let botlock = bot.read().await; @@ -602,39 +586,43 @@ impl BotInstance let a = hacts.read().await; // println!("hacts size : {}",(*a).len()); // Log::debug(&format!("hacts size : {}",(*a).len())); - botlog::trace(&format!("hacts size : {}",(*a).len()), - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + &format!("hacts size : {}", (*a).len()), + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); // println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); // Log::trace(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); - botlog::trace(">> Inner listenermain_prvmsg() >> before for loop of bot actions", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); - - for (_m,acts) in &*hacts.read().await { - + botlog::trace( + ">> Inner listenermain_prvmsg() >> before for loop of bot actions", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); + + for (_m, acts) in &*hacts.read().await { // println!(">> Inner listenermain_prvmsg() >> checking bot actions"); // Log::trace(">> Inner listenermain_prvmsg() >> checking bot actions"); - botlog::trace(">> Inner listenermain_prvmsg() >> checking bot actions", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + ">> Inner listenermain_prvmsg() >> checking bot actions", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); + // let bot = bot; - // let bot = bot; - for a in acts { - // println!(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); // Log::trace(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); - botlog::trace(">> Inner listenermain_prvmsg() >> checking bot actions >> 2", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + ">> Inner listenermain_prvmsg() >> checking bot actions >> 2", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); let _act = match a { - crate::core::botmodules::BotAction::C(c) => { - /* + /* BotCommand handling - - [x] Checks if the input message is a prefix with command name or alias - [ ] Validate User can run based on identityModule(From_Bot)::can_user_run( @@ -650,102 +638,119 @@ impl BotInstance // println!("Reviewing internal commands"); // Log::trace("Reviewing internal commands"); - botlog::trace("Reviewing internal commands", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Reviewing internal commands", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); // let inpt = msg.message_text.split("\n").next().expect("ERROR during BotCommand"); - let inpt = msg.message_text.split(" ").next().expect("ERROR during BotCommand"); - - - + let inpt = msg + .message_text + .split(" ") + .next() + .expect("ERROR during BotCommand"); // [x] Check if a bot command based on ... // [x] prefix + command let mut confirmed_bot_command = false; - + let instr = bot.read().await.get_prefix(); if inpt == String::from(instr) + c.command.as_str() { confirmed_bot_command = true; - } + } // [x] prefix + alias for alias in &c.alias { - let instr = bot.read().await.get_prefix(); if inpt == String::from(instr) + alias.as_str() { confirmed_bot_command = true; - } + } } if confirmed_bot_command { // println!("Confirmed bot command"); // Log::debug("Confirmed bot command"); - botlog::debug("Confirmed bot command", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); - + botlog::debug( + "Confirmed bot command", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); + // println!("Going for botlock"); // Log::trace("Going for botlock"); - botlog::trace("Going for botlock", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Going for botlock", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); let botlock = bot.read().await; // println!("Going for identity"); // Log::trace("Going for identity"); - botlog::trace("Going for identity", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Going for identity", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); let id = botlock.get_identity(); - + let eval = { let mut id = id.write().await; // println!("Unlocking identity"); // Log::trace("Unlocking identity"); - botlog::trace("Unpacking identity", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Unpacking identity", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); - - let (a,b) = id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + let (a, b) = + id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; // // [-] #todo : need ot add functionality around here to do an o7 when a mod has been promoted => Preferring to do this outside the mutex // if let ChangeResult::Success(b) = b { // // let b = b.to_lowercase(); // // let b = b.contains(&"Auto Promoted Mod".to_lowercase()); // if b.to_lowercase().contains(&"Auto Promoted Mod".to_lowercase()) { - // let chat = + // let chat = // } // } - (a,b) + (a, b) }; // println!("Checking if permissible"); Log::trace("Checking if permissible"); - botlog::trace("Checking if permissible", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Checking if permissible", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); - let (eval , rolechange) = eval; + let (eval, rolechange) = eval; if let ChangeResult::Success(b) = rolechange { - - if b.to_lowercase().contains(&"Auto Promoted Mod".to_lowercase()) { - botlog::notice("Assigning Mod UserRole to Mod", - Some("botinstance > listener_main_prvmsg()".to_string()), Some(&msg)); - + if b.to_lowercase() + .contains(&"Auto Promoted Mod".to_lowercase()) + { + botlog::notice( + "Assigning Mod UserRole to Mod", + Some("botinstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); // println!("Read() lock Bot"); // Log::trace("Read() lock Bot"); - botlog::trace("Read() lock Bot", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "Read() lock Bot", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); - let botlock = bot.read().await; - let outstr = "o7 a Mod. I kneel to serve! pepeKneel ".to_string(); + let botlock = bot.read().await; + let outstr = + "o7 a Mod. I kneel to serve! pepeKneel ".to_string(); (*botlock).botmgrs.chat.say_in_reply_to(msg, outstr).await; - } } @@ -753,69 +758,61 @@ impl BotInstance Permissible::Allow => { // println!("Executed as permissible"); // Log::debug("Executed as permissible"); - botlog::debug("Executed as permissible", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::debug( + "Executed as permissible", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); let a = Arc::clone(&bot); c.execute(a, msg.clone()).await; // println!("exit out of execution"); // Log::trace("exit out of execution"); - botlog::trace("exit out of execution", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); - + botlog::trace( + "exit out of execution", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); } Permissible::Block => { // println!("User Not allowed to run command"); // Log::info("User Not allowed to run command"); - botlog::info("User Not allowed to run command", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); - }, - // _ => (), + botlog::info( + "User Not allowed to run command", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); + } // _ => (), }; - }; - - } - - }, + } crate::core::botmodules::BotAction::L(l) => { let a = Arc::clone(&bot); l.execute(a, msg.clone()).await; - }, + } _ => (), }; } - }; - + } // // [ ] There should be a BotCommand Listener to check for prefixes ran // println!("End of Separate Listener Main prvmsg"); // Log::trace("End of Separate Listener Main prvmsg"); - botlog::trace("End of Separate Listener Main prvmsg", - Some("BotInstance > listener_main_prvmsg()".to_string()) , - Some(&msg)); + botlog::trace( + "End of Separate Listener Main prvmsg", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(&msg), + ); // self // bot Log::flush(); - } - - - } - - - - - // ====================================== // ====================================== // ====================================== @@ -823,13 +820,9 @@ impl BotInstance // UNIT TEST MODULES - - - - #[cfg(test)] mod tests { fn always() { - assert_eq!(1,1); + assert_eq!(1, 1); } } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 86c6314..2a38523 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -1,4 +1,4 @@ -use core::{panic}; +use core::panic; use std::error::Error; use std::collections::HashMap; @@ -15,34 +15,30 @@ use std::future::Future; // Important to use tokios Mutex here since std Mutex doesn't work with async functions use tokio::sync::Mutex; - - use crate::core::botinstance::{self, botlog, BotInstance}; use std::rc::Rc; // use tokio::sync::RwLock; - - use async_trait::async_trait; -use casual_logger::{Level,Log}; +use casual_logger::{Level, Log}; /* -ModulesManager is used to manage Modules and BotActions associated with those modules +ModulesManager is used to manage Modules and BotActions associated with those modules pub struct ModulesManager { statusdb: HashMap>, - botactions: HashMap>, + botactions: HashMap>, } - statusdb: HashMap> - Defines Modules and their ModStatusType (e.g., Enabled at an Instance level, Disabled at a Channel Level) -- botactions: HashMap> - Defines Modules and their BotActions (e.g., BotCommand , Listener, Routine) +- botactions: HashMap> - Defines Modules and their BotActions (e.g., BotCommand , Listener, Routine) Example { - ModulesManager { - statusdb: {BotModule("experiments 004"): [Enabled(Instance)]}, + ModulesManager { + statusdb: {BotModule("experiments 004"): [Enabled(Instance)]}, botactions: {BotModule("experiments 004"): [C(BotCommand { module: BotModule("experiments 004"), command: "DUPCMD4", alias: ["DUPALIAS4A", "DUPALIAS4B"], help: "DUPCMD4 tester" })]} } } @@ -52,7 +48,7 @@ Example pub enum ModType { BotModule(String), } - + pub use ModType::BotModule; // #[derive(Debug, PartialEq, Eq, Hash, Clone)] @@ -62,13 +58,12 @@ pub use ModType::BotModule; use botinstance::ChType; -pub use ChType::Channel; use twitch_irc::message::PrivmsgMessage; +pub use ChType::Channel; use self::bot_actions::actions_util; use self::bot_actions::actions_util::BotAR; - #[derive(Debug)] enum StatusLvl { Instance, @@ -82,246 +77,223 @@ pub enum ModStatusType { } // #[derive(Clone)] -pub enum BotAction -{ - C(BotCommand), +pub enum BotAction { + C(BotCommand), L(Listener), - R(Routine), + R(Routine), } impl BotAction { - - pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () - { - + pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () { match self { - BotAction::L(a) => a.execute(m,n).await, - BotAction::C(a) => a.execute(m,n).await, + BotAction::L(a) => a.execute(m, n).await, + BotAction::C(a) => a.execute(m, n).await, _ => (), } - } } #[async_trait] -pub trait BotActionTrait -{ - async fn add_to_bot(self, bot:BotInstance); - async fn add_to_modmgr(self,modmgr:Arc); +pub trait BotActionTrait { + async fn add_to_bot(self, bot: BotInstance); + async fn add_to_modmgr(self, modmgr: Arc); } // #[derive(Clone)] pub struct BotCommand { - pub module : ModType, - pub command : String, // command call name - pub alias : Vec, // String of alternative names + pub module: ModType, + pub command: String, // command call name + pub alias: Vec, // String of alternative names // bot_prefix : char, // although should be global? - pub exec_body : bot_actions::actions_util::ExecBody, - pub help : String, - pub required_roles : Vec, + pub exec_body: bot_actions::actions_util::ExecBody, + pub help: String, + pub required_roles: Vec, } -impl BotCommand -{ - pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { - ((*self).exec_body)(m,n).await; +impl BotCommand { + pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () { + ((*self).exec_body)(m, n).await; } } #[async_trait] -impl BotActionTrait for BotCommand -{ - async fn add_to_bot(self, bot:BotInstance) { +impl BotActionTrait for BotCommand { + async fn add_to_bot(self, bot: BotInstance) { self.add_to_modmgr(bot.botmodules).await; } // async fn add_to_modmgr(self, modmgr:Arc>) { - async fn add_to_modmgr(self, modmgr:Arc) { - modmgr.add_botaction(self.module.clone(), BotAction::C(self)).await + async fn add_to_modmgr(self, modmgr: Arc) { + modmgr + .add_botaction(self.module.clone(), BotAction::C(self)) + .await } - } - - pub mod bot_actions { pub mod actions_util { - - use std::future::Future; + use std::boxed::Box; + use std::future::Future; use std::pin::Pin; use std::rc::Rc; use crate::core::botinstance::{BotInstance, BotManagers, Chat}; - use twitch_irc::message::PrivmsgMessage; use std::cell::RefCell; - use std::sync::{Arc}; + use std::sync::Arc; + use twitch_irc::message::PrivmsgMessage; // use futures::lock::Mutex; // Important to use tokios Mutex here since std Mutex doesn't work with async functions - use tokio::sync::{Mutex,RwLock}; + use tokio::sync::{Mutex, RwLock}; pub type BotAM = Arc>; pub type BotAR = Arc>; - pub type ExecBody = Box Pin + Send>> + Send + Sync>; + pub type ExecBody = Box< + dyn Fn(BotAR, PrivmsgMessage) -> Pin + Send>> + Send + Sync, + >; - pub fn asyncbox(f: fn(BotAR,PrivmsgMessage) -> T) -> ExecBody + pub fn asyncbox(f: fn(BotAR, PrivmsgMessage) -> T) -> ExecBody where - T: Future + Send + 'static + T: Future + Send + 'static, { - Box::new(move |a,b| Box::pin(f(a,b))) + Box::new(move |a, b| Box::pin(f(a, b))) } } - - } - - -pub struct Listener -{ - pub module : ModType, - pub name : String, - pub exec_body : bot_actions::actions_util::ExecBody, - pub help : String +pub struct Listener { + pub module: ModType, + pub name: String, + pub exec_body: bot_actions::actions_util::ExecBody, + pub help: String, } -impl Listener -{ - - pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { - ((*self).exec_body)(m,n).await; +impl Listener { + pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () { + ((*self).exec_body)(m, n).await; } } #[async_trait] -impl BotActionTrait for Listener -{ - async fn add_to_bot(self, bot:BotInstance) { - +impl BotActionTrait for Listener { + async fn add_to_bot(self, bot: BotInstance) { // println!("Adding action to bot"); // Log::trace("Adding action to bot"); - botinstance::botlog::trace("Adding action to bot", - Some("BotModules > BotActionTrait > add_to_bot()".to_string()) , - None); + botinstance::botlog::trace( + "Adding action to bot", + Some("BotModules > BotActionTrait > add_to_bot()".to_string()), + None, + ); self.add_to_modmgr(bot.botmodules).await; } - async fn add_to_modmgr(self, modmgr:Arc) { + async fn add_to_modmgr(self, modmgr: Arc) { // let modmgr = *modmgr.lock().await; // println!("Adding action to module manager"); // Log::trace("Adding action to module manager"); - botinstance::botlog::trace("Adding action to module manager", - Some("BotModules > BotActionTrait > add_to_bot()".to_string()) , - None); + botinstance::botlog::trace( + "Adding action to module manager", + Some("BotModules > BotActionTrait > add_to_bot()".to_string()), + None, + ); - modmgr.add_botaction(self.module.clone(), BotAction::L(self)).await; + modmgr + .add_botaction(self.module.clone(), BotAction::L(self)) + .await; } - } - - #[derive(Debug)] struct Routine {} // #[derive(Clone)] -pub struct ModulesManager -{ - statusdb: Arc>>>, - pub botactions: Arc>>>, +pub struct ModulesManager { + statusdb: Arc>>>, + pub botactions: Arc>>>, } /* statusdb - <-- shows Enabled/Disabled per Status level -botactions +botactions HashMap< - ModType, <-- e.g., BotModule(String::from("experiments001")) + ModType, <-- e.g., BotModule(String::from("experiments001")) Vec> BotCommand, Listener */ -impl ModulesManager -{ - - pub async fn init() -> Arc - { - - +impl ModulesManager { + pub async fn init() -> Arc { let m = HashMap::new(); let act = HashMap::new(); let mut mgr = ModulesManager { - statusdb : Arc::new(RwLock::new(m)), - botactions : Arc::new(RwLock::new(act)), + statusdb: Arc::new(RwLock::new(m)), + botactions: Arc::new(RwLock::new(act)), }; // :: [x] initialize core modules - + // println!("ModulesManager > init() > Adding modules"); - botlog::debug("ModulesManager > init() > Adding modules", + botlog::debug( + "ModulesManager > init() > Adding modules", Some("ModulesManager > init()".to_string()), - None + None, ); let mgra = Arc::new(mgr); crate::core::identity::init(Arc::clone(&mgra)).await; - crate::modules::init(Arc::clone(&mgra)).await; - - // println!(">> Modules Manager : End of Init"); - botlog::trace(">> Modules Manager : End of Init", + botlog::trace( + ">> Modules Manager : End of Init", Some("ModulesManager > init()".to_string()), - None + None, ); mgra - } + } - pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { + pub fn modstatus(&self, _: ModType, _: ChType) -> ModStatusType { // Example usage : botmanager.modstatus( // BotModule("GambaCore"), // Channel("modulatingforce") - // ) - // - The ModStatusType checks in the context of the given channel , + // ) + // - The ModStatusType checks in the context of the given channel , // but also validates based on wheher the module is disabled at a bot instance // level as well ModStatusType::Enabled(StatusLvl::Instance) } - - pub fn togglestatus(&self, _:ModType, _:ChType) -> ModStatusType { + pub fn togglestatus(&self, _: ModType, _: ChType) -> ModStatusType { // enables or disables based on current status ModStatusType::Enabled(StatusLvl::Instance) } - - pub fn setstatus(&self, _:ModType, _:ModStatusType) -> Result<&str,Box> { + pub fn setstatus(&self, _: ModType, _: ModStatusType) -> Result<&str, Box> { // sets the status based given ModSatusType // e.g., b.setstatus(BodModule("GambaCore"), Enabled(Channel("modulatingforce"))).expect("ERROR") Ok("") } - - pub async fn add_botaction(&self, in_module:ModType, in_action:BotAction ) { + pub async fn add_botaction(&self, in_module: ModType, in_action: BotAction) { // println!("Add botaction called"); - botlog::trace("Add botaction called", - Some("ModulesManager > init()".to_string()), - None + botlog::trace( + "Add botaction called", + Some("ModulesManager > init()".to_string()), + None, ); - /* adds a BotAction to the Modules Manager - This will require a BotModule passed as well This will including the logic of a valid add @@ -331,7 +303,7 @@ impl ModulesManager -- In particular to BotCommands, which must have Unique command call names and aliases that to not conflict with any other already BotCommand added name or alias Other types might be fine? For example, if 2 modules have their own listeners but each have the name "targetchatter" , - both would be called separately, even if they both have the same or different logic + both would be called separately, even if they both have the same or different logic */ // let newlistener = Listener { @@ -341,20 +313,15 @@ impl ModulesManager // help : String::from("This will listen and react to sock randomly"), // }; - // As a Demonstration, the listener's Module is added and Enabled at Instance level - - // [x] Before Adding, validate the following : - // - If BotAction to Add is a BotCommand , In Module Manager DB (botactions), + // [x] Before Adding, validate the following : + // - If BotAction to Add is a BotCommand , In Module Manager DB (botactions), // Check All Other BotAction Command Names & Aliases to ensure they don't conflict - async fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option - { - + async fn find_conflict_module(mgr: &ModulesManager, act: &BotAction) -> Option { // Some(BotModule(String::from("GambaCore"))) - // match act { // BotAction::C(c) => { // Some(BotModule(String::from("GambaCore"))) @@ -364,15 +331,12 @@ impl ModulesManager // } if let BotAction::C(incmd) = act { - // let n = & mgr.botactions; let d = mgr.botactions.read().await; let d = &(*d); - for (module,moduleactions) in d { - - + for (module, moduleactions) in d { for modact in moduleactions.iter() { if let BotAction::C(dbcmd) = &modact { // At this point, there is an command incmd and looked up dbcmd @@ -385,54 +349,43 @@ impl ModulesManager // return Some(incmd); // for some reason I keep getting issues //return Some(BotModule(String::from("GambaCore"))); // works return Some(module.clone()); // works - // return Some(dbcmd.clone()); - } + // return Some(dbcmd.clone()); + } for a in &dbcmd.alias { if incmd.command.to_lowercase() == a.to_lowercase() { // Returning State - with the identified module // return Some((module.clone(),BotAction::C(dbcmd))); return Some(module.clone()); // works - - } - } - + } + } // [x] Then do the same check except for each c.alias for inalias in &incmd.alias { - if inalias.to_lowercase() == dbcmd.command.to_lowercase() { // Returning State - with the identified module // return Some((module.clone(),BotAction::C(dbcmd))); return Some(module.clone()); // works - - } + } for a in &dbcmd.alias { if inalias.to_lowercase() == a.to_lowercase() { // Returning State - with the identified module // return Some((module.clone(),BotAction::C(dbcmd))); return Some(module.clone()); // works - - } - } - + } + } } - - } } - } // return Some(BotModule(String::from("GambaCore"))) } - // for all other scenarios (e.g., Listener, Routine), find no conflicts None - } // if let probmod = find_conflict_module(&self, &in_action) { @@ -441,7 +394,10 @@ impl ModulesManager // } match find_conflict_module(&self, &in_action).await { // Some(c) => panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , c ), - Some(c) => panic!("ERROR: Could not add module; there was a conflict with existing module {:?}", c ), + Some(c) => panic!( + "ERROR: Could not add module; there was a conflict with existing module {:?}", + c + ), None => (), } @@ -456,30 +412,28 @@ impl ModulesManager let mut a = self.botactions.write().await; let modactions = a //.entry( BotModule(String::from("experiments"))) - .entry( in_module.clone()) + .entry(in_module.clone()) .or_insert(Vec::new()); // modactions.push(BotAction::L(newlistener)); modactions.push(in_action); // println!(">> Modules Manager : Called Add bot Action"); - botlog::trace(">> Modules Manager : Called Add bot Action", - Some("ModulesManager > init()".to_string()), - None + botlog::trace( + ">> Modules Manager : Called Add bot Action", + Some("ModulesManager > init()".to_string()), + None, ); // println!("add_botaction - botactions size : {}",modactions.len()); - botlog::trace(&format!("add_botaction - botactions size : {}",modactions.len()), - Some("ModulesManager > init()".to_string()), - None + botlog::trace( + &format!("add_botaction - botactions size : {}", modactions.len()), + Some("ModulesManager > init()".to_string()), + None, ); - } - - - - fn statuscleanup(&self,_:Option) -> () { - // internal cleans up statusdb . For example : + fn statuscleanup(&self, _: Option) -> () { + // internal cleans up statusdb . For example : // - remove redudancies . If we see several Enabled("m"), only keep 1x // - Clarify Conflict. If we see Enabled("m") and Disabled("m") , we remove Enabled("m") and keep Disabled("m") // the IDEAL is that this is ran before every read/update operation to ensure quality @@ -487,7 +441,4 @@ impl ModulesManager // Passing None to chnl may be a heavy operation, as this will review and look at the whole table () } - - - -} \ No newline at end of file +} diff --git a/src/core/identity.rs b/src/core/identity.rs index 1b7e908..0c59879 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1,12 +1,11 @@ - use std::borrow::Borrow; use std::collections::HashMap; use std::error::Error; -use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; use crate::core::botmodules::bot_actions::actions_util; +use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager}; -use crate::core::botinstance::{self, botlog, BotInstance,ChType}; +use crate::core::botinstance::{self, botlog, BotInstance, ChType}; use futures::lock::Mutex; use twitch_irc::message::{Badge, PrivmsgMessage}; @@ -14,57 +13,56 @@ use twitch_irc::message::{Badge, PrivmsgMessage}; use crate::core::botinstance::ArcBox; - -use std::rc::Rc; use std::cell::RefCell; +use std::rc::Rc; use std::sync::Arc; use tokio::sync::RwLock; -use casual_logger::{Level,Log}; - +use casual_logger::{Level, Log}; use super::botmodules::bot_actions::actions_util::BotAR; - fn adminvector() -> Vec { vec![String::from("ModulatingForce")] //vec![] } - // pub fn init(mgr:&mut ModulesManager) -pub async fn init(mgr:Arc) -{ - +pub async fn init(mgr: Arc) { // println!("Went into Identiy Module init"); - botinstance::botlog::trace("Went into Identiy Module init", - Some("identity.rs > init()".to_string()), None); + botinstance::botlog::trace( + "Went into Identiy Module init", + Some("identity.rs > init()".to_string()), + None, + ); // let a = actions_util::asyncbox(cmd_promote) ; let tempb = BotCommand { - module : BotModule(String::from("identity")), - command : String::from("promote"), // command call name - alias : vec![], // String of alternative names - exec_body : actions_util::asyncbox(cmd_promote) , - help : String::from("promote"), - required_roles : vec![ + module: BotModule(String::from("identity")), + command: String::from("promote"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(cmd_promote), + help: String::from("promote"), + required_roles: vec![ UserRole::Mod(ChType::Channel(String::new())), UserRole::SupMod(ChType::Channel(String::new())), UserRole::Broadcaster, UserRole::BotAdmin, - ], + ], }; - + tempb.add_to_modmgr(Arc::clone(&mgr)).await; - async fn cmd_promote(bot:BotAR,msg:PrivmsgMessage) -> () - { + async fn cmd_promote(bot: BotAR, msg: PrivmsgMessage) -> () { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // println!("Called cmd promote"); - botinstance::botlog::trace("Called cmd promote", - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + botinstance::botlog::trace( + "Called cmd promote", + Some("identity.rs > cmd_prommote()".to_string()), + Some(&msg), + ); // -- If the BotCommand.command was called (e.g., promote) & required roles were validated OUTSIDE of this call // , this is the current function body to execute @@ -72,66 +70,66 @@ pub async fn init(mgr:Arc) /* - `promote` / `demote` - [ ] `SupMod` & `Broadcaster` & `BotAdmin` can run - - [ ] `UserRole`s that can run, can + - [ ] `UserRole`s that can run, can - [ ] run `promote` on a regular `Chatter` to make them a `Mod` - [ ] run `demote` on a `Mod` to make them a `Chatter` - - [ ] Only `BotAdmin` can : + - [ ] Only `BotAdmin` can : - [ ] target themselves to `promote` / `demote` , in the case that they want to make themselves either a `Mod` or `SupMod` for the channel temporarily - - [ ] `promote admin ` to assign them `BotAdmin` role + - [ ] `promote admin ` to assign them `BotAdmin` role - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` or `promote` the other way */ - /* - Usage : + Usage : promote - demote + demote promote -admin - + */ - // println!("{}",msg.message_text); - botinstance::botlog::trace(&format!("Twich Message > {}",msg.message_text), - Some("identity.rs > cmd_promote()".to_string()), None); + botinstance::botlog::trace( + &format!("Twich Message > {}", msg.message_text), + Some("identity.rs > cmd_promote()".to_string()), + None, + ); let sendername = msg.clone().sender.name; - let mut argv = msg.message_text.split(" "); - - argv.next(); // Skip the command name - - let arg1 = argv.next(); + let mut argv = msg.message_text.split(" "); - let arg2 = argv.next(); + argv.next(); // Skip the command name - let mut sender_badge:Option = None; + let arg1 = argv.next(); - for b in &msg.badges { - if b.name == "moderator" { - sender_badge = Some(ChatBadge::Mod); - } else if b.name == "broadcaster" { - sender_badge = Some(ChatBadge::Broadcaster); - } - } + let arg2 = argv.next(); - let targetchnl = msg.channel_login.to_lowercase(); + let mut sender_badge: Option = None; - /* - - [x] 1. Get trgusr (regardless of -admin flag) - [x] 2. promote trguser - [x] 3. Output resulting change + for b in &msg.badges { + if b.name == "moderator" { + sender_badge = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + sender_badge = Some(ChatBadge::Broadcaster); + } + } - */ + let targetchnl = msg.channel_login.to_lowercase(); + + /* + + [x] 1. Get trgusr (regardless of -admin flag) + [x] 2. promote trguser + [x] 3. Output resulting change + + */ // [x] 1. Get trgusr (regardless of -admin flag) - let targetusr = if arg1 == Some("-admin") {arg2} else {arg1}; - + let targetusr = if arg1 == Some("-admin") { arg2 } else { arg1 }; // [x] 2. promote trguser @@ -143,325 +141,351 @@ pub async fn init(mgr:Arc) let rslt = match targetusr { Some(targetusr) => { - - botinstance::botlog::debug(&format!("running promote()"), - Some("identity.rs > cmd_promote()".to_string()), None); + botinstance::botlog::debug( + &format!("running promote()"), + Some("identity.rs > cmd_promote()".to_string()), + None, + ); Log::flush(); - let target_bot_admin_role = if arg1 == Some("-admin") {Some(UserRole::BotAdmin)} else {None}; + let target_bot_admin_role = if arg1 == Some("-admin") { + Some(UserRole::BotAdmin) + } else { + None + }; - idlock.promote( - sendername.clone(), - &sender_badge, - targetusr.to_string(), - Some(ChType::Channel(targetchnl.clone())), - target_bot_admin_role, - ).await + idlock + .promote( + sendername.clone(), + &sender_badge, + targetusr.to_string(), + Some(ChType::Channel(targetchnl.clone())), + target_bot_admin_role, + ) + .await } None => { - - botinstance::botlog::debug(&format!("No Targer User argument"), - Some("identity.rs > cmd_demote()".to_string()), None); + botinstance::botlog::debug( + &format!("No Targer User argument"), + Some("identity.rs > cmd_demote()".to_string()), + None, + ); Log::flush(); ChangeResult::NoChange("No Targer User".to_string()) - } - }; - - - // [x] 3. Output resulting change + // [x] 3. Output resulting change match rslt { ChangeResult::Success(a) => { // println!("Succesfully promoted : {a} ;"); let outmsg = &format!("o7 Successfully promoted : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_prommote()".to_string()), + Some(&msg), + ); // let outmsg = "o7 Successfully promoted : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } ChangeResult::Failed(a) => { // println!("Failed to promote : {a} ; "); let outmsg = &format!("PoroSad failed to promote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_prommote()".to_string()), + Some(&msg), + ); // let outmsg = "PoroSad failed to promote : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } ChangeResult::NoChange(a) => { // println!("No Changes Made : {a} ; "); let outmsg = &format!("uuh No Promotion Change : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_prommote()".to_string()), + Some(&msg), + ); // let outmsg = "uuh No Promotion Change : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } + } + + /* + match arg1 { + Some(a1) if a1 == String::from("-admin") => { + // - [x] BotAdmins can promote admin to give BotAdmin UserRole + + let botlock = bot.read().await; + let idlock = botlock.get_identity(); + let id = idlock.read().await; + // let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + // let ta = ta.getspecialuserroles(arg2.unwrap().to_string(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + let rolesfut = id.getspecialuserroles( + msg.sender.name.to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase()))); + let usrroles = rolesfut.await; + // let ta = ta.unwrap(); + // let a = ta.read().await; + // let ta = *ta; + // let ta = *ta; + // if let Some(a) = *ta { + + if usrroles.contains(&UserRole::BotAdmin) { + // println!("BotAdmin allowed to promote admin"); + botinstance::botlog::debug("BotAdmin allowed to promote admin", + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + + { + + let idlock = Arc::clone(&bot.read().await.get_identity()); + // let idlock = idlock.write().await; + let idlock = idlock.read().await; + // let mut idlock = *idlock; + // let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + let ta = idlock.promote(arg2.unwrap().to_string().to_lowercase(), None, Some(UserRole::BotAdmin)).await; + + match ta { + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + let outmsg = &format!("o7 Successfully promoted : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // let outmsg = "o7 Successfully promoted : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + let outmsg = &format!("PoroSad failed to promote : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // let outmsg = "PoroSad failed to promote : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + let outmsg = &format!("uuh No Promotion Change : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // let outmsg = "uuh No Promotion Change : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + + } + } + } // if usrroles.contains(&UserRole::BotAdmin) + } + + // }, + Some(arg1) => { + // In the case of promoting another chatter + // Check caller's roles + // Check targer chatter's roles + // - Also check if target chatter alread has target roles + // if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin) + // if caller is BotAdmin, they can promote BotAdmins to Mod + // if caller's role is Broadcaster, BotAdmin, they can Promote target Mod to SupMod + botinstance::botlog::debug(&format!("Evaluating arg1: {arg1}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + + let idlock = Arc::clone(&bot.read().await.get_identity()); + let idlock = idlock.read().await; + // let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + + let senderroles = idlock.getspecialuserroles( + msg.sender.name.to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + + let trgusrroles = idlock.getspecialuserroles( + arg1.to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + + botinstance::botlog::debug(&format!("Ready to evaluate sender and targer user roles"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + + botinstance::botlog::trace(&format!("Related Vars : sender roles : {:?} ; targer usr roles : {:?}" , + senderroles,trgusrroles), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + + if ( senderroles.contains(&UserRole::Broadcaster) || + senderroles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) || + senderroles.contains(&UserRole::BotAdmin) ) && + ( !trgusrroles.contains(&UserRole::Broadcaster) && + // !trgusrroles.contains(&UserRole::BotAdmin) && // target users that are BotAdmins can promote themselves to Mod or SupMod + !trgusrroles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) && + !trgusrroles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) + ) + { + // if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin) + botinstance::botlog::trace(&format!("Attempting promote..."), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + let ta = idlock.promote(arg1.to_string().to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase())), + Some(UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase())))).await; + + match ta { + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + let outmsg = &format!("Successful Promotion : {a}"); + botinstance::botlog::debug(&format!("Successful Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "o7 Successfully promoted : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + let outmsg = &format!("PoroSad failed to promote : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // Log::flush(); + // let outmsg = "PoroSad failed to promote : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + let outmsg = &format!("uuh Not making any changes : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "uuh No Promotion Change : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + + } + + } else if trgusrroles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) && + ( senderroles.contains(&UserRole::Broadcaster) || + senderroles.contains(&UserRole::BotAdmin) ) + { + botinstance::botlog::trace(&format!("Attempting promote..."), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + + // broadcaster & botadmins can make mods into SupMod + let ta = idlock.promote(arg1.to_string().to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase())), + Some(UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase())))).await; + + match ta { + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + let outmsg = &format!("Successful Promotion : {a}"); + botinstance::botlog::debug(&format!("Successful Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "o7 Successfully promoted : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + let outmsg = &format!("PoroSad failed to promote : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // Log::flush(); + // let outmsg = "PoroSad failed to promote : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + let outmsg = &format!("uuh No Change in Promotion : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "uuh No Promotion Change : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + + } + + } else if trgusrroles.contains(&UserRole::Broadcaster) // This should always be NoChange + { + botinstance::botlog::trace(&format!("Attempting promote..."), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + + // broadcaster & botadmins can make mods into superadmins + let ta = idlock.promote(arg1.to_string().to_lowercase(), + Some(ChType::Channel(msg.channel_login.to_lowercase())), + Some(UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase())))).await; + + match ta { + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + let outmsg = &format!("Successful Promotion : {a}"); + botinstance::botlog::debug(&format!("Successful Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "o7 Successfully promoted : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + let outmsg = &format!("PoroSad failed to promote : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + // Log::flush(); + // let outmsg = "PoroSad failed to promote : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + let outmsg = &format!("uuh No Change in Promotion : {a}"); + botinstance::botlog::debug(outmsg, + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + Log::flush(); + // let outmsg = "uuh No Promotion Change : ".to_string(); + bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + + } + } + + else { + let s = botlog::fatal("Reached unreachable else", + Some("identity > cmd_promote()".to_string()), Some(&msg)); + panic!("{}",s); + }; + + Log::flush(); + + } + _ => (), } - /* - match arg1 { - Some(a1) if a1 == String::from("-admin") => { - // - [x] BotAdmins can promote admin to give BotAdmin UserRole - let botlock = bot.read().await; - let idlock = botlock.get_identity(); - let id = idlock.read().await; - // let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))); - // let ta = ta.getspecialuserroles(arg2.unwrap().to_string(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); - let rolesfut = id.getspecialuserroles( - msg.sender.name.to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase()))); - let usrroles = rolesfut.await; - // let ta = ta.unwrap(); - // let a = ta.read().await; - // let ta = *ta; - // let ta = *ta; - // if let Some(a) = *ta { + let arg2 = argv.next(); - if usrroles.contains(&UserRole::BotAdmin) { - // println!("BotAdmin allowed to promote admin"); - botinstance::botlog::debug("BotAdmin allowed to promote admin", - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - - { - - let idlock = Arc::clone(&bot.read().await.get_identity()); - // let idlock = idlock.write().await; - let idlock = idlock.read().await; - // let mut idlock = *idlock; - // let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; - let ta = idlock.promote(arg2.unwrap().to_string().to_lowercase(), None, Some(UserRole::BotAdmin)).await; - - match ta { - ChangeResult::Success(a) => { - // println!("Succesfully promoted : {a} ;"); - let outmsg = &format!("o7 Successfully promoted : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // let outmsg = "o7 Successfully promoted : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::Failed(a) => { - // println!("Failed to promote : {a} ; "); - let outmsg = &format!("PoroSad failed to promote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // let outmsg = "PoroSad failed to promote : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::NoChange(a) => { - // println!("No Changes Made : {a} ; "); - let outmsg = &format!("uuh No Promotion Change : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // let outmsg = "uuh No Promotion Change : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - - } - } - } // if usrroles.contains(&UserRole::BotAdmin) - } - - // }, - Some(arg1) => { - // In the case of promoting another chatter - // Check caller's roles - // Check targer chatter's roles - // - Also check if target chatter alread has target roles - // if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin) - // if caller is BotAdmin, they can promote BotAdmins to Mod - // if caller's role is Broadcaster, BotAdmin, they can Promote target Mod to SupMod - botinstance::botlog::debug(&format!("Evaluating arg1: {arg1}"), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - - let idlock = Arc::clone(&bot.read().await.get_identity()); - let idlock = idlock.read().await; - // let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; - - let senderroles = idlock.getspecialuserroles( - msg.sender.name.to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - - let trgusrroles = idlock.getspecialuserroles( - arg1.to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - - botinstance::botlog::debug(&format!("Ready to evaluate sender and targer user roles"), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - - botinstance::botlog::trace(&format!("Related Vars : sender roles : {:?} ; targer usr roles : {:?}" , - senderroles,trgusrroles), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - - if ( senderroles.contains(&UserRole::Broadcaster) || - senderroles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) || - senderroles.contains(&UserRole::BotAdmin) ) && - ( !trgusrroles.contains(&UserRole::Broadcaster) && - // !trgusrroles.contains(&UserRole::BotAdmin) && // target users that are BotAdmins can promote themselves to Mod or SupMod - !trgusrroles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) && - !trgusrroles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) - ) - { - // if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin) - botinstance::botlog::trace(&format!("Attempting promote..."), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - let ta = idlock.promote(arg1.to_string().to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase())), - Some(UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase())))).await; - - match ta { - ChangeResult::Success(a) => { - // println!("Succesfully promoted : {a} ;"); - let outmsg = &format!("Successful Promotion : {a}"); - botinstance::botlog::debug(&format!("Successful Promotion : {a}"), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "o7 Successfully promoted : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::Failed(a) => { - // println!("Failed to promote : {a} ; "); - let outmsg = &format!("PoroSad failed to promote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // Log::flush(); - // let outmsg = "PoroSad failed to promote : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::NoChange(a) => { - // println!("No Changes Made : {a} ; "); - let outmsg = &format!("uuh Not making any changes : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "uuh No Promotion Change : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - - } - - } else if trgusrroles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) && - ( senderroles.contains(&UserRole::Broadcaster) || - senderroles.contains(&UserRole::BotAdmin) ) - { - botinstance::botlog::trace(&format!("Attempting promote..."), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - - // broadcaster & botadmins can make mods into SupMod - let ta = idlock.promote(arg1.to_string().to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase())), - Some(UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase())))).await; - - match ta { - ChangeResult::Success(a) => { - // println!("Succesfully promoted : {a} ;"); - let outmsg = &format!("Successful Promotion : {a}"); - botinstance::botlog::debug(&format!("Successful Promotion : {a}"), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "o7 Successfully promoted : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::Failed(a) => { - // println!("Failed to promote : {a} ; "); - let outmsg = &format!("PoroSad failed to promote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // Log::flush(); - // let outmsg = "PoroSad failed to promote : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::NoChange(a) => { - // println!("No Changes Made : {a} ; "); - let outmsg = &format!("uuh No Change in Promotion : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "uuh No Promotion Change : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - - } - - } else if trgusrroles.contains(&UserRole::Broadcaster) // This should always be NoChange - { - botinstance::botlog::trace(&format!("Attempting promote..."), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - - // broadcaster & botadmins can make mods into superadmins - let ta = idlock.promote(arg1.to_string().to_lowercase(), - Some(ChType::Channel(msg.channel_login.to_lowercase())), - Some(UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase())))).await; - - match ta { - ChangeResult::Success(a) => { - // println!("Succesfully promoted : {a} ;"); - let outmsg = &format!("Successful Promotion : {a}"); - botinstance::botlog::debug(&format!("Successful Promotion : {a}"), - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "o7 Successfully promoted : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::Failed(a) => { - // println!("Failed to promote : {a} ; "); - let outmsg = &format!("PoroSad failed to promote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - // Log::flush(); - // let outmsg = "PoroSad failed to promote : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - ChangeResult::NoChange(a) => { - // println!("No Changes Made : {a} ; "); - let outmsg = &format!("uuh No Change in Promotion : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); - Log::flush(); - // let outmsg = "uuh No Promotion Change : ".to_string(); - bot.read().await.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - - } - } - - else { - let s = botlog::fatal("Reached unreachable else", - Some("identity > cmd_promote()".to_string()), Some(&msg)); - panic!("{}",s); - }; - - Log::flush(); - - } - _ => (), - } - - - - let arg2 = argv.next(); - - let targetchnl = arg2; - - */ - - - botinstance::botlog::trace(&format!("End of cmd_promote()"), - Some("identity.rs > cmd_prommote()".to_string()), None); + let targetchnl = arg2; + */ + botinstance::botlog::trace( + &format!("End of cmd_promote()"), + Some("identity.rs > cmd_prommote()".to_string()), + None, + ); } // BotCommand { @@ -479,53 +503,55 @@ pub async fn init(mgr:Arc) // }.add_to_modmgr(Arc::clone(&mgr)); let tempb = BotCommand { - module : BotModule(String::from("identity")), - command : String::from("demote"), // command call name - alias : vec![], // String of alternative names - exec_body : actions_util::asyncbox(cmd_demote) , - help : String::from("demote"), - required_roles : vec![ + module: BotModule(String::from("identity")), + command: String::from("demote"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(cmd_demote), + help: String::from("demote"), + required_roles: vec![ UserRole::Mod(ChType::Channel(String::new())), UserRole::SupMod(ChType::Channel(String::new())), UserRole::Broadcaster, UserRole::BotAdmin, - ], + ], }; - + tempb.add_to_modmgr(Arc::clone(&mgr)).await; // async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { - async fn cmd_demote(mut bot:BotAR,msg:PrivmsgMessage) { + async fn cmd_demote(mut bot: BotAR, msg: PrivmsgMessage) { // println!("Called cmd demote"); - botinstance::botlog::debug("Called cmd demote", - Some("identity.rs > cmd_demote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + "Called cmd demote", + Some("identity.rs > cmd_demote()".to_string()), + Some(&msg), + ); Log::flush(); - + // -- If the BotCommand.command was called (e.g., demote) & required roles were validated OUTSIDE of this call // , this is the current function body to execute /* - `promote` / `demote` - [ ] `SupMod` & `Broadcaster` & `BotAdmin` can run - - [ ] `UserRole`s that can run, can + - [ ] `UserRole`s that can run, can - [ ] run `promote` on a regular `Chatter` to make them a `Mod` - [ ] run `demote` on a `Mod` to make them a `Chatter` - - [ ] Only `BotAdmin` can : + - [ ] Only `BotAdmin` can : - [ ] target themselves to `promote` / `demote` , in the case that they want to make themselves either a `Mod` or `SupMod` for the channel temporarily - - [ ] `promote admin ` to assign them `BotAdmin` role + - [ ] `promote admin ` to assign them `BotAdmin` role - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` or `promote` the other way */ - /* - Usage : + Usage : promote - demote + demote promote -admin - + */ // [ ] #TODO : Need to define the body that calls demote() @@ -533,27 +559,23 @@ pub async fn init(mgr:Arc) // [x] Unwraps arguments from message // let mut argv = msg.message_text.split(" "); - + // argv.next(); // Skip the command name // let arg1 = argv.next(); - // let arg2 = argv.next(); - - let (arg1,arg2) = { - + let (arg1, arg2) = { let mut argv = msg.message_text.split(" "); - + argv.next(); // Skip the command name - + let arg1 = argv.next(); let arg2 = argv.next(); - (arg1,arg2) - + (arg1, arg2) }; /* @@ -571,45 +593,43 @@ pub async fn init(mgr:Arc) // --- /* - => 2024.02.15 - The business logic seems embeded straight into demote() with the following in mind : - - demote() atm doesn't take sender ChatBadge <-- the assumption is canuserrun() was done - for this user, and automatically assigned any roles that should get auto assigned - - demote() returns a ChangeResult + => 2024.02.15 - The business logic seems embeded straight into demote() with the following in mind : + - demote() atm doesn't take sender ChatBadge <-- the assumption is canuserrun() was done + for this user, and automatically assigned any roles that should get auto assigned + - demote() returns a ChangeResult - - [ ] So I think all I need to do here is parse out and pass input args to demote(), and output quirky messages based on ChangeResult - - - [x] 1. Parse out the following - - Sender (e.g., Name & Badge) - - Target User (arg1) - - Target Channel (current channel) - - Msg or Msg.Message_Text (for later) - - - [x] 2. Run Demote() - - within demote(), getspecialuserroles() is called on both the sender and the target - - getspecialuserroles() only sends current db , while canuserrun() may change db depending on the most current state of the sender - - getspecialuserroles also borrows the sender's badge to evaluate + - [ ] So I think all I need to do here is parse out and pass input args to demote(), and output quirky messages based on ChangeResult - - [ ] 3. Take ChangeResult and output response - + - [x] 1. Parse out the following + - Sender (e.g., Name & Badge) + - Target User (arg1) + - Target Channel (current channel) + - Msg or Msg.Message_Text (for later) - */ + - [x] 2. Run Demote() + - within demote(), getspecialuserroles() is called on both the sender and the target + - getspecialuserroles() only sends current db , while canuserrun() may change db depending on the most current state of the sender + - getspecialuserroles also borrows the sender's badge to evaluate + - [ ] 3. Take ChangeResult and output response + + + */ /* - - + + - [x] 1. Parse out the following - Sender (e.g., Name & Badge) - Target User (arg1) - Target Channel (current channel) - (no need) Msg or Msg.Message_Text (for later) - - */ + */ let sendername = msg.clone().sender.name; - let mut sender_badge_mut:Option = None; + let mut sender_badge_mut: Option = None; for b in &msg.badges { if b.name == "moderator" { @@ -626,76 +646,75 @@ pub async fn init(mgr:Arc) let targetchnl = msg.channel_login.to_lowercase(); /* - + - [x] 2. Run Demote() - within demote(), getspecialuserroles() is called on both the sender and the target - getspecialuserroles() only sends current db , while canuserrun() may change db depending on the most current state of the sender - getspecialuserroles also borrows the sender's badge to evaluate - + */ - // [x] Get a required lock first - - let botlock = bot.read().await; - let id = botlock.get_identity(); - let idlock = id.read().await; - + // [x] Get a required lock first + let botlock = bot.read().await; + let id = botlock.get_identity(); + let idlock = id.read().await; let rslt = match targetusr { Some(targetusr) => { - - botinstance::botlog::debug(&format!("running demote()"), - Some("identity.rs > cmd_demote()".to_string()), None); + botinstance::botlog::debug( + &format!("running demote()"), + Some("identity.rs > cmd_demote()".to_string()), + None, + ); Log::flush(); - idlock.demote( - sendername.clone(), - &sender_badge, - targetusr.to_string(), - Some(ChType::Channel(targetchnl.clone()))).await + idlock + .demote( + sendername.clone(), + &sender_badge, + targetusr.to_string(), + Some(ChType::Channel(targetchnl.clone())), + ) + .await } None => { - - botinstance::botlog::debug(&format!("No Targer User argument"), - Some("identity.rs > cmd_demote()".to_string()), None); + botinstance::botlog::debug( + &format!("No Targer User argument"), + Some("identity.rs > cmd_demote()".to_string()), + None, + ); Log::flush(); ChangeResult::NoChange("No Targer User".to_string()) - } - }; /* - - - [x] 3. Take ChangeResult and output response - - */ + - [x] 3. Take ChangeResult and output response + + */ // let senderUserRole = { - // // note : getspecialuserroles will cover : + // // note : getspecialuserroles will cover : // // - Internal roles stored at db for Mod & SupMod & BotAdmin // // - Broadcaster (based on target hchatter & channel) // // It MAY NOT COVER sutations where Sender has a Mod Badge, but not in DB yet as Mod // // - So ideally this covers that (at least returns that they're a mod and go ahead and run for now) // // - [ ] #TODO : This should also go ahead and add that mod to DB if possible as channel mod - - // // let evalroles = vec![]; // let evalroles = match sender_badge { // Some(ChatBadge::Mod) => { - // let mut rslroles = idlock.getspecialuserroles( - // sendername.clone(), + // sendername.clone(), // Some(ChType::Channel(targetchnl.clone()))).await; // rslroles.push(UserRole::Mod(ChType::Channel(targetchnl))); @@ -704,87 +723,103 @@ pub async fn init(mgr:Arc) // }, // _ => { // idlock.getspecialuserroles( - // sendername, + // sendername, // Some(ChType::Channel(targetchnl.clone()))).await // } // }; - // // => 02.16 - I think better would just migrate over the logic within demote - // // - If there's business reqs to evaluate , better to keep the ChangeResult + // // => 02.16 - I think better would just migrate over the logic within demote + // // - If there's business reqs to evaluate , better to keep the ChangeResult // // consistent and also pass ChatBadge // }; // senderUserRole - - - match rslt { ChangeResult::Success(a) => { // println!("Succesfully promoted : {a} ;"); let outmsg = &format!("o7 Successfully demoted : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_demote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_demote()".to_string()), + Some(&msg), + ); // let outmsg = "o7 Successfully promoted : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } ChangeResult::Failed(a) => { // println!("Failed to promote : {a} ; "); let outmsg = &format!("PoroSad failed to demote : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_demote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_demote()".to_string()), + Some(&msg), + ); // let outmsg = "PoroSad failed to promote : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } ChangeResult::NoChange(a) => { // println!("No Changes Made : {a} ; "); let outmsg = &format!("uuh No Demotion Change : {a}"); - botinstance::botlog::debug(outmsg, - Some("identity.rs > cmd_demote()".to_string()), Some(&msg)); + botinstance::botlog::debug( + outmsg, + Some("identity.rs > cmd_demote()".to_string()), + Some(&msg), + ); // let outmsg = "uuh No Promotion Change : ".to_string(); - botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; - }, - - + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + } } // println!("tester"); // println!("tester2"); - } - let tempcomm = BotCommand { - module : BotModule(String::from("identity")), - command : String::from("getroles"), // command call name - alias : vec![], // String of alternative names - exec_body : actions_util::asyncbox(getroles) , - help : String::from("getroles"), - required_roles : vec![ + let tempcomm = BotCommand { + module: BotModule(String::from("identity")), + command: String::from("getroles"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(getroles), + help: String::from("getroles"), + required_roles: vec![ UserRole::Mod(ChType::Channel(String::new())), UserRole::SupMod(ChType::Channel(String::new())), UserRole::Broadcaster, UserRole::BotAdmin, - ], + ], }; - + tempcomm.add_to_modmgr(Arc::clone(&mgr)).await; - - // async fn getroles(bot:Arc>,msg:PrivmsgMessage) { - async fn getroles(bot:BotAR,msg:PrivmsgMessage) { + async fn getroles(bot: BotAR, msg: PrivmsgMessage) { // println!("Called cmd getroles"); - botinstance::botlog::debug("Called cmd getroles", - Some("identity.rs > cmd_getroles()".to_string()), Some(&msg)); + botinstance::botlog::debug( + "Called cmd getroles", + Some("identity.rs > cmd_getroles()".to_string()), + Some(&msg), + ); /* Usage getroles - - If channel is provided, provide roles for that channel specifically + - If channel is provided, provide roles for that channel specifically */ - // IN other code areas , I see this + // IN other code areas , I see this // ServerMessage::Privmsg(msg) => { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -795,7 +830,6 @@ pub async fn init(mgr:Arc) // println!("args : {v}"); // } - argv.next(); // Skip the command name let arg1 = argv.next(); @@ -804,9 +838,8 @@ pub async fn init(mgr:Arc) // return ; // Do nothing if no arguments // } - let targetuser = match arg1 { - None => return , // exit if no arguments + None => return, // exit if no arguments Some(arg) => arg, }; @@ -815,7 +848,6 @@ pub async fn init(mgr:Arc) // _ => (), // } - // match argv[1] { // String::from("admin") => (), @@ -823,7 +855,7 @@ pub async fn init(mgr:Arc) let arg2 = argv.next(); - let targetchnl = arg2; + let targetchnl = arg2; // // let a = bot.read().ok().unwrap().get_identity(); // let a = bot.lock().await; @@ -848,16 +880,25 @@ pub async fn init(mgr:Arc) // let a = bot.get_identity(); let botlock = bot.read().await; // println!("botlock read"); - botinstance::botlog::trace("botlock read", - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + botinstance::botlog::trace( + "botlock read", + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); let idlock = botlock.get_identity(); // println!("got identity"); - botinstance::botlog::trace("got identity", - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + botinstance::botlog::trace( + "got identity", + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); let idlock = idlock.read().await; // <-- 02.12 - Latest where it gest stuck - before or at this point - // println!("id lock"); - botinstance::botlog::trace("id lock", - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + // println!("id lock"); + botinstance::botlog::trace( + "id lock", + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); let sproles = match targetchnl { None => { // let bot = Rc::clone(&bot); @@ -873,8 +914,13 @@ pub async fn init(mgr:Arc) // idlock.getspecialuserroles(String::from(targetuser),None).await // [ ] If targetchnl is not provided, default to pulling the current channel - idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(msg.channel_login.to_lowercase()))).await - }, + idlock + .getspecialuserroles( + String::from(targetuser), + Some(ChType::Channel(msg.channel_login.to_lowercase())), + ) + .await + } Some(targetchnl) => { // let bot = Rc::clone(&bot); // let bot = Arc::clone(&bot); @@ -908,75 +954,99 @@ pub async fn init(mgr:Arc) // } // _ => { - + // } - // } + // } // [x]gets special roles for caller - let callersproles = idlock.getspecialuserroles(msg.sender.name.to_lowercase(),Some(ChType::Channel(targetchnl.to_lowercase().to_string()))).await; + let callersproles = idlock + .getspecialuserroles( + msg.sender.name.to_lowercase(), + Some(ChType::Channel(targetchnl.to_lowercase().to_string())), + ) + .await; // idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(targetchnl.to_lowercase().to_string()))).await // let a = callersproles.contains(&UserRole::Mod(ChType::Channel(targetchnl.to_lowercase().to_string()))); - if callersproles.contains(&UserRole::Mod(ChType::Channel(targetchnl.to_lowercase().to_string()))) || - callersproles.contains(&UserRole::SupMod(ChType::Channel(targetchnl.to_lowercase().to_string()))) || - callersproles.contains(&&UserRole::Broadcaster) { - idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(targetchnl.to_lowercase()))).await + if callersproles.contains(&UserRole::Mod(ChType::Channel( + targetchnl.to_lowercase().to_string(), + ))) || callersproles.contains(&UserRole::SupMod(ChType::Channel( + targetchnl.to_lowercase().to_string(), + ))) || callersproles.contains(&&UserRole::Broadcaster) + { + idlock + .getspecialuserroles( + String::from(targetuser), + Some(ChType::Channel(targetchnl.to_lowercase())), + ) + .await // callersproles } else { // Otherwise, don't get the target channel, return the current channel instead - idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(msg.channel_login.to_lowercase()))).await + idlock + .getspecialuserroles( + String::from(targetuser), + Some(ChType::Channel(msg.channel_login.to_lowercase())), + ) + .await } - - - - }, + } }; // let sproles = idlock.getspecialuserroles(String::from(targetuser),).await; - // println!("Retrieved User Roles >> {:?}",sproles); - botinstance::botlog::debug(&format!("User roles of Target Chatter >> {:?}",sproles), - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); - + botinstance::botlog::debug( + &format!("User roles of Target Chatter >> {:?}", sproles), + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); + // # I believe at this stage I still have botlock active - botinstance::botlog::debug(&format!("Evaluating special roles"), - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + botinstance::botlog::debug( + &format!("Evaluating special roles"), + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); // let mut outmsg = String::new(); let sproles = sproles; // let arg2 = arg2.unwrap(); - let outmsg = if ((targetuser.to_lowercase() == msg.channel_login.to_lowercase()) && arg2.is_none()) || (arg2.is_some() && arg2.unwrap() == targetuser.to_lowercase()) - { - // First evaluates if they're broadcaster - let mut outmsg = format!("FeelsWowMan they're the broadcaster. "); - if sproles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) || - sproles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) || - sproles.contains(&UserRole::BotAdmin) { - outmsg = outmsg + &format!("Target chatter's user roles are : {:?}",sproles) ; - } - outmsg + let outmsg = if ((targetuser.to_lowercase() == msg.channel_login.to_lowercase()) + && arg2.is_none()) + || (arg2.is_some() && arg2.unwrap() == targetuser.to_lowercase()) + { + // First evaluates if they're broadcaster + let mut outmsg = format!("FeelsWowMan they're the broadcaster. "); + if sproles.contains(&UserRole::Mod(ChType::Channel( + msg.channel_login.to_lowercase(), + ))) || sproles.contains(&UserRole::SupMod(ChType::Channel( + msg.channel_login.to_lowercase(), + ))) || sproles.contains(&UserRole::BotAdmin) + { + outmsg = outmsg + &format!("Target chatter's user roles are : {:?}", sproles); } - - else if sproles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) || - sproles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) || - sproles.contains(&UserRole::BotAdmin) { - format!("Target chatter's user roles are : {:?}",sproles) - } - else { - format!("Target chatter has no special roles LULE ") - }; + outmsg + } else if sproles.contains(&UserRole::Mod(ChType::Channel( + msg.channel_login.to_lowercase(), + ))) || sproles.contains(&UserRole::SupMod(ChType::Channel( + msg.channel_login.to_lowercase(), + ))) || sproles.contains(&UserRole::BotAdmin) + { + format!("Target chatter's user roles are : {:?}", sproles) + } else { + format!("Target chatter has no special roles LULE ") + }; + // if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { - // if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { + // } else if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { - // } else if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { - - // } + // } - // let outmsg = match sproles + // let outmsg = match sproles // { // // let mut outmsg = String::new(); @@ -986,16 +1056,16 @@ pub async fn init(mgr:Arc) // format!("Target chatter's user roles are : {:?}",sproles) - // } + // } // None => { // // # NOTE : Broadcaster could be included in this // // # below is checking if the provided text includes the username // // let msg = msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase()); - // botinstance::botlog::debug(&format!("Evaluating special roles > channel login : {} ; message text : {} ; ",&msg.channel_login,&msg.message_text), + // botinstance::botlog::debug(&format!("Evaluating special roles > channel login : {} ; message text : {} ; ",&msg.channel_login,&msg.message_text), // Some("identity.rs > init > getroles()".to_string()), Some(&msg)); // botinstance::botlog::debug(&format!("Evaluating special roles > bool evaluation : {} ", - // msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase())), + // msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase())), // Some("identity.rs > init > getroles()".to_string()), Some(&msg)); // if msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase()) { @@ -1005,68 +1075,66 @@ pub async fn init(mgr:Arc) // } // } - + // }; // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot")))); // println!("{:?}",a); - botinstance::botlog::debug(&format!("Chat Say Reply message : {:?}",outmsg), - Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + botinstance::botlog::debug( + &format!("Chat Say Reply message : {:?}", outmsg), + Some("identity.rs > init > getroles()".to_string()), + Some(&msg), + ); botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg).await; - // [ ] NOTE : After the above, I should receive only the roles in the context of the current channel I received this ideally and maybe BotAdmin ; not outside - - + // [ ] NOTE : After the above, I should receive only the roles in the context of the current channel I received this ideally and maybe BotAdmin ; not outside } - - // println!("End of Init MOdule add"); - botinstance::botlog::trace("End of Init MOdule add", - Some("identity.rs > init ".to_string()), None); + botinstance::botlog::trace( + "End of Init MOdule add", + Some("identity.rs > init ".to_string()), + None, + ); Log::flush(); - } - // #[derive(Debug, PartialEq, Eq, Hash, Clone)] // pub enum ChType { // Channel(String), // } -#[derive(Debug, PartialEq, Eq , Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum UserRole { - Chatter, - Mod(ChType), // String specifies Channel - SupMod(ChType), // String specifies Channel - Broadcaster, - BotAdmin, - + Chatter, + Mod(ChType), // String specifies Channel + SupMod(ChType), // String specifies Channel + Broadcaster, + BotAdmin, } - pub enum Permissible { - Allow, - Block + Allow, + Block, } #[derive(Clone)] pub struct IdentityManager { // special_roles_users : HashMap>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel // special_roles_users : Arc>>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel - // special_roles_users : Arc>>>, - special_roles_users : Arc>>>>>, + // special_roles_users : Arc>>>, + special_roles_users: Arc>>>>>, // parent_mgr : Box, //parent_mgr : Option>, -} -/* +} +/* HashMap< String, <-- Chatter / Username Vec -- <-- Vectors are basically arrays > - -- [ ] + -- [ ] let a = vec![] modulatingforce : vec![UserRole::BotAdmin, @@ -1082,80 +1150,89 @@ pub enum ChatBadge { Mod, } -#[derive(Debug,PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum ChangeResult { Success(String), Failed(String), NoChange(String), } - impl IdentityManager { - pub fn init() -> IdentityManager { let mut a = HashMap::new(); for admn in adminvector() { - a.insert(admn.to_lowercase(),Arc::new(RwLock::new(vec![UserRole::BotAdmin]))); - }; + a.insert( + admn.to_lowercase(), + Arc::new(RwLock::new(vec![UserRole::BotAdmin])), + ); + } IdentityManager { - special_roles_users : Arc::new(RwLock::new(a)), + special_roles_users: Arc::new(RwLock::new(a)), //parent_mgr : None, } } - - async fn add_role(&self, trgchatter:String,trg_role:UserRole) - { - + async fn add_role(&self, trgchatter: String, trg_role: UserRole) { let mut srulock = self.special_roles_users.write().await; let mut usrrolelock = srulock .get_mut(&trgchatter) .expect("Error retrieving roles") - .write().await; - usrrolelock.push(trg_role); - + .write() + .await; + usrrolelock.push(trg_role); } - async fn remove_role(&self, trgchatter:String,trg_role:UserRole) - { - + async fn remove_role(&self, trgchatter: String, trg_role: UserRole) { let mut srulock = self.special_roles_users.write().await; let mut usrrolelock = srulock .get_mut(&trgchatter) .expect("Error retrieving roles") - .write().await; - if let Some(indx) = usrrolelock.iter().position(|value| *value == trg_role){ + .write() + .await; + if let Some(indx) = usrrolelock.iter().position(|value| *value == trg_role) { usrrolelock.swap_remove(indx); //return ChangeResult::Success("Demoted successfully".to_string()) } } - async fn affirm_chatter_in_db(&self, trgchatter:String) - { + async fn affirm_chatter_in_db(&self, trgchatter: String) { let mut srulock = self.special_roles_users.write().await; - srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - botinstance::botlog::trace(&format!("Ensuring User in Roles {:?}",srulock.entry(trgchatter.clone())), - Some("IdentityManager > affirm_chatter_in_db()".to_string()), None); + srulock + .entry(trgchatter.clone()) + .or_insert(Arc::new(RwLock::new(vec![]))); + botinstance::botlog::trace( + &format!( + "Ensuring User in Roles {:?}", + srulock.entry(trgchatter.clone()) + ), + Some("IdentityManager > affirm_chatter_in_db()".to_string()), + None, + ); Log::flush(); } - // [ ] Maybe I should create a can_user_run version that simply takes PrvMsg, but then calls can_user_run directly - - // pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Result> + + // pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Result> // pub fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible - // pub async fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible - pub async fn can_user_run_PRVMSG(&mut self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> (Permissible,ChangeResult) - { + // pub async fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible + pub async fn can_user_run_PRVMSG( + &mut self, + msg: &PrivmsgMessage, + cmdreqroles: Vec, + ) -> (Permissible, ChangeResult) { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // [ ] Check what Badges in PrivmsgMessage // println!{"Checking within PRVMSG"}; - botinstance::botlog::debug("Checking within PRVMSG", - Some("identity.rs > can_user_run_PRVMSG()".to_string()), Some(&msg)); + botinstance::botlog::debug( + "Checking within PRVMSG", + Some("identity.rs > can_user_run_PRVMSG()".to_string()), + Some(&msg), + ); - let mut sender_badge:Option = None; + let mut sender_badge: Option = None; for b in &msg.badges { if b.name == "moderator" { @@ -1172,317 +1249,396 @@ impl IdentityManager { // if let Some(sender_badge) = sender_badge { // match sender_badge { // Some(sender_badge) => { - // return &self.can_user_run(msg.sender.name.to_owned(), - // ChType::Channel(msg.channel_login.to_owned()), - // sender_badge, - // cmdreqroles - // return self.can_user_run(msg.sender.name.to_owned(), - // let a = Arc::new(Mutex::new(self)); - // let mut a = a.lock().await; - // let a = **a; - // let a = a.can_user_run(msg.sender.name.to_owned(), - // ChType::Channel(msg.channel_login.to_owned()), - // sender_badge, - // cmdreqroles - // ) ; - // let a = *self; - // let a = Arc::new(Mutex::new(a)); - // let a = a.lock().await.can_user_run(msg.sender.name.to_owned(), - // ChType::Channel(msg.channel_login.to_owned()), - // sender_badge, - // cmdreqroles - // ) ; - // return a; - // return self.can_user_run(msg.sender.name.to_owned(), - // ChType::Channel(msg.channel_login.to_owned()), - // sender_badge, - // cmdreqroles - // ).await + // return &self.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // return self.can_user_run(msg.sender.name.to_owned(), + // let a = Arc::new(Mutex::new(self)); + // let mut a = a.lock().await; + // let a = **a; + // let a = a.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // ) ; + // let a = *self; + // let a = Arc::new(Mutex::new(a)); + // let a = a.lock().await.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // ) ; + // return a; + // return self.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // ).await + // * NOTE : We're preferring to pass the ChangeResult up , where we have access to Chat via BotInstance + // that have more strained chatting rules + // let evalpermissible = self.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // ).await ; + // evalpermissible + // // } + // None => { - // * NOTE : We're preferring to pass the ChangeResult up , where we have access to Chat via BotInstance - // that have more strained chatting rules - // let evalpermissible = self.can_user_run(msg.sender.name.to_owned(), - // ChType::Channel(msg.channel_login.to_owned()), - // sender_badge, - // cmdreqroles - // ).await ; - // evalpermissible - // // } - // None => { - - // } + // } // here , sender_badge is likely None // This could be a regular chatter, BotAdmin,SupserMod - - // [ ] Call can_user_run() // (self,Permissible::Block) // (Permissible::Block,ChangeResult::NoChange("".to_string())) - - self.can_user_run(msg.sender.name.to_owned(), - ChType::Channel(msg.channel_login.to_owned()), - sender_badge, - cmdreqroles - ).await + self.can_user_run( + msg.sender.name.to_owned(), + ChType::Channel(msg.channel_login.to_owned()), + sender_badge, + cmdreqroles, + ) + .await } - - pub async fn can_user_run(&mut self, - usr:String, - channelname:ChType, - chat_badge:Option, - cmdreqroles:Vec - // ) -> Result> { - ) -> (Permissible,ChangeResult) { - - // println!{"Checking within can_user_run()"}; - botinstance::botlog::debug(&format!("Checking within can_user_run() : + pub async fn can_user_run( + &mut self, + usr: String, + channelname: ChType, + chat_badge: Option, + cmdreqroles: Vec, // ) -> Result> { + ) -> (Permissible, ChangeResult) { + // println!{"Checking within can_user_run()"}; + botinstance::botlog::debug( + &format!( + "Checking within can_user_run() : usr : {} ; channel : {:?} ; badge : {:?} ; cmdreqroles : {:?}", - usr,channelname,chat_badge,cmdreqroles), - Some("identity.rs > can_user_run()".to_string()), None); - /* - canUserRun - + usr, channelname, chat_badge, cmdreqroles + ), + Some("identity.rs > can_user_run()".to_string()), + None, + ); + /* + canUserRun - - Input : - usr:String, - channelname:ChType, - chat_badge:ChatBadge, - cmdreqroles:Vec + Input : + usr:String, + channelname:ChType, + chat_badge:ChatBadge, + cmdreqroles:Vec - Output : Result> - Some Possible outcomes : Ok(Permissible::Allow) , Ok(Permissible::Block) + Output : Result> + Some Possible outcomes : Ok(Permissible::Allow) , Ok(Permissible::Block) - Description - For a Given Chatter (with any special ChatBadge) who ran the Command at a Given Channel , check if that user can - run the command based on the given cmdreqroles required by the command + Description + For a Given Chatter (with any special ChatBadge) who ran the Command at a Given Channel , check if that user can + run the command based on the given cmdreqroles required by the command - Inputs and business logic determine if the user can run the command based on the command's required roles - */ + Inputs and business logic determine if the user can run the command based on the command's required roles + */ + // Requirements + /* + [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) + [x] If chatBadge::Broadcaster ... + [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) + [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) + [x] If chatBadge::Mod ... + [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) + [x] If not, assign them UserRole::Mod(channelname::ChType) + [x] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) + [x] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) + [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) + [x] Otherwise, Ok(Permissible::Block) + */ - // Requirements - /* - [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) - [x] If chatBadge::Broadcaster ... - [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) - [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) - [x] If chatBadge::Mod ... - [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) - [x] If not, assign them UserRole::Mod(channelname::ChType) - [x] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) - [x] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) - [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) - [x] Otherwise, Ok(Permissible::Block) - */ + // [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) - // [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) + // let idar = Arc::new(RwLock::new(self)); - // let idar = Arc::new(RwLock::new(self)); + let usr = usr.to_lowercase(); - let usr = usr.to_lowercase(); - - if cmdreqroles.len() == 0 { - // return Ok(Permissible::Allow) - return (Permissible::Allow , ChangeResult::NoChange("Command has no required cmdreqroles".to_string())) - } - - - let mut modrolechange = ChangeResult::NoChange("".to_string()); - - - match chat_badge { - - // [x] If chatBadge::Broadcaster ... - // [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) - // [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) - - Some(ChatBadge::Broadcaster) => { - if cmdreqroles.contains(&UserRole::Broadcaster) || - cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) || - cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { - // return Ok(Permissible::Allow) - return (Permissible::Allow , ChangeResult::NoChange("Broadcaster Role".to_string())) - } - }, - - // [x] If chatBadge::Mod ... - // [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) - // [x] If not, assign them UserRole::Mod(channelname::ChType) - - Some(ChatBadge::Mod) => { - - // println!("Mod Chatbadge detected"); - botinstance::botlog::info("Mod Chatbadge detected", - Some("identity.rs > can_user_run()".to_string()), None); - - // println!("debug special roles : {:?}",self.special_roles_users); - // println!("debug usr : {}",&usr.to_lowercase()); - - // let Some((k,v)) = self.special_roles_users.get_key_value(usr); - // match self.special_roles_users.get_mut(&usr.to_lowercase()) { - // match self.special_roles_users.get(&usr.to_lowercase()) { - // println!("Creating clone"); - botinstance::botlog::trace("Creating arc clone", - Some("identity.rs > can_user_run()".to_string()), None); - - let roleslock = Arc::clone(&(*self).special_roles_users); - - // println!("Read lock on : Special_Roles_User"); // <-- after this is slightly different between working and problem - botinstance::botlog::trace("Read lock on : Special_Roles_User", - Some("identity.rs > can_user_run()".to_string()), None); - - // { - - // // If target user doesn't exist in special_roles_users , add with blank vector roles - // let mut srulock = self.special_roles_users.write().await; - // srulock.entry(usr.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(usr.clone())), - // Some("identity.rs > promote()".to_string()), None); - // Log::flush(); - // } - self.affirm_chatter_in_db(usr.clone()).await; - - let mut roleslock = roleslock.write().await; - match (*roleslock).get(&usr.to_lowercase()) { - Some(usrroles) if - usrroles.read().await.contains(&UserRole::Mod(channelname.clone())) || - usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())) => { // <-- working got to this point - // println!("contains mod : {}", usrroles.read().await.contains(&UserRole::Mod(channelname.clone()))); - // println!("contains supmod : {}", usrroles.read().await.contains(&UserRole::SupMod(channelname.clone()))); - - // Do nothing when theh have a mod badge and have either a supmod or mod badge for the channel - // println!("Already a mod in roles"); - botinstance::botlog::trace("Already a mod in roles", - Some("identity.rs > can_user_run()".to_string()), None); - - } - _ => { - // In the event they have a mod badge , are running a bot command, but don't have a channel mod role yet... - // println!("lock created > adding with a mod role o7"); - botinstance::botlog::trace("lock created > adding with a mod role o7", - Some("identity.rs > can_user_run()".to_string()), None); - - // botinstance::botlog::notice("Assigning ModRole to Chatter", - // Some("identity.rs > can_user_run()".to_string()), None); - - let mut roleslock = roleslock; - let mut a = roleslock.get_mut(&usr.to_lowercase()).unwrap(); - let mut alock = a.write().await; - - alock.push(UserRole::Mod(channelname.clone())); - - modrolechange = ChangeResult::Success("Auto Promoted Mod".to_string()); - - // alock.get_mut(&usr.to_lowercase()) - // .get_or_insert_with(|| UserRole::Mod(channelname.clone())) - // // .expect("ERROR") - // .unwrap() - // .write().await - // // .get_mut() - // .push(UserRole::Mod(channelname.clone())); - } // <-- I'm assuming problem got to here - } - - }, - _ => (), // Don't handle other roles here - } - - // [x] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) - - // println!("cmd required roles : {:?}",cmdreqroles); - botinstance::botlog::trace(&format!("cmd required roles : {:?}",cmdreqroles), - Some("identity.rs > can_user_run()".to_string()), None); - - if cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) { - // match self.special_roles_users.get(&channelname) { - // Some(usrroles) => {}, - // None => (), - - // } - - // println!("Command requires Mod Role"); - botinstance::botlog::trace("Command requires Mod Role", - Some("identity.rs > can_user_run()".to_string()), None); - - if let Some(a) = (&*self).special_roles_users.read().await.get(&usr.to_lowercase()) { - // println!("Special roles found for user"); - botinstance::botlog::trace("Special roles found for user", - Some("identity.rs > can_user_run()".to_string()), None); - - if a.read().await.contains(&UserRole::Mod(channelname.clone())) || a.read().await.contains(&UserRole::SupMod(channelname.clone())){ - // return Ok(Permissible::Allow); - // println!("Special roles found for user : A mod idenfified "); - botinstance::botlog::trace("> Special Role Identified : Mod ", - Some("identity.rs > can_user_run()".to_string()), None); - return (Permissible::Allow , modrolechange) - } - } - } - - - // [x] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) - - - if cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { - if let Some(a) = (&*self).special_roles_users.read().await.get(&usr.to_lowercase()) { - if a.read().await.contains(&UserRole::SupMod(channelname.clone())) { - // return Ok(Permissible::Allow); - return (Permissible::Allow,modrolechange) - } - } - } - - - // [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) - - // println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); - botinstance::botlog::trace(&format!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)), - Some("identity.rs > can_user_run()".to_string()), None); - - if cmdreqroles.contains(&UserRole::BotAdmin) { - // println!("special roles get : {:?}",(&*self).special_roles_users.read().await.get(&usr.to_lowercase())); - botinstance::botlog::trace(&format!("special roles get : {:?}",(&*self).special_roles_users.read().await.get(&usr.to_lowercase())), - Some("identity.rs > can_user_run()".to_string()), None); - - - - if let Some(a) = (&*self).special_roles_users.read().await.get(&usr.to_lowercase()) { - println!("special roles contains BotAdmin: {}",a.read().await.contains(&UserRole::BotAdmin)); - botinstance::botlog::trace(&format!("special roles contains BotAdmin: {}",a.read().await.contains(&UserRole::BotAdmin)), - Some("identity.rs > can_user_run()".to_string()), None); - - if a.read().await.contains(&UserRole::BotAdmin) { - // return Ok(Permissible::Allow); - return (Permissible::Allow,modrolechange) - } - } - } - - (Permissible::Block , ChangeResult::NoChange("Not any permissiable condition".to_string())) + if cmdreqroles.len() == 0 { + // return Ok(Permissible::Allow) + return ( + Permissible::Allow, + ChangeResult::NoChange("Command has no required cmdreqroles".to_string()), + ); } + let mut modrolechange = ChangeResult::NoChange("".to_string()); + + match chat_badge { + // [x] If chatBadge::Broadcaster ... + // [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) + // [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) + Some(ChatBadge::Broadcaster) => { + if cmdreqroles.contains(&UserRole::Broadcaster) + || cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) + || cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) + { + // return Ok(Permissible::Allow) + return ( + Permissible::Allow, + ChangeResult::NoChange("Broadcaster Role".to_string()), + ); + } + } + + // [x] If chatBadge::Mod ... + // [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) + // [x] If not, assign them UserRole::Mod(channelname::ChType) + Some(ChatBadge::Mod) => { + // println!("Mod Chatbadge detected"); + botinstance::botlog::info( + "Mod Chatbadge detected", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + // println!("debug special roles : {:?}",self.special_roles_users); + // println!("debug usr : {}",&usr.to_lowercase()); + + // let Some((k,v)) = self.special_roles_users.get_key_value(usr); + // match self.special_roles_users.get_mut(&usr.to_lowercase()) { + // match self.special_roles_users.get(&usr.to_lowercase()) { + // println!("Creating clone"); + botinstance::botlog::trace( + "Creating arc clone", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + let roleslock = Arc::clone(&(*self).special_roles_users); + + // println!("Read lock on : Special_Roles_User"); // <-- after this is slightly different between working and problem + botinstance::botlog::trace( + "Read lock on : Special_Roles_User", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + // { + + // // If target user doesn't exist in special_roles_users , add with blank vector roles + // let mut srulock = self.special_roles_users.write().await; + // srulock.entry(usr.clone()).or_insert(Arc::new(RwLock::new(vec![]))); + // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(usr.clone())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.affirm_chatter_in_db(usr.clone()).await; + + let mut roleslock = roleslock.write().await; + match (*roleslock).get(&usr.to_lowercase()) { + Some(usrroles) + if usrroles + .read() + .await + .contains(&UserRole::Mod(channelname.clone())) + || usrroles + .read() + .await + .contains(&UserRole::SupMod(channelname.clone())) => + { + // <-- working got to this point + // println!("contains mod : {}", usrroles.read().await.contains(&UserRole::Mod(channelname.clone()))); + // println!("contains supmod : {}", usrroles.read().await.contains(&UserRole::SupMod(channelname.clone()))); + + // Do nothing when theh have a mod badge and have either a supmod or mod badge for the channel + // println!("Already a mod in roles"); + botinstance::botlog::trace( + "Already a mod in roles", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + } + _ => { + // In the event they have a mod badge , are running a bot command, but don't have a channel mod role yet... + // println!("lock created > adding with a mod role o7"); + botinstance::botlog::trace( + "lock created > adding with a mod role o7", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + // botinstance::botlog::notice("Assigning ModRole to Chatter", + // Some("identity.rs > can_user_run()".to_string()), None); + + let mut roleslock = roleslock; + let mut a = roleslock.get_mut(&usr.to_lowercase()).unwrap(); + let mut alock = a.write().await; + + alock.push(UserRole::Mod(channelname.clone())); + + modrolechange = ChangeResult::Success("Auto Promoted Mod".to_string()); + + // alock.get_mut(&usr.to_lowercase()) + // .get_or_insert_with(|| UserRole::Mod(channelname.clone())) + // // .expect("ERROR") + // .unwrap() + // .write().await + // // .get_mut() + // .push(UserRole::Mod(channelname.clone())); + } // <-- I'm assuming problem got to here + } + } + _ => (), // Don't handle other roles here + } + + // [x] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) + + // println!("cmd required roles : {:?}",cmdreqroles); + botinstance::botlog::trace( + &format!("cmd required roles : {:?}", cmdreqroles), + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) { + // match self.special_roles_users.get(&channelname) { + // Some(usrroles) => {}, + // None => (), + + // } + + // println!("Command requires Mod Role"); + botinstance::botlog::trace( + "Command requires Mod Role", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if let Some(a) = (&*self) + .special_roles_users + .read() + .await + .get(&usr.to_lowercase()) + { + // println!("Special roles found for user"); + botinstance::botlog::trace( + "Special roles found for user", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if a.read().await.contains(&UserRole::Mod(channelname.clone())) + || a.read() + .await + .contains(&UserRole::SupMod(channelname.clone())) + { + // return Ok(Permissible::Allow); + // println!("Special roles found for user : A mod idenfified "); + botinstance::botlog::trace( + "> Special Role Identified : Mod ", + Some("identity.rs > can_user_run()".to_string()), + None, + ); + return (Permissible::Allow, modrolechange); + } + } + } + + // [x] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) + + if cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { + if let Some(a) = (&*self) + .special_roles_users + .read() + .await + .get(&usr.to_lowercase()) + { + if a.read() + .await + .contains(&UserRole::SupMod(channelname.clone())) + { + // return Ok(Permissible::Allow); + return (Permissible::Allow, modrolechange); + } + } + } + + // [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) + + // println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); + botinstance::botlog::trace( + &format!( + "Eval cmdreqroles with botadmin : {}", + cmdreqroles.contains(&UserRole::BotAdmin) + ), + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if cmdreqroles.contains(&UserRole::BotAdmin) { + // println!("special roles get : {:?}",(&*self).special_roles_users.read().await.get(&usr.to_lowercase())); + botinstance::botlog::trace( + &format!( + "special roles get : {:?}", + (&*self) + .special_roles_users + .read() + .await + .get(&usr.to_lowercase()) + ), + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if let Some(a) = (&*self) + .special_roles_users + .read() + .await + .get(&usr.to_lowercase()) + { + println!( + "special roles contains BotAdmin: {}", + a.read().await.contains(&UserRole::BotAdmin) + ); + botinstance::botlog::trace( + &format!( + "special roles contains BotAdmin: {}", + a.read().await.contains(&UserRole::BotAdmin) + ), + Some("identity.rs > can_user_run()".to_string()), + None, + ); + + if a.read().await.contains(&UserRole::BotAdmin) { + // return Ok(Permissible::Allow); + return (Permissible::Allow, modrolechange); + } + } + } + + ( + Permissible::Block, + ChangeResult::NoChange("Not any permissiable condition".to_string()), + ) + } + // pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { - pub async fn promote(&self, - authorizer:String, - authorizer_badge:&Option, - trgchatter:String, - channel:Option, - trg_role:Option - ) -> ChangeResult - { - - - botinstance::botlog::trace(&format!( + pub async fn promote( + &self, + authorizer: String, + authorizer_badge: &Option, + trgchatter: String, + channel: Option, + trg_role: Option, + ) -> ChangeResult { + botinstance::botlog::trace( + &format!( "IN VARS for promote() : auth : {} ; authbadge : {:?} ; trg : {} ; Channel {:?} ; {:?}", - authorizer,authorizer_badge,trgchatter,channel,trg_role), - Some("identity.rs > promote()".to_string()), None); + authorizer,authorizer_badge,trgchatter,channel,trg_role), + Some("identity.rs > promote()".to_string()), + None, + ); Log::flush(); - /* [x] 1. Check if Authorizer Mod Badge then Auto Promote to Mod if not Mod [x] 2. Get Authorizer & Target Chatter Roles with a Given Channel @@ -1493,30 +1649,30 @@ impl IdentityManager { - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod [ ] 4d. If Authorizer is a Broadcaster,BotAdmin , can Promote a Target Mod > SupMod - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod - - + + */ // [x] 1. Check if Authorizer Mod Badge then Auto Promote to Mod if not Mod - let trgchatter = trgchatter.to_lowercase(); - let (authusrroles,trgusrroles) = if let Some(channel) = channel.clone() { - let mut authusrroles = self.getspecialuserroles( - authorizer.to_lowercase().clone(), - Some(channel.clone())) + let (authusrroles, trgusrroles) = if let Some(channel) = channel.clone() { + let mut authusrroles = self + .getspecialuserroles(authorizer.to_lowercase().clone(), Some(channel.clone())) .await; - - { // mut block + { + // mut block // let authusrroles_mut = &mut authusrroles; // [x] Add Mod(channel) to authusrroles // [x] #TODO also add to DB if possible? match *authorizer_badge { - Some(ChatBadge::Mod) if ( !authusrroles.contains(&UserRole::Mod(channel.clone())) - && !authusrroles.contains(&UserRole::SupMod(channel.clone()))) => { + Some(ChatBadge::Mod) + if (!authusrroles.contains(&UserRole::Mod(channel.clone())) + && !authusrroles.contains(&UserRole::SupMod(channel.clone()))) => + { // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); authusrroles.push(UserRole::Mod(channel.clone())); @@ -1529,55 +1685,46 @@ impl IdentityManager { // .push(UserRole::Mod(channel.clone())); self.affirm_chatter_in_db(authorizer.clone()).await; - self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())).await; - - } - - _ => (), + self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())) + .await; } - } // mut block - - // [x] 2. Get Authorizer & Target Chatter Roles - - let trgusrroles = self.getspecialuserroles( - trgchatter.to_lowercase().clone(), - Some(channel.clone())) - .await; - - (authusrroles,trgusrroles) - } else { - let mut authusrroles = self.getspecialuserroles( - authorizer.to_lowercase().clone(), - None) - .await; - let trgusrroles = self.getspecialuserroles( - trgchatter.to_lowercase().clone(), - None) - .await; - (authusrroles,trgusrroles) - }; + _ => (), + } + } // mut block + // [x] 2. Get Authorizer & Target Chatter Roles + let trgusrroles = self + .getspecialuserroles(trgchatter.to_lowercase().clone(), Some(channel.clone())) + .await; + (authusrroles, trgusrroles) + } else { + let mut authusrroles = self + .getspecialuserroles(authorizer.to_lowercase().clone(), None) + .await; + let trgusrroles = self + .getspecialuserroles(trgchatter.to_lowercase().clone(), None) + .await; + (authusrroles, trgusrroles) + }; // [x] 3. If the authorizer & Target Chatters are the same, and the Authorizer is not a Admin, return no change if trgchatter == authorizer && !authusrroles.contains(&UserRole::BotAdmin) { return ChangeResult::NoChange("Can't target yourself".to_string()); } - // [x] 4a. If Authorizer is BotAdmin & trg_role is Some(BotAdmin) , set Target as BotAdmin and return if authusrroles.contains(&UserRole::BotAdmin) && trg_role == Some(UserRole::BotAdmin) { if trgusrroles.contains(&UserRole::BotAdmin) { return ChangeResult::NoChange("Already has the role".to_string()); } else { - // { // let mut srulock = self.special_roles_users.write().await; // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("Ensuring Target Chatter in Roles > {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Ensuring Target Chatter in Roles > {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } @@ -1592,15 +1739,13 @@ impl IdentityManager { // .expect("Error getting roles for the user") // .write().await // .push(UserRole::BotAdmin); // <-- Adds the specific role - // botinstance::botlog::trace(&format!("Inserting Role > {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Inserting Role > {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } self.add_role(trgchatter.clone(), UserRole::BotAdmin).await; - return ChangeResult::Success("Promotion Successful".to_string()); - } } @@ -1610,93 +1755,85 @@ impl IdentityManager { return ChangeResult::NoChange("Can't target broadcaster".to_string()); } - /* - [ ] 4c. If Authorizer is a SupMod,Broadcaster,BotAdmin , can Promote Target Chatter > Mod - - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod - [ ] 4d. If Authorizer is a Broadcaster,BotAdmin , can Promote a Target Mod > SupMod - - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod - */ - + [ ] 4c. If Authorizer is a SupMod,Broadcaster,BotAdmin , can Promote Target Chatter > Mod + - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod + [ ] 4d. If Authorizer is a Broadcaster,BotAdmin , can Promote a Target Mod > SupMod + - NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod + */ // let authhasnsreqroles = match channel.clone() { - // Some(channel) => authusrroles.contains(&UserRole::SupMod(channel.clone())) || - // authusrroles.contains(&UserRole::BotAdmin) || + // Some(channel) => authusrroles.contains(&UserRole::SupMod(channel.clone())) || + // authusrroles.contains(&UserRole::BotAdmin) || // authusrroles.contains(&UserRole::Broadcaster) , // None => authusrroles.contains(&UserRole::BotAdmin), // }; - if let Some(trg_chnl) = channel.clone() { - - - if !trgusrroles.contains(&UserRole::Broadcaster) - && !trgusrroles.contains(&UserRole::Mod(trg_chnl.clone())) - && !trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) { + if !trgusrroles.contains(&UserRole::Broadcaster) + && !trgusrroles.contains(&UserRole::Mod(trg_chnl.clone())) + && !trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) + { // target user is neither Mod nor SupMod && not broadcaster // target's Next Role would be Mod - // Authorizer must be SupMod,Broadcaster,BotAdmin + // Authorizer must be SupMod,Broadcaster,BotAdmin // > Promote target to Mod - if authusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) - || authusrroles.contains(&UserRole::Broadcaster) + if authusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) + || authusrroles.contains(&UserRole::Broadcaster) || authusrroles.contains(&UserRole::BotAdmin) { - // { // // If target user doesn't exist in special_roles_users , add with blank vector roles // let mut srulock = self.special_roles_users.write().await; // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } self.affirm_chatter_in_db(trgchatter.clone()).await; // { - // // promote target after + // // promote target after // let mut srulock = self.special_roles_users.write().await; // srulock // .get_mut(&trgchatter) // .expect("Error getting roles") // .write().await // .push(UserRole::Mod(trg_chnl.clone())); // Role to Add - // botinstance::botlog::trace(&format!("Adding Roles to Chatter {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Adding Roles to Chatter {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } - self.add_role(trgchatter.clone(), UserRole::Mod(trg_chnl.clone())).await; - + self.add_role(trgchatter.clone(), UserRole::Mod(trg_chnl.clone())) + .await; + return ChangeResult::Success(String::from("Promotion Successful")); - - } - // Other else conditions would be mostly spcecial responses like ChangeResult::NoChange or ChangeResult::Fail + } + // Other else conditions would be mostly spcecial responses like ChangeResult::NoChange or ChangeResult::Fail // related to authusrroles - else { return ChangeResult::Failed(String::from("You're not permitted to do that")); } - - - } else if !trgusrroles.contains(&UserRole::Broadcaster) - && trgusrroles.contains(&UserRole::Mod(trg_chnl.clone())) - && !trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) // - { + } else if !trgusrroles.contains(&UserRole::Broadcaster) + && trgusrroles.contains(&UserRole::Mod(trg_chnl.clone())) + && !trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) + // + { // target user is a Mod && not broadcaster // target's Next Role would be SupMod // [ ] #todo Check first if target have SupMod - Optional but could be done to cleanup first - // Authorizer must be Broadcaster,BotAdmin - // > Promote target to SupMod + // Authorizer must be Broadcaster,BotAdmin + // > Promote target to SupMod - if authusrroles.contains(&UserRole::Broadcaster) - || authusrroles.contains(&UserRole::BotAdmin) + if authusrroles.contains(&UserRole::Broadcaster) + || authusrroles.contains(&UserRole::BotAdmin) { - // { // Inserts user if doesn't exist // let mut srulock = self.special_roles_users.write().await; // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("Ensuring User in Roles {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Ensuring User in Roles {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } @@ -1710,13 +1847,13 @@ impl IdentityManager { // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at // .write().await // .push(UserRole::SupMod(trg_chnl.clone())); - // botinstance::botlog::trace(&format!("Adding Required Role > {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Adding Required Role > {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } - self.add_role(trgchatter.clone(), UserRole::SupMod(trg_chnl.clone())).await; - + self.add_role(trgchatter.clone(), UserRole::SupMod(trg_chnl.clone())) + .await; // { // Removes the lower role (mod) from the user // let mut srulock = self.special_roles_users.write().await; @@ -1728,59 +1865,55 @@ impl IdentityManager { // uroleslock.swap_remove(indx); // } - // botinstance::botlog::trace(&format!("Removing lower role > {:?}",uroleslock), + // botinstance::botlog::trace(&format!("Removing lower role > {:?}",uroleslock), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } - self.remove_role(trgchatter, UserRole::Mod(trg_chnl.clone())).await; - + self.remove_role(trgchatter, UserRole::Mod(trg_chnl.clone())) + .await; + return ChangeResult::Success(String::from("Promotion Successful")); - - } else { return ChangeResult::Failed(String::from("You're not permitted to do that")); } - - } else if !trgusrroles.contains(&UserRole::Broadcaster) - && trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) { + } else if !trgusrroles.contains(&UserRole::Broadcaster) + && trgusrroles.contains(&UserRole::SupMod(trg_chnl.clone())) + { // target user is a SuMod && not broadcaster // No Change return ChangeResult::Failed(String::from("Already highest available role")); - - - } else { + } else { // since handling for channel is already done, will be handling other trguserroles situations here - // other situations includes : + // other situations includes : /* - [-] targetuser is broadcaster >> no need - this was done earlier in the function - [?] ? - */ + [-] targetuser is broadcaster >> no need - this was done earlier in the function + [?] ? + */ - // At the moment, without any new roles, this should not be reached - - botinstance::botlog::warn(&format!("Code Warning : add handing for other trgusrroles"), - Some("identity.rs > promote()".to_string()), None); - return ChangeResult::Failed(String::from("Code Warning")); - + // At the moment, without any new roles, this should not be reached + botinstance::botlog::warn( + &format!("Code Warning : add handing for other trgusrroles"), + Some("identity.rs > promote()".to_string()), + None, + ); + return ChangeResult::Failed(String::from("Code Warning")); } + // let trghasreqroles = - - // let trghasreqroles = - // { // // If target user doesn't exist in special_roles_users , add with blank vector roles // let mut srulock = self.special_roles_users.write().await; // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } // { - // // promote target after + // // promote target after // let mut srulock = self.special_roles_users.write().await; // srulock // .get_mut(&trgchatter) @@ -1788,29 +1921,27 @@ impl IdentityManager { // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at // .write().await // .push(UserRole::Mod(trg_chnl.clone())); // Role to Add - // botinstance::botlog::trace(&format!("Adding Roles to Chatter {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("Adding Roles to Chatter {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } // return ChangeResult::Success(String::from("Promotion Successful")); - - }; // if authhasnsreqroles { - + // { // // If target user doesn't exist in special_roles_users , add with blank vector roles // let mut srulock = self.special_roles_users.write().await; // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - // botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } // { - // // promote target after + // // promote target after // let mut srulock = self.special_roles_users.write().await; // srulock // .get_mut(&trgchatter) @@ -1818,7 +1949,7 @@ impl IdentityManager { // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at // .write().await // .push(UserRole::Mod(trg_chnl)); - // botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), + // botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), // Some("identity.rs > promote()".to_string()), None); // Log::flush(); // } @@ -1829,25 +1960,18 @@ impl IdentityManager { // authusrroles.contains(&UserRole::Mod(())) - - - - - - - /* let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; - + let rolemap = chatterroles; - + match trg_role { Some(UserRole::Mod(_)) => { - + if let Some(trg_chnl) = channel.clone() { // [ ] 1. If trg_role & trgchatter is a Mod or SupMod of the target channel, return NoChange @@ -1877,12 +2001,12 @@ impl IdentityManager { // If target user doesn't exist in special_roles_users , add with blank vector roles let mut srulock = self.special_roles_users.write().await; srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } { - // promote target after + // promote target after let mut srulock = self.special_roles_users.write().await; srulock .get_mut(&trgchatter) @@ -1890,17 +2014,17 @@ impl IdentityManager { // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at .write().await .push(UserRole::Mod(trg_chnl)); - botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } return ChangeResult::Success(String::from("Promotion Successful")); - } + } + - }, - Some(UserRole::SupMod(_)) => + Some(UserRole::SupMod(_)) => { if let Some(trg_chnl) = channel.clone() { @@ -1921,7 +2045,7 @@ impl IdentityManager { // // let c = b.get_mut(&trgchatter); // let c = (*b).; - + // [ ] 2. Ensure an entry in Special_Roles_user for trgchatter, and push SupMod(Channel) for the Target User // [x] (!!) AROUND HERE - check if the user exists first, and at least add the user as we're promoting anyway @@ -1929,7 +2053,7 @@ impl IdentityManager { { let mut srulock = self.special_roles_users.write().await; srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } @@ -1941,7 +2065,7 @@ impl IdentityManager { // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at .write().await .push(UserRole::SupMod(trg_chnl.clone())); - botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } @@ -1963,7 +2087,7 @@ impl IdentityManager { uroleslock.swap_remove(indx); } - botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",uroleslock), + botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",uroleslock), Some("identity.rs > promote()".to_string()), None); Log::flush(); } @@ -1973,22 +2097,22 @@ impl IdentityManager { } , Some(UserRole::BotAdmin) => { - + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; let rolemap = chatterroles; - botinstance::botlog::trace(&format!("Target Role : BotAdmin"), + botinstance::botlog::trace(&format!("Target Role : BotAdmin"), Some("identity.rs > promote()".to_string()), None); // [x] 1. Check their roles first if they already have botadmin - // [x] 2. Know that prior to promote() , BotAdmins should have been validated before being able to pass the BotAdmin target - + // [x] 2. Know that prior to promote() , BotAdmins should have been validated before being able to pass the BotAdmin target + // [x] 1. Check target chatter's roles first if they already have botadmin - botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) : {}",rolemap.contains(&UserRole::BotAdmin)), + botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) : {}",rolemap.contains(&UserRole::BotAdmin)), Some("identity.rs > promote()".to_string()), None); - botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) > Rolemap : {:?}",rolemap), + botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) > Rolemap : {:?}",rolemap), Some("identity.rs > promote()".to_string()), None); // [ ] (!) This seems to be an issue - rolemap by this point is blank @@ -1997,14 +2121,14 @@ impl IdentityManager { } // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); - + // [x] (!!) AROUND HERE - check if the user exists first, and at least add the user as we're promoting anyway { let mut srulock = self.special_roles_users.write().await; srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); - botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } @@ -2019,21 +2143,21 @@ impl IdentityManager { .expect("Error getting roles") .write().await .push(UserRole::BotAdmin); - botinstance::botlog::trace(&format!("SRLOCK - 2nd write > {:?}",srulock.entry(trgchatter.clone())), + botinstance::botlog::trace(&format!("SRLOCK - 2nd write > {:?}",srulock.entry(trgchatter.clone())), Some("identity.rs > promote()".to_string()), None); Log::flush(); } - botinstance::botlog::trace(&format!("Target Role : BotAdmin >> Successful"), + botinstance::botlog::trace(&format!("Target Role : BotAdmin >> Successful"), Some("identity.rs > promote()".to_string()), None); return ChangeResult::Success(String::from("Promotion Successful")); }, Some(_) => { - botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), + botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), Some("identity.rs > promote()".to_string()), None); }, None => { - botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), + botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), Some("identity.rs > promote()".to_string()), None); }, } @@ -2046,26 +2170,26 @@ impl IdentityManager { // // [x] chatter already has the target role // if chatterroles.contains(&trg_role) { // return ChangeResult::NoChange(String::from("Target User already has Target Role")); - // } + // } - // // By this point, chatteroles does not contain target role + // // By this point, chatteroles does not contain target role // // match trgRole { // // Some(trgRole) => { // // match trgRole { // // UserRole::Mod(a) => { - + // // }, // // UserRole::SupMod(a) => (), // // UserRole::BotAdmin => (), - // // _ => (), // <-- do nothing with al other options + // // _ => (), // <-- do nothing with al other options // // } // // }, // // None => { // // /* - // // - If trgRole is None , then promote by implicit rules . For example, + // // - If trgRole is None , then promote by implicit rules . For example, // // - For UserRoles without Mod or SupMod & Caller is SupMod | Broadcaster | BotAdmin > To Mod // // - For Mod & Caller is SupMod | Broadcaster | BotAdmin > To SupMod - // // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin + // // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin // // */ // // }, @@ -2077,17 +2201,15 @@ impl IdentityManager { // // Some(UserRole::BotAdmin) => UserRole::BotAdmin, // // None => { // // /* - // // - If trgRole is None , then promote by implicit rules . For example, + // // - If trgRole is None , then promote by implicit rules . For example, // // - For UserRoles without Mod or SupMod & Caller is SupMod | Broadcaster | BotAdmin > To Mod // // - For Mod & Caller is SupMod | Broadcaster | BotAdmin > To SupMod - // // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin + // // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin // // */ // // }, // // }; - - // // if let Some(trgRole) = trgRole { // // // [x] chatter already has the target role @@ -2102,54 +2224,54 @@ impl IdentityManager { // }, // _ => (), // } - botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), - Some("identity.rs > promote()".to_string()), None); + botinstance::botlog::warn( + &format!("Runtime reached undeveloped code"), + Some("identity.rs > promote()".to_string()), + None, + ); ChangeResult::Failed(String::from("ERROR")) - } + } - - pub async fn demote(&self, - authorizer:String, - authorizer_badge:&Option, - trgchatter:String, - channel:Option, + pub async fn demote( + &self, + authorizer: String, + authorizer_badge: &Option, + trgchatter: String, + channel: Option, // trg_role:Option - ) -> ChangeResult - { + ) -> ChangeResult { // botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", - // authorizer,trgchatter,channel,trg_role), + // authorizer,trgchatter,channel,trg_role), botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?}", - authorizer,trgchatter,channel), - Some("identity.rs > demote()".to_string()), None); + authorizer,trgchatter,channel), Some("identity.rs > demote()".to_string()), None); Log::flush(); /* - Check authorizer roles (if any) for the target channel - Check Targer User's roles (if any) for the target channel - Target Channel may be NONE in the case of Non-Channel related roles (FUTURE ENH) + Check authorizer roles (if any) for the target channel + Check Targer User's roles (if any) for the target channel + Target Channel may be NONE in the case of Non-Channel related roles (FUTURE ENH) - Use the roles of the above to determine whether the authorizer can demote the target user or not - */ + Use the roles of the above to determine whether the authorizer can demote the target user or not + */ // [x] 1. If Authorizer's Badge is Mod, ensuring Sender is in DB as Mod(Channel) let trgchatter = trgchatter.to_lowercase(); if let Some(channel) = channel { - let mut authusrroles = self.getspecialuserroles( - authorizer.to_lowercase().clone(), - Some(channel.clone())) + let mut authusrroles = self + .getspecialuserroles(authorizer.to_lowercase().clone(), Some(channel.clone())) .await; // let authusrroles = authusrroles; { - // let authusrroles_mut = &mut authusrroles; // [x] Add Mod(channel) to authusrroles // [x] #TODO also add to DB if possible? match *authorizer_badge { - Some(ChatBadge::Mod) if (!authusrroles.contains(&UserRole::Mod(channel.clone())) - && !authusrroles.contains(&UserRole::SupMod(channel.clone())) - ) => { + Some(ChatBadge::Mod) + if (!authusrroles.contains(&UserRole::Mod(channel.clone())) + && !authusrroles.contains(&UserRole::SupMod(channel.clone()))) => + { // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); authusrroles.push(UserRole::Mod(channel.clone())); @@ -2162,8 +2284,8 @@ impl IdentityManager { // .write().await // .push(UserRole::Mod(channel.clone())); - self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())).await; - + self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())) + .await; } _ => (), } @@ -2171,94 +2293,98 @@ impl IdentityManager { // [x] 2. Targer User's Vec - let trgusrroles = self.getspecialuserroles( - trgchatter.to_lowercase().clone(), - Some(channel.clone())) + let trgusrroles = self + .getspecialuserroles(trgchatter.to_lowercase().clone(), Some(channel.clone())) .await; // [x] 3. Return if Authorizer & Target are same chatter and Authorizer is not a BotAdmin if trgchatter == authorizer && !authusrroles.contains(&UserRole::BotAdmin) { - return ChangeResult::NoChange("Can't target yourself".to_string()) + return ChangeResult::NoChange("Can't target yourself".to_string()); } // [x] 4a. Authorizers who are BotAdmin, Broadcaster or Supermod can demote a Mod - if ( authusrroles.contains(&UserRole::BotAdmin) || - authusrroles.contains(&UserRole::Broadcaster) || - authusrroles.contains(&UserRole::SupMod(channel.clone())) ) && - trgusrroles.contains(&UserRole::Mod(channel.clone())) - { - // // [ ] Below removes Mod from trgchatter - // let mut srulock = self.special_roles_users.write().await; - // let mut usrrolelock = srulock - // .get_mut(&trgchatter) - // .expect("Error getting roles") - // .write().await; - // if let Some(indx) = usrrolelock.iter().position(|value| *value == UserRole::Mod(channel.clone())){ - // usrrolelock.swap_remove(indx); - // return ChangeResult::Success("Demoted successfully".to_string()) - // } - self.remove_role(trgchatter.clone(), UserRole::Mod(channel.clone())).await; - return ChangeResult::Success("Demoted successfully".to_string()) - } - + if (authusrroles.contains(&UserRole::BotAdmin) + || authusrroles.contains(&UserRole::Broadcaster) + || authusrroles.contains(&UserRole::SupMod(channel.clone()))) + && trgusrroles.contains(&UserRole::Mod(channel.clone())) + { + // // [ ] Below removes Mod from trgchatter + // let mut srulock = self.special_roles_users.write().await; + // let mut usrrolelock = srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // .write().await; + // if let Some(indx) = usrrolelock.iter().position(|value| *value == UserRole::Mod(channel.clone())){ + // usrrolelock.swap_remove(indx); + // return ChangeResult::Success("Demoted successfully".to_string()) + // } + self.remove_role(trgchatter.clone(), UserRole::Mod(channel.clone())) + .await; + return ChangeResult::Success("Demoted successfully".to_string()); + } // [x] 4b. Authorizers who are BotAdmin, Broadcaster can demote a SupMod - else if ( authusrroles.contains(&UserRole::BotAdmin) || - authusrroles.contains(&UserRole::Broadcaster) ) && - trgusrroles.contains(&UserRole::SupMod(channel.clone())) - - - { - // [ ] For Trgchatter, below pushes Mod UserRole and removes SupMod - // let mut srulock = self.special_roles_users.write().await; - // let mut usrrolelock = srulock - // .get_mut(&trgchatter) - // .expect("Error getting roles") - // .write().await; - // usrrolelock.push(UserRole::Mod(channel.clone())); // pushes Mod , and removes SupMod - // if let Some(indx) = usrrolelock.iter().position(|value| *value == UserRole::SupMod(channel.clone())){ - // usrrolelock.swap_remove(indx); - // return ChangeResult::Success("Demoted successfully".to_string()) - // } - - self.add_role(trgchatter.clone(), UserRole::Mod(channel.clone())).await; - self.remove_role(trgchatter.clone(), UserRole::SupMod(channel.clone())).await; - return ChangeResult::Success("Demoted successfully".to_string()); - } - + else if (authusrroles.contains(&UserRole::BotAdmin) + || authusrroles.contains(&UserRole::Broadcaster)) + && trgusrroles.contains(&UserRole::SupMod(channel.clone())) + { + // [ ] For Trgchatter, below pushes Mod UserRole and removes SupMod + // let mut srulock = self.special_roles_users.write().await; + // let mut usrrolelock = srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // .write().await; + // usrrolelock.push(UserRole::Mod(channel.clone())); // pushes Mod , and removes SupMod + // if let Some(indx) = usrrolelock.iter().position(|value| *value == UserRole::SupMod(channel.clone())){ + // usrrolelock.swap_remove(indx); + // return ChangeResult::Success("Demoted successfully".to_string()) + // } + self.add_role(trgchatter.clone(), UserRole::Mod(channel.clone())) + .await; + self.remove_role(trgchatter.clone(), UserRole::SupMod(channel.clone())) + .await; + return ChangeResult::Success("Demoted successfully".to_string()); + } // [x] 4c. When Target chatter isnt a Mod or SupMod to demote - else if !trgusrroles.contains(&UserRole::Mod(channel.clone())) && - !trgusrroles.contains(&UserRole::SupMod(channel.clone())) { - return ChangeResult::Failed("Target chatter does not have a role that can be demoted".to_string()) - } + else if !trgusrroles.contains(&UserRole::Mod(channel.clone())) + && !trgusrroles.contains(&UserRole::SupMod(channel.clone())) + { + return ChangeResult::Failed( + "Target chatter does not have a role that can be demoted".to_string(), + ); + } // [x] 4d. When they're only a Mod else if authusrroles.contains(&UserRole::Mod(channel.clone())) { - return ChangeResult::Failed("You're not permitted to do that".to_string()) + return ChangeResult::Failed("You're not permitted to do that".to_string()); } } - botinstance::botlog::warn(&format!("Potential Unhandled Demotion Condition : Consider explicitely adding in for better handling"), Some("identity.rs > demote()".to_string()), None); Log::flush(); ChangeResult::Failed(String::from("Did not meet criteria to demote succesfully")) - } - - // pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { pub async fn getspecialuserroles( - &self,chattername:String, - channel:Option) -> Vec { + &self, + chattername: String, + channel: Option, + ) -> Vec { /* - Note : Ideally this be called for a given chatter name ? - */ - + Note : Ideally this be called for a given chatter name ? + */ + // [ ] !!! TODO: I don't think below is evaluating by given channel - botinstance::botlog::debug(&format!("IN VARS > chattername {} ; channel {:?}", chattername,channel), - Some("IdentityManager > getspecialuserroles()".to_string()), None); + botinstance::botlog::debug( + &format!( + "IN VARS > chattername {} ; channel {:?}", + chattername, channel + ), + Some("IdentityManager > getspecialuserroles()".to_string()), + None, + ); // resulting vector let mut evalsproles = vec![]; @@ -2277,14 +2403,12 @@ impl IdentityManager { } Some(ChType::Channel(channel_tmp)) - }, - // _ => () + } // _ => () } } None => None, }; - let rolesa = Arc::clone(&self.special_roles_users); let a = rolesa.read().await; @@ -2300,62 +2424,66 @@ impl IdentityManager { Some(channel) => { // let eval = a.read().await.contains(&UserRole::Mod(channel)); // let eval = a.read().await.contains(&UserRole::SupMod(channel)); - botinstance::botlog::debug(&format!("INTERNAL > All Roles found {:?}", &a), - Some("IdentityManager > getspecialuserroles()".to_string()), None); + botinstance::botlog::debug( + &format!("INTERNAL > All Roles found {:?}", &a), + Some("IdentityManager > getspecialuserroles()".to_string()), + None, + ); // a.read().await.contains(&UserRole::BotAdmin) - botinstance::botlog::trace(&format!("INTERNAL > eval special roles contains botadmin : {:?}", a.read().await.contains(&UserRole::BotAdmin)), - Some("IdentityManager > getspecialuserroles()".to_string()), None); + botinstance::botlog::trace( + &format!( + "INTERNAL > eval special roles contains botadmin : {:?}", + a.read().await.contains(&UserRole::BotAdmin) + ), + Some("IdentityManager > getspecialuserroles()".to_string()), + None, + ); if a.read().await.contains(&UserRole::BotAdmin) { evalsproles.push(UserRole::BotAdmin); - } + } if a.read().await.contains(&UserRole::Mod(channel.clone())) { evalsproles.push(UserRole::Mod(channel.clone())); } if a.read().await.contains(&UserRole::SupMod(channel.clone())) { evalsproles.push(UserRole::SupMod(channel.clone())); - } + } // else {}; - - } + } None => { - // here , do nothing if the channel not provided - // [ ] TODO : Future is to provide all maybe ? - // ... no I think missing this is an issue for when the flag is -admin and channel is None? - // - // => 02.13 - Decided That None is provided as a Channel, we can output non-channel related roles like BotAdmin - if a.read().await.contains(&UserRole::BotAdmin) { + // here , do nothing if the channel not provided + // [ ] TODO : Future is to provide all maybe ? + // ... no I think missing this is an issue for when the flag is -admin and channel is None? + // + // => 02.13 - Decided That None is provided as a Channel, we can output non-channel related roles like BotAdmin + if a.read().await.contains(&UserRole::BotAdmin) { evalsproles.push(UserRole::BotAdmin); - } + } } } - - }, + } None => { // here, the user has no special listed roles. Note though Broadcaster is not stored in special roles // Do nothing in this case // There may be an issue if the chattername does not exist at the moment in special_roles_users - // In this case, evalsproles would only contain Broadcaster flags if any - }, - + // In this case, evalsproles would only contain Broadcaster flags if any + } } - botinstance::botlog::debug(&format!("OUT > evalsproles {:?}", &evalsproles), - Some("IdentityManager > getspecialuserroles()".to_string()), None); + botinstance::botlog::debug( + &format!("OUT > evalsproles {:?}", &evalsproles), + Some("IdentityManager > getspecialuserroles()".to_string()), + None, + ); return evalsproles; - } - - } - #[cfg(test)] mod core_identity { - use casual_logger::Extension; use super::*; @@ -2366,14 +2494,17 @@ mod core_identity { // Log::set_level(Level::Trace); // let result = 2 + 2; // assert_eq!(result, 4); - assert_eq!(UserRole::SupMod(ChType::Channel("strong".to_string())),UserRole::SupMod(ChType::Channel("Strong".to_lowercase()))); - } + assert_eq!( + UserRole::SupMod(ChType::Channel("strong".to_string())), + UserRole::SupMod(ChType::Channel("Strong".to_lowercase())) + ); + } #[tokio::test] async fn promote_workflow_01() { Log::set_file_ext(Extension::Log); // Log::set_level(Level::Trace); - + let test_id_mgr = IdentityManager::init(); // [x] Mod Attempts to Promote User @@ -2382,20 +2513,28 @@ mod core_identity { let authorizer_badge = &Some(ChatBadge::Mod); let authorizer = "chatMod".to_string(); let trg_role = None; - - let rslt = test_id_mgr.promote(authorizer, authorizer_badge, trgchatter.clone(), channel.clone(), trg_role).await; + let rslt = test_id_mgr + .promote( + authorizer, + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role, + ) + .await; - assert_eq!(rslt,ChangeResult::Failed(String::from("You're not permitted to do that"))); - - } + assert_eq!( + rslt, + ChangeResult::Failed(String::from("You're not permitted to do that")) + ); + } #[tokio::test] async fn promote_workflow_02() { - Log::set_file_ext(Extension::Log); // Log::set_level(Level::Trace); - + let test_id_mgr = IdentityManager::init(); // [x] Broadcaster Promotes Chatter to SupMod @@ -2404,66 +2543,120 @@ mod core_identity { let authorizer_badge = &Some(ChatBadge::Broadcaster); let authorizer = "broadcasterer".to_string(); let trg_role = None; - - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(trgchatter.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::Mod(ChType::Channel("broadcasterer".to_string())))); - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(trgchatter.clone(), channel.clone()) + .await; - assert!(rslt.contains(&UserRole::SupMod(ChType::Channel("broadcasterer".to_string())))); - - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; - - assert_eq!(rslt, ChangeResult::Failed(String::from("Already highest available role"))); + assert!(rslt.contains(&UserRole::SupMod(ChType::Channel( + "broadcasterer".to_string() + )))); + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; + assert_eq!( + rslt, + ChangeResult::Failed(String::from("Already highest available role")) + ); } - - #[tokio::test] async fn promote_workflow_03() { - Log::set_file_ext(Extension::Log); // Log::set_level(Level::Trace); - + let test_id_mgr = IdentityManager::init(); // [x] SupMod Promotes Chatter to SupMod // [x] Broadcaster first promotes a SupMod - + let broadcaster = "broadcasterer".to_string(); let broadcaster_badge = &Some(ChatBadge::Broadcaster); let channel = Some(ChType::Channel(broadcaster.clone())); let supchatter = "superModerator".to_string(); let trg_role = None; - - let rslt = test_id_mgr.promote(broadcaster.clone(), broadcaster_badge, supchatter.clone(), channel.clone(), trg_role.clone()).await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + let rslt = test_id_mgr + .promote( + broadcaster.clone(), + broadcaster_badge, + supchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.promote(broadcaster.clone(), broadcaster_badge, supchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + broadcaster.clone(), + broadcaster_badge, + supchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(supchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(supchatter.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::SupMod(channel.unwrap()))); - - // [x] SupMod Attempts to Promote Chatter to SupMod // let broadcaster = "broadcasterer".to_string(); @@ -2473,28 +2666,50 @@ mod core_identity { let trgchatter = "regularChatter".to_string(); let trg_role = None; - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(trgchatter.clone(), channel.clone()) + .await; // assert!(rslt.contains(&UserRole::Mod(ChType::Channel("broadcasterer".to_string())))); assert!(rslt.contains(&UserRole::Mod(channel.clone().unwrap()))); - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; // assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); - assert_eq!(rslt, ChangeResult::Failed("You're not permitted to do that".to_string())); - - } + assert_eq!( + rslt, + ChangeResult::Failed("You're not permitted to do that".to_string()) + ); + } #[tokio::test] async fn promote_workflow_04() { - Log::set_file_ext(Extension::Log); // Log::set_level(Level::Trace); - + let test_id_mgr = IdentityManager::init(); // [x] BotAdmin Promotes Chatter to SupMod @@ -2505,13 +2720,16 @@ mod core_identity { let botadmin_badge = &None; test_id_mgr.affirm_chatter_in_db(botadmin.clone()).await; - test_id_mgr.add_role(botadmin.clone(), UserRole::BotAdmin).await; - - let rslt = test_id_mgr.getspecialuserroles(botadmin.clone(), None).await; + test_id_mgr + .add_role(botadmin.clone(), UserRole::BotAdmin) + .await; + + let rslt = test_id_mgr + .getspecialuserroles(botadmin.clone(), None) + .await; assert!(rslt.contains(&UserRole::BotAdmin)); - // [x] SupMod Attempts to Promote Chatter to SupMod // let broadcaster = "broadcasterer".to_string(); @@ -2521,41 +2739,74 @@ mod core_identity { let trgchatter = "regularChatter".to_string(); let trg_role = None; - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(trgchatter.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::Mod(channel.clone().unwrap()))); - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; // assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); - assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + assert_eq!( + rslt, + ChangeResult::Success("Promotion Successful".to_string()) + ); - let rslt = test_id_mgr.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(trgchatter.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::SupMod(channel.clone().unwrap()))); - let rslt = test_id_mgr.promote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone(), trg_role.clone()).await; - - assert_eq!(rslt, ChangeResult::Failed(String::from("Already highest available role"))); - - - } + let rslt = test_id_mgr + .promote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + trg_role.clone(), + ) + .await; + assert_eq!( + rslt, + ChangeResult::Failed(String::from("Already highest available role")) + ); + } #[tokio::test] async fn demote_workflow_01() { - Log::set_file_ext(Extension::Log); // Log::set_level(Level::Trace); // [x] SupMod demotes a mod // [x] create a SupMod first - + let test_id_mgr = IdentityManager::init(); let supmod = "supmoder".to_string(); @@ -2563,9 +2814,13 @@ mod core_identity { let channel = Some(ChType::Channel("somechannel".to_string())); test_id_mgr.affirm_chatter_in_db(supmod.clone()).await; - test_id_mgr.add_role(supmod.clone(), UserRole::SupMod(channel.clone().unwrap())).await; + test_id_mgr + .add_role(supmod.clone(), UserRole::SupMod(channel.clone().unwrap())) + .await; - let rslt = test_id_mgr.getspecialuserroles(supmod.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(supmod.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::SupMod(channel.clone().unwrap()))); @@ -2576,9 +2831,13 @@ mod core_identity { // let channel = Some(ChType::Channel("somechannel".to_string())); test_id_mgr.affirm_chatter_in_db(regmod.clone()).await; - test_id_mgr.add_role(regmod.clone(), UserRole::Mod(channel.clone().unwrap())).await; + test_id_mgr + .add_role(regmod.clone(), UserRole::Mod(channel.clone().unwrap())) + .await; - let rslt = test_id_mgr.getspecialuserroles(regmod.clone(), channel.clone()).await; + let rslt = test_id_mgr + .getspecialuserroles(regmod.clone(), channel.clone()) + .await; assert!(rslt.contains(&UserRole::Mod(channel.clone().unwrap()))); @@ -2588,29 +2847,54 @@ mod core_identity { let authorizer_badge = &None; let trgchatter = supmod.clone(); + let rslt = test_id_mgr + .demote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + ) + .await; - let rslt = test_id_mgr.demote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone()).await; + assert_eq!( + rslt, + ChangeResult::Failed("You're not permitted to do that".to_string()) + ); - assert_eq!(rslt, ChangeResult::Failed("You're not permitted to do that".to_string())); - // [x] SupMod demotes regular mod let authorizer = supmod; let authorizer_badge = &None; let trgchatter = regmod; - let rslt = test_id_mgr.demote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone()).await; - - assert_eq!(rslt, ChangeResult::Success("Demoted successfully".to_string())); - - - let rslt = test_id_mgr.demote(authorizer.clone(), authorizer_badge, trgchatter.clone(), channel.clone()).await; - - assert_eq!(rslt, ChangeResult::Failed("Target chatter does not have a role that can be demoted".to_string())); + let rslt = test_id_mgr + .demote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + ) + .await; + assert_eq!( + rslt, + ChangeResult::Success("Demoted successfully".to_string()) + ); + let rslt = test_id_mgr + .demote( + authorizer.clone(), + authorizer_badge, + trgchatter.clone(), + channel.clone(), + ) + .await; + assert_eq!( + rslt, + ChangeResult::Failed( + "Target chatter does not have a role that can be demoted".to_string() + ) + ); } - - } diff --git a/src/core/ratelimiter.rs b/src/core/ratelimiter.rs index a25871c..f87b2b9 100644 --- a/src/core/ratelimiter.rs +++ b/src/core/ratelimiter.rs @@ -1,10 +1,8 @@ - use std::time::Instant; const TIME_THRESHOLD_S: u64 = 30; const MSG_THRESHOLD: u32 = 20; - #[derive(Debug, Clone)] pub struct RateLimiter { timer: Instant, @@ -13,10 +11,9 @@ pub struct RateLimiter { pub enum LimiterResp { Allow, // when it's evaluated to be within limits - Skip, // as outside of rate limits + Skip, // as outside of rate limits } - impl RateLimiter { pub fn new() -> Self { Self { @@ -25,24 +22,23 @@ impl RateLimiter { } } -pub fn check_limiter(&mut self) -> LimiterResp { - - if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S { -// # [x] elapsed >= TIME_THRESHOLD_S - self.timer = Instant::now(); - self.msgcounter = 0; - LimiterResp::Allow - } else if self.msgcounter < MSG_THRESHOLD { -// # [x] elapsed < TIME_THRESHOLD_S && msgcounter < MSG_THRESHOLD - LimiterResp::Allow - // } else if self.msgcounter >= MSG_THRESHOLD { - } else { -// # [x] elapsed < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD - LimiterResp::Skip + pub fn check_limiter(&mut self) -> LimiterResp { + if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S { + // # [x] elapsed >= TIME_THRESHOLD_S + self.timer = Instant::now(); + self.msgcounter = 0; + LimiterResp::Allow + } else if self.msgcounter < MSG_THRESHOLD { + // # [x] elapsed < TIME_THRESHOLD_S && msgcounter < MSG_THRESHOLD + LimiterResp::Allow + // } else if self.msgcounter >= MSG_THRESHOLD { + } else { + // # [x] elapsed < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD + LimiterResp::Skip + } } -} pub fn increment_counter(&mut self) -> () { - self.msgcounter += 1; + self.msgcounter += 1; } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 15558d2..650ed26 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,2 @@ - pub mod core; pub mod modules; diff --git a/src/main.rs b/src/main.rs index afd1526..d00584f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ - - // pub mod core; // pub mod modules; //use myLib; @@ -9,22 +7,21 @@ use std::process::Output; // use crate::core::botinstance::ArcBox; use botLib::core::botinstance::ArcBox; -use botLib::core::botinstance::{self,BotInstance}; +use botLib::core::botinstance::{self, BotInstance}; // use core::botinstance::{self,BotInstance}; use casual_logger::Extension; -use tokio::sync::RwLock; use std::sync::Arc; +use tokio::sync::RwLock; pub type BotAR = Arc>; -use casual_logger::{Level,Log}; +use casual_logger::{Level, Log}; #[tokio::main] pub async fn main() { - Log::set_file_ext(Extension::Log); Log::set_level(Level::Trace); - // Log::set_level(Level::Notice); + // Log::set_level(Level::Notice); let bot = BotInstance::init().await; @@ -34,28 +31,39 @@ pub async fn main() { let a = a.read().await; // let a = *a; - for (_,acts) in &*a { + for (_, acts) in &*a { for act in acts { match act { botLib::core::botmodules::BotAction::C(b) => { // println!("bot actiions: {}",b.command) // Log::info(&format!("bot actions: {}",b.command)); - botinstance::botlog::info(&format!("bot actions: {}",b.command), Some("main()".to_string()), None); - }, + botinstance::botlog::info( + &format!("bot actions: {}", b.command), + Some("main()".to_string()), + None, + ); + } botLib::core::botmodules::BotAction::L(l) => { // println!("bot actiions: {}",l.name) // Log::info(&format!("bot actions: {}",l.name)); - botinstance::botlog::info(&format!("bot actions: {}",l.name), Some("main()".to_string()), None); - }, + botinstance::botlog::info( + &format!("bot actions: {}", l.name), + Some("main()".to_string()), + None, + ); + } _ => { // println!("Not a valid match??") // Log::info("Not a valid match??"); - botinstance::botlog::info("Not a valid match??", Some("main()".to_string()), None); - }, + botinstance::botlog::info( + "Not a valid match??", + Some("main()".to_string()), + None, + ); + } } - } - }; + } // println!("Starting runner.."); // Log::notice("Starting Bot Runner"); @@ -70,6 +78,5 @@ pub async fn main() { // let msg = Log::fatal("ERROR : EXIT Game loop"); // panic!("{}",Log::fatal("ERROR : EXIT Game loop")); let a = botinstance::botlog::fatal("ERROR : EXIT Game loop", Some("main()".to_string()), None); - panic!("{}",a); - -} \ No newline at end of file + panic!("{}", a); +} diff --git a/src/modules.rs b/src/modules.rs index 49f3583..08cb49b 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -10,22 +10,20 @@ pub use crate::core::botmodules::ModulesManager; // use crate::core::botinstance; pub use crate::core::botinstance::BotInstance; -use std::sync::Arc; use futures::lock::Mutex; +use std::sync::Arc; // [ ] Load submodules mod experiments; - // [ ] init() function that accepts bot instance - this is passed to init() on submodules -pub async fn init(mgr:Arc) -{ +pub async fn init(mgr: Arc) { // Modules initializer loads modules into the bot // this is achieved by calling submodules that also have fn init() defined - experiments::init(mgr).await + experiments::init(mgr).await //(); -} \ No newline at end of file +} diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index c75574f..e61d296 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -1,9 +1,8 @@ - /* Submodules - - should have definitions of BotAction that will be added to a bit - - therefore, will be defined in modules.rs file + - therefore, will be defined in modules.rs file - will define one init(&BotInstance) take within the module that will contain : - BotAction definitions that each call &BotInstance module manager to add itself @@ -14,28 +13,23 @@ use std::future::Future; -use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; use crate::core::botmodules::bot_actions::actions_util::{self, BotAR}; +use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager}; -use crate::core::botinstance::{self,BotInstance,ChType}; +use crate::core::botinstance::{self, BotInstance, ChType}; use futures::lock::Mutex; use twitch_irc::message::PrivmsgMessage; use crate::core::identity; - use rand::Rng; use std::rc::Rc; use std::sync::{Arc, RwLock}; - // pub fn init(mgr:&mut ModulesManager) -pub async fn init(mgr:Arc) -{ - - +pub async fn init(mgr: Arc) { // BotCommand { // module : BotModule(String::from("experiments 004")), // command : String::from("test1"), // command call name @@ -48,81 +42,78 @@ pub async fn init(mgr:Arc) // ], // }.add_to_modmgr(mgr); - let botc1 = BotCommand { - module : BotModule(String::from("experiments001")), - command : String::from("test1"), // command call name - alias : vec![String::from("tester1"),String::from("testy1")], // String of alternative names - exec_body : actions_util::asyncbox(testy) , - help : String::from("Test Command tester"), - required_roles : vec![ - identity::UserRole::BotAdmin - ], + module: BotModule(String::from("experiments001")), + command: String::from("test1"), // command call name + alias: vec![String::from("tester1"), String::from("testy1")], // String of alternative names + exec_body: actions_util::asyncbox(testy), + help: String::from("Test Command tester"), + required_roles: vec![identity::UserRole::BotAdmin], }; botc1.add_to_modmgr(Arc::clone(&mgr)).await; - - let list1 = Listener { - module : BotModule(String::from("experiments001")), - name : String::from("GoodGirl Listener"), - exec_body : actions_util::asyncbox(good_girl) , - help : String::from("") + module: BotModule(String::from("experiments001")), + name: String::from("GoodGirl Listener"), + exec_body: actions_util::asyncbox(good_girl), + help: String::from(""), }; list1.add_to_modmgr(Arc::clone(&mgr)).await; - - } - -async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) -{ +async fn good_girl(mut bot: BotAR, msg: PrivmsgMessage) { // println!("In GoodGirl() Listener"); // Change below from debug to trace if required later - botinstance::botlog::debug("In GoodGirl() Listener", - Some("experiments > goodgirl()".to_string()) , - Some(&msg)); + botinstance::botlog::debug( + "In GoodGirl() Listener", + Some("experiments > goodgirl()".to_string()), + Some(&msg), + ); - //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - // [ ] Uses gen_ratio() to output bool based on a ratio probability . + // [ ] 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 msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase() || msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase() // && msg.message_text.contains("GoodGirl") + if msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase() + || msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase() + // && msg.message_text.contains("GoodGirl") { // chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; //if rng.gen_ratio(1,5) { // println!("In GoodGirl() > Pausechamp"); - botinstance::botlog::debug("In GoodGirl() > Pausechamp", - Some("experiments > goodgirl()".to_string()) , - Some(&msg)); - let rollwin = rand::thread_rng().gen_ratio(1,8); + botinstance::botlog::debug( + "In GoodGirl() > Pausechamp", + Some("experiments > goodgirl()".to_string()), + Some(&msg), + ); + let rollwin = rand::thread_rng().gen_ratio(1, 8); if rollwin { // println!("In GoodGirl() > Win"); - botinstance::botlog::debug("In GoodGirl() > Win", - Some("experiments > goodgirl()".to_string()) , - Some(&msg)); - let a = Arc::clone(&bot); - let botlock = a.read().await; - botlock.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + botinstance::botlog::debug( + "In GoodGirl() > Win", + Some("experiments > goodgirl()".to_string()), + Some(&msg), + ); + let a = Arc::clone(&bot); + let botlock = a.read().await; + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, String::from("GoodGirl xdd ")) + .await; } - - } - } - -async fn testy(mut _chat:BotAR,msg:PrivmsgMessage) -{ +async fn testy(mut _chat: BotAR, msg: PrivmsgMessage) { println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call - botinstance::botlog::debug("testy triggered!", - Some("experiments > testy()".to_string()) , - Some(&msg)); - -} \ No newline at end of file + botinstance::botlog::debug( + "testy triggered!", + Some("experiments > testy()".to_string()), + Some(&msg), + ); +}