From 45564cceedcbcd0142cac7e0dea5c72254822300 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 04:28:58 -0500 Subject: [PATCH 01/39] BotCommands added are valided at runtime --- src/core/botmodules.rs | 86 +++++++++++++++++++------------------- src/modules/experiments.rs | 24 +++++++---- 2 files changed, 60 insertions(+), 50 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index aab2cf2..b06858a 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -276,70 +276,70 @@ impl ModulesManager // BotAction::R(r) => None, // } - // if let BotAction::C(incmd) = act { + if let BotAction::C(incmd) = act { - // // let n = & mgr.botactions; + // let n = & mgr.botactions; - // let d = &mgr.botactions; + let d = &mgr.botactions; - // 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 + for modact in moduleactions.iter() { + if let BotAction::C(dbcmd) = &modact { + // At this point, there is an command incmd and looked up dbcmd - // // [x] check if given botcommand c.command:String conflicts with any in botactions + // [x] check if given botcommand c.command:String conflicts with any in botactions - // if incmd.command.to_lowercase() == dbcmd.command.to_lowercase() { - // // Returning State - with the identified module - // // return Some((module.clone(),BotAction::C(*dbcmd.clone()))); - // // 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()); - // } + if incmd.command.to_lowercase() == dbcmd.command.to_lowercase() { + // Returning State - with the identified module + // return Some((module.clone(),BotAction::C(*dbcmd.clone()))); + // 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()); + } - // 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 + 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 + // [x] Then do the same check except for each c.alias - // for inalias in &incmd.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 + 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 + 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"))) - // } + // return Some(BotModule(String::from("GambaCore"))) + } // for all other scenarios (e.g., Listener, Routine), find no conflicts diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 11f1b94..2d761d3 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -24,13 +24,23 @@ pub fn init(mgr:&mut ModulesManager) { - BotCommand { - module : BotModule(String::from("experiments 004")), - command : String::from("test"), // command call name - alias : vec![String::from("tester"),String::from("testy")], // String of alternative names - exec_body : actions_util::asyncbox(testy) , - help : String::from("DUPCMD4 tester"), - }.add_to_modmgr(mgr); + BotCommand { + module : BotModule(String::from("experiments 004")), + 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("DUPCMD4 tester"), + }.add_to_modmgr(mgr); + + + BotCommand { + module : BotModule(String::from("experiments 004")), + command : String::from("test2"), // command call name + alias : vec![String::from("tester2"),String::from("testy2")], // String of alternative names + exec_body : actions_util::asyncbox(testy) , + help : String::from("DUPCMD4 tester"), + }.add_to_modmgr(mgr); + let list1 = Listener { -- 2.46.1 From 422cd933030a59cc38c1e444ef70340dbd236c3f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 06:18:27 -0500 Subject: [PATCH 02/39] (init) Identity Module --- src/core.rs | 1 + src/core/botinstance.rs | 15 +++++++++++++-- src/core/identity.rs | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/core/identity.rs diff --git a/src/core.rs b/src/core.rs index 320ee73..ca51e65 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,6 +1,7 @@ pub mod botinstance; pub mod ratelimiter; pub mod botmodules; +pub mod identity; // pub fn init() -> () // { diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index c2bff7a..19596bf 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -22,6 +22,8 @@ use crate::core::ratelimiter; use crate::core::botmodules; use crate::core::botmodules::ModulesManager; +use crate::core::identity::IdentityManager; + #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { @@ -137,6 +139,7 @@ pub struct BotInstance pub botmodules : ModulesManager, twitch_oauth : String, pub bot_channels : Vec, + pub identity : IdentityManager, } @@ -203,6 +206,7 @@ impl BotInstance botmodules : ModulesManager::init(), twitch_oauth : oauth_token, bot_channels : botchannels, + identity : IdentityManager::init(), }; @@ -288,19 +292,26 @@ impl BotInstance // [x] Check if a bot command based on ... // [x] prefix + command + + let mut exec_bot_command = false; if inpt == self.prefix.to_string() + c.command.as_str() { - c.execute(self.chat.clone(), msg.clone()).await; + exec_bot_command = true; } // [x] prefix + alias for alias in &c.alias { if inpt == self.prefix.to_string() + alias.as_str() { - c.execute(self.chat.clone(), msg.clone()).await; + exec_bot_command = true; } } + + if exec_bot_command { + c.execute(self.chat.clone(), msg.clone()).await; + } }, crate::core::botmodules::BotAction::L(l) => l.execute(self.chat.clone(), msg.clone()).await, + _ => (), } } diff --git a/src/core/identity.rs b/src/core/identity.rs new file mode 100644 index 0000000..eca2243 --- /dev/null +++ b/src/core/identity.rs @@ -0,0 +1,36 @@ + +use std::collections::HashMap; + +fn adminvector() -> Vec { + vec![String::from("ModulatingForce")] +} + + +enum userRole { + Chatter, + Mod(String), // String specifies Channel + SupMod(String), // String specifies Channel + Broadcaster, + BotAdmin, +} + + +pub struct IdentityManager { + specialRolesUsers : HashMap>, +} + + +impl IdentityManager { + + pub fn init() -> IdentityManager { + let mut a = HashMap::new(); + for admn in adminvector() { + a.insert(admn.to_lowercase(),vec![userRole::BotAdmin]); + }; + + IdentityManager { + specialRolesUsers : a, + } + } +} + -- 2.46.1 From e1535aef2a511152aee5725ea156c1c87136e208 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:09:33 -0500 Subject: [PATCH 03/39] (cont) work on identity module --- src/core/botinstance.rs | 2 +- src/core/botmodules.rs | 3 +++ src/core/identity.rs | 49 ++++++++++++++++++++++++++++++++++---- src/modules/experiments.rs | 2 ++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 19596bf..0ec8541 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -222,7 +222,7 @@ impl BotInstance while let Some(message) = self.incoming_messages.recv().await { // Below can be used to debug if I want to capture all messages - //println!("Received message: {:?}", message); + println!("Received message: {:?}", message); match message { ServerMessage::Notice(msg) => { diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index b06858a..ae50cb7 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -3,6 +3,8 @@ use std::error::Error; use std::collections::HashMap; +use crate::core::identity; + /* @@ -89,6 +91,7 @@ pub struct BotCommand { // bot_prefix : char, // although should be global? pub exec_body : bot_actions::actions_util::ExecBody, pub help : String, + pub required_roles : Vec, } impl BotCommand diff --git a/src/core/identity.rs b/src/core/identity.rs index eca2243..3ad3b68 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1,12 +1,53 @@ use std::collections::HashMap; + +use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; +use crate::core::botmodules::bot_actions::actions_util; + +use crate::core::botinstance::{self}; +use twitch_irc::message::PrivmsgMessage; + fn adminvector() -> Vec { vec![String::from("ModulatingForce")] } -enum userRole { +pub fn init(mgr:&mut ModulesManager) +{ + + 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![], + }.add_to_modmgr(mgr); + + async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { + //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + } + + 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![], + }.add_to_modmgr(mgr); + + + async fn cmd_demote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { + + } + + +} + + +pub enum UserRole { Chatter, Mod(String), // String specifies Channel SupMod(String), // String specifies Channel @@ -16,7 +57,7 @@ enum userRole { pub struct IdentityManager { - specialRolesUsers : HashMap>, + special_roles_users : HashMap>, } @@ -25,11 +66,11 @@ impl IdentityManager { pub fn init() -> IdentityManager { let mut a = HashMap::new(); for admn in adminvector() { - a.insert(admn.to_lowercase(),vec![userRole::BotAdmin]); + a.insert(admn.to_lowercase(),vec![UserRole::BotAdmin]); }; IdentityManager { - specialRolesUsers : a, + special_roles_users : a, } } } diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 2d761d3..79cd388 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -30,6 +30,7 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![String::from("tester1"),String::from("testy1")], // String of alternative names exec_body : actions_util::asyncbox(testy) , help : String::from("DUPCMD4 tester"), + required_roles : vec![], }.add_to_modmgr(mgr); @@ -39,6 +40,7 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![String::from("tester2"),String::from("testy2")], // String of alternative names exec_body : actions_util::asyncbox(testy) , help : String::from("DUPCMD4 tester"), + required_roles : vec![], }.add_to_modmgr(mgr); -- 2.46.1 From 1343093ecd88a3c0ac2657fd3c0e67441aafc3f3 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:41:26 -0500 Subject: [PATCH 04/39] (init) identity > canUserRun() --- src/core/identity.rs | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 3ad3b68..fbf0fa1 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1,6 +1,6 @@ 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; @@ -8,6 +8,8 @@ use crate::core::botmodules::bot_actions::actions_util; use crate::core::botinstance::{self}; use twitch_irc::message::PrivmsgMessage; +use crate::core::botmodules::ChType; + fn adminvector() -> Vec { vec![String::from("ModulatingForce")] } @@ -27,6 +29,8 @@ pub fn init(mgr:&mut ModulesManager) async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + + } BotCommand { @@ -53,13 +57,24 @@ pub enum UserRole { SupMod(String), // String specifies Channel Broadcaster, BotAdmin, + } +enum Permissible { + Allow, + Block +} + pub struct IdentityManager { special_roles_users : HashMap>, } +enum ChatBadge { + Broadcaster, + Mod, +} + impl IdentityManager { @@ -73,5 +88,37 @@ impl IdentityManager { special_roles_users : a, } } + + pub fn canUserRun(self, + usr:String, + channelname:ChType, + chatBadge:ChatBadge, + cmdreqroles:Vec + ) -> Result> { + /* + canUserRun - + + Input : + usr:String, + channelname:ChType, + chatBadge:ChatBadge, + cmdreqroles:Vec + + 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 + + Inputs and business logic determine if the user can run the command based on the command's required roles + */ + + + + + Ok(Permissible::Allow) + } } -- 2.46.1 From e61f9fd4ac1b9c06d5a3b82a48fd83ce8d01c9c6 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:08:35 -0500 Subject: [PATCH 05/39] (cont) identity > canUserRun() - Logic Design (comments) --- src/core/identity.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index fbf0fa1..797f058 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -53,8 +53,8 @@ pub fn init(mgr:&mut ModulesManager) pub enum UserRole { Chatter, - Mod(String), // String specifies Channel - SupMod(String), // String specifies Channel + Mod(ChType), // String specifies Channel + SupMod(ChType), // String specifies Channel Broadcaster, BotAdmin, @@ -116,6 +116,17 @@ impl IdentityManager { */ + // Requirements + /* + [ ] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) + [ ] If chatBadge::Broadcaster ... + [ ] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) + [ ] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) + [ ] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) to determine if Ok(Permissible::Allow) + [ ] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) + [ ] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) + [ ] Otherwise, Ok(Permissible::Block) + */ Ok(Permissible::Allow) -- 2.46.1 From 4aaab7e2fa4706f33c203552b4101e53eb2e4e67 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:57:07 -0500 Subject: [PATCH 06/39] working identity > can_user_run() --- src/core/botinstance.rs | 42 ++++++-- src/core/botmodules.rs | 2 +- src/core/identity.rs | 192 +++++++++++++++++++++++++++++++++---- src/modules/experiments.rs | 27 ++++-- 4 files changed, 224 insertions(+), 39 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 0ec8541..37ce4db 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -22,7 +22,7 @@ use crate::core::ratelimiter; use crate::core::botmodules; use crate::core::botmodules::ModulesManager; -use crate::core::identity::IdentityManager; +use crate::core::identity::{IdentityManager,Permissible}; #[derive(Debug, PartialEq, Eq, Hash, Clone)] @@ -222,7 +222,7 @@ impl BotInstance while let Some(message) = self.incoming_messages.recv().await { // Below can be used to debug if I want to capture all messages - println!("Received message: {:?}", message); + // println!("Received message: {:?}", message); match message { ServerMessage::Notice(msg) => { @@ -271,7 +271,8 @@ impl BotInstance // PRIVATE FUNCTIONS - async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { + // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { + async fn listener_main_prvmsg(&self,msg:PrivmsgMessage) -> () { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -286,6 +287,11 @@ impl BotInstance /* 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( + _usr:String, + _channelname:ChType, + _chat_badge:ChatBadge, + _cmdreqroles:Vec) */ let inpt = msg.message_text.split("\n").next().expect("ERROR during BotCommand"); @@ -293,20 +299,40 @@ impl BotInstance // [x] Check if a bot command based on ... // [x] prefix + command - let mut exec_bot_command = false; + let mut confirmed_bot_command = false; if inpt == self.prefix.to_string() + c.command.as_str() { - exec_bot_command = true; + confirmed_bot_command = true; } // [x] prefix + alias for alias in &c.alias { if inpt == self.prefix.to_string() + alias.as_str() { - exec_bot_command = true; + confirmed_bot_command = true; } } - if exec_bot_command { - c.execute(self.chat.clone(), msg.clone()).await; + if confirmed_bot_command { + + // self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()); + + // [ ] Around here, validate if permissable before executing + // match self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // Ok(Permissible::Allow) => c.execute(self.chat.clone(), msg.clone()).await, + // Ok(Permissible::Block) => println!("User Not allowed to run command"), + // _ => (), + // } + + match self.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // Ok(Permissible::Allow) => (), + Permissible::Allow => { + println!("Executed as permissible"); + c.execute(self.chat.clone(), msg.clone()).await; + } + Permissible::Block => println!("User Not allowed to run command"), + // _ => (), + } + + // c.execute(self.chat.clone(), msg.clone()).await; } }, diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index ae50cb7..7be3673 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -34,7 +34,7 @@ pub enum ModType { pub use ModType::BotModule; -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { Channel(String), } diff --git a/src/core/identity.rs b/src/core/identity.rs index 797f058..3c02c88 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -6,7 +6,7 @@ use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, use crate::core::botmodules::bot_actions::actions_util; use crate::core::botinstance::{self}; -use twitch_irc::message::PrivmsgMessage; +use twitch_irc::message::{Badge, PrivmsgMessage}; use crate::core::botmodules::ChType; @@ -29,7 +29,7 @@ pub fn init(mgr:&mut ModulesManager) async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - + println!("Called cmd promote"); } @@ -44,13 +44,19 @@ pub fn init(mgr:&mut ModulesManager) async fn cmd_demote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { - + println!("Called cmd demote"); } } +// #[derive(Debug, PartialEq, Eq, Hash, Clone)] +// pub enum ChType { +// Channel(String), +// } + +#[derive(Debug, PartialEq, Eq , Clone)] pub enum UserRole { Chatter, Mod(ChType), // String specifies Channel @@ -61,16 +67,17 @@ pub enum UserRole { } -enum Permissible { +pub enum Permissible { Allow, Block } +#[derive(Clone)] pub struct IdentityManager { - special_roles_users : HashMap>, + special_roles_users : HashMap>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel } -enum ChatBadge { +pub enum ChatBadge { Broadcaster, Mod, } @@ -89,19 +96,57 @@ impl IdentityManager { } } - pub fn canUserRun(self, + // [ ] 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) -> Permissible + { + // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + + // [ ] Check what Badges in PrivmsgMessage + + let mut sender_badge:Option = None; + + for b in &msg.badges { + if b.name == "moderator" { + sender_badge = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + sender_badge = Some(ChatBadge::Broadcaster); + } + } + + // if &msg.badges.contains(Badge{}) { + + // } + + if let Some(sender_badge) = sender_badge { + return self.can_user_run(msg.sender.name.to_owned(), + ChType::Channel(msg.channel_login.to_owned()), + sender_badge, + cmdreqroles + ) ; + } + + + + // [ ] Call can_user_run() + Permissible::Block + } + + pub fn can_user_run(mut self, usr:String, channelname:ChType, - chatBadge:ChatBadge, + chat_badge:ChatBadge, cmdreqroles:Vec - ) -> Result> { + // ) -> Result> { + ) -> Permissible { /* canUserRun - Input : usr:String, channelname:ChType, - chatBadge:ChatBadge, + chat_badge:ChatBadge, cmdreqroles:Vec Output : Result> @@ -118,18 +163,125 @@ impl IdentityManager { // Requirements /* - [ ] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) - [ ] If chatBadge::Broadcaster ... - [ ] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) - [ ] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) - [ ] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) to determine if Ok(Permissible::Allow) - [ ] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) - [ ] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) - [ ] Otherwise, Ok(Permissible::Block) + [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) - Ok(Permissible::Allow) + if cmdreqroles.len() == 0 { + // return Ok(Permissible::Allow) + return Permissible::Allow + } + + + + 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) + + 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 + } + }, + + // [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) + + ChatBadge::Mod => { + + println!("Mod Chatbadge detected"); + + 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()) { + Some(usrroles) => { + println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); + println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); + if usrroles.contains(&UserRole::Mod(channelname.clone())) || + usrroles.contains(&UserRole::SupMod(channelname.clone())) { + // Do nothing - this is expected + } else { + // in this case, they have a ChatBadge::Mod but should have this for the channel + usrroles.push(UserRole::Mod(channelname.clone())); + println!("debug special roles : {:?}",self.special_roles_users); + } + }, + _ => () + } + + }, + // _ => (), + } + + // [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); + + if cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) { + // match self.special_roles_users.get(&channelname) { + // Some(usrroles) => {}, + // None => (), + + // } + + println!("Mod Role required"); + + if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) { + if a.contains(&UserRole::Mod(channelname.clone())) || a.contains(&UserRole::SupMod(channelname.clone())){ + // return Ok(Permissible::Allow); + return Permissible::Allow + } + } + } + + + // [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.get(&usr.to_lowercase()) { + if a.contains(&UserRole::SupMod(channelname.clone())) { + // return Ok(Permissible::Allow); + return Permissible::Allow + } + } + } + + + // [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) + + println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); + + if cmdreqroles.contains(&UserRole::BotAdmin) { + println!("special roles get : {:?}",self.special_roles_users.get(&usr.to_lowercase())); + if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) { + println!("special roles contains BotAdmin: {}",a.contains(&UserRole::BotAdmin)); + if a.contains(&UserRole::BotAdmin) { + // return Ok(Permissible::Allow); + return Permissible::Allow + } + } + } + + Permissible::Block } } - diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 79cd388..0078ea8 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -14,12 +14,14 @@ use std::future::Future; -use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; +use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType}; use crate::core::botmodules::bot_actions::actions_util; use crate::core::botinstance::{self}; use twitch_irc::message::PrivmsgMessage; +use crate::core::identity; + pub fn init(mgr:&mut ModulesManager) { @@ -30,7 +32,10 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![String::from("tester1"),String::from("testy1")], // String of alternative names exec_body : actions_util::asyncbox(testy) , help : String::from("DUPCMD4 tester"), - required_roles : vec![], + required_roles : vec![ + //identity::UserRole::Mod(ChType::Channel(String::new())), + identity::UserRole::SupMod(ChType::Channel(String::new())) + ], }.add_to_modmgr(mgr); @@ -40,19 +45,21 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![String::from("tester2"),String::from("testy2")], // String of alternative names exec_body : actions_util::asyncbox(testy) , help : String::from("DUPCMD4 tester"), - required_roles : vec![], + required_roles : vec![ + identity::UserRole::BotAdmin + ], }.add_to_modmgr(mgr); - let list1 = Listener { - module : BotModule(String::from("experiments 004")), - name : String::from("GoodGirl Listener"), - exec_body : actions_util::asyncbox(good_girl) , - help : String::from("") - }; + // let list1 = Listener { + // module : BotModule(String::from("experiments 004")), + // name : String::from("GoodGirl Listener"), + // exec_body : actions_util::asyncbox(good_girl) , + // help : String::from("") + // }; - list1.add_to_modmgr(mgr); + // list1.add_to_modmgr(mgr); } -- 2.46.1 From b2dc82ee906070f57a193755a02e6584bfed1583 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 30 Jan 2024 09:13:59 -0500 Subject: [PATCH 07/39] (init) identity > promote/demote commands --- src/core/botmodules.rs | 2 ++ src/core/identity.rs | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 7be3673..7186730 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -199,6 +199,8 @@ impl ModulesManager botactions : act, }; + // initialize core modules + crate::core::identity::init(&mut mgr); // initialize custom crate modules crate::modules::init(&mut mgr); diff --git a/src/core/identity.rs b/src/core/identity.rs index 3c02c88..49a3528 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -24,7 +24,12 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![], // String of alternative names exec_body : actions_util::asyncbox(cmd_promote) , help : String::from("promote"), - required_roles : vec![], + required_roles : vec![ + UserRole::Mod(ChType::Channel(String::new())), + UserRole::SupMod(ChType::Channel(String::new())), + UserRole::Broadcaster, + UserRole::BotAdmin, + ], }.add_to_modmgr(mgr); async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { @@ -39,7 +44,12 @@ pub fn init(mgr:&mut ModulesManager) alias : vec![], // String of alternative names exec_body : actions_util::asyncbox(cmd_demote) , help : String::from("demote"), - required_roles : vec![], + required_roles : vec![ + UserRole::Mod(ChType::Channel(String::new())), + UserRole::SupMod(ChType::Channel(String::new())), + UserRole::Broadcaster, + UserRole::BotAdmin, + ], }.add_to_modmgr(mgr); @@ -206,23 +216,23 @@ impl IdentityManager { ChatBadge::Mod => { - println!("Mod Chatbadge detected"); + // println!("Mod Chatbadge detected"); - println!("debug special roles : {:?}",self.special_roles_users); - println!("debug usr : {}",&usr.to_lowercase()); + // 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()) { Some(usrroles) => { - println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); - println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); + // println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); + // println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); if usrroles.contains(&UserRole::Mod(channelname.clone())) || usrroles.contains(&UserRole::SupMod(channelname.clone())) { // Do nothing - this is expected } else { // in this case, they have a ChatBadge::Mod but should have this for the channel usrroles.push(UserRole::Mod(channelname.clone())); - println!("debug special roles : {:?}",self.special_roles_users); + // println!("debug special roles : {:?}",self.special_roles_users); } }, _ => () -- 2.46.1 From 26fc8b86830cd6103d6bf7f65d0f552cb0e5310e Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:48:54 -0500 Subject: [PATCH 08/39] added funny random listener/responder --- src/modules/experiments.rs | 71 +++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 0078ea8..7f028fa 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -22,29 +22,33 @@ use twitch_irc::message::PrivmsgMessage; use crate::core::identity; + +use rand::Rng; + + pub fn init(mgr:&mut ModulesManager) { + // BotCommand { + // module : BotModule(String::from("experiments 004")), + // 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("DUPCMD4 tester"), + // required_roles : vec![ + // //identity::UserRole::Mod(ChType::Channel(String::new())), + // identity::UserRole::SupMod(ChType::Channel(String::new())) + // ], + // }.add_to_modmgr(mgr); + + BotCommand { - module : BotModule(String::from("experiments 004")), + 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("DUPCMD4 tester"), - required_roles : vec![ - //identity::UserRole::Mod(ChType::Channel(String::new())), - identity::UserRole::SupMod(ChType::Channel(String::new())) - ], - }.add_to_modmgr(mgr); - - - BotCommand { - module : BotModule(String::from("experiments 004")), - command : String::from("test2"), // command call name - alias : vec![String::from("tester2"),String::from("testy2")], // String of alternative names - exec_body : actions_util::asyncbox(testy) , - help : String::from("DUPCMD4 tester"), + help : String::from("Test Command tester"), required_roles : vec![ identity::UserRole::BotAdmin ], @@ -52,14 +56,14 @@ pub fn init(mgr:&mut ModulesManager) - // let list1 = Listener { - // module : BotModule(String::from("experiments 004")), - // name : String::from("GoodGirl Listener"), - // exec_body : actions_util::asyncbox(good_girl) , - // help : String::from("") - // }; + let list1 = Listener { + module : BotModule(String::from("experiments001")), + name : String::from("GoodGirl Listener"), + exec_body : actions_util::asyncbox(good_girl) , + help : String::from("") + }; - // list1.add_to_modmgr(mgr); + list1.add_to_modmgr(mgr); } @@ -70,11 +74,30 @@ async fn good_girl(mut chat:botinstance::Chat,msg:PrivmsgMessage) println!("In GoodGirl()"); //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - if msg.sender.name == "ModulatingForce" && msg.message_text.contains("GoodGirl") { - chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; + // [ ] 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 + + //let mut rng = thread_rng(); + + // let roll = rand::thread_rng().gen_range(1..=5); + + + + if msg.sender.name == "ModulatingForce" // && msg.message_text.contains("GoodGirl") + { + // chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; + //if rng.gen_ratio(1,5) { + let rollwin = rand::thread_rng().gen_ratio(1,10); + if rollwin { + chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; + } + } + + } async fn testy(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) -- 2.46.1 From 50321a7ce00fbccb668fe1cff0c8424727bd1fc0 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 30 Jan 2024 15:07:40 -0500 Subject: [PATCH 09/39] (cont) identity > promote - comments --- src/core/identity.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/core/identity.rs b/src/core/identity.rs index 49a3528..f7aed5d 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -36,6 +36,25 @@ pub fn init(mgr:&mut ModulesManager) //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); + // -- If the BotCommand.command was called (e.g., promote), this is the current function body to execute + + /* + - `promote` / `demote` + - [ ] `SupMod` & `Broadcaster` & `BotAdmin` can run + - [ ] `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 : + - [ ] 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 + - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` + */ + + + // [ ] Split message based on arguments + + + } BotCommand { -- 2.46.1 From a6aedb291fa29951c32b51e570c77eaf9067b6e8 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:21:58 -0500 Subject: [PATCH 10/39] introduced BotManagers to BotInstance --- src/core/botinstance.rs | 29 +++++++++++++++++++++++------ src/core/botmodules.rs | 4 ++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 37ce4db..80bfb06 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -130,16 +130,32 @@ impl Chat { +pub struct BotManagers { + pub botmodules : ModulesManager, + pub identity : IdentityManager, +} + +impl BotManagers { + + pub fn init() -> BotManagers { + BotManagers { + botmodules : ModulesManager::init(), + identity : IdentityManager::init(), + } + } +} + pub struct BotInstance { prefix : char, bot_channel : ChType, pub incoming_messages : UnboundedReceiver, pub chat : Chat, - pub botmodules : ModulesManager, + // pub botmodules : ModulesManager, twitch_oauth : String, pub bot_channels : Vec, - pub identity : IdentityManager, + // pub identity : IdentityManager, + pub botmgrs : BotManagers, } @@ -203,10 +219,11 @@ impl BotInstance ratelimiters : ratelimiters, client : client, } , - botmodules : ModulesManager::init(), + // botmodules : ModulesManager::init(), twitch_oauth : oauth_token, bot_channels : botchannels, - identity : IdentityManager::init(), + // identity : IdentityManager::init(), + botmgrs : BotManagers::init(), }; @@ -278,7 +295,7 @@ impl BotInstance // // [ ] 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) - for (_m,acts) in &self.botmodules.botactions { + for (_m,acts) in &self.botmgrs.botmodules.botactions { for a in acts { match a { @@ -322,7 +339,7 @@ impl BotInstance // _ => (), // } - match self.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 7186730..4035a35 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -105,7 +105,7 @@ impl BotCommand impl BotActionTrait for BotCommand { fn add_to_bot(self, mut bot:BotInstance) { - let mgr = &mut bot.botmodules; + let mgr = &mut bot.botmgrs.botmodules; self.add_to_modmgr(mgr); } @@ -162,7 +162,7 @@ impl BotActionTrait for Listener { fn add_to_bot(self, mut bot:BotInstance) { - let mgr = &mut bot.botmodules; + let mgr = &mut bot.botmgrs.botmodules; self.add_to_modmgr(mgr); } -- 2.46.1 From a556a5aa892b934f7a74d32f95055564714a8e6d Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 31 Jan 2024 01:07:27 -0500 Subject: [PATCH 11/39] (cont) BotManagers --- src/core/botinstance.rs | 8 ++++++++ src/core/botmodules.rs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 80bfb06..6b3903f 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -48,6 +48,14 @@ pub struct Chat { impl Chat { + pub fn init(ratelimiters:HashMap, + client:TwitchIRCClient, StaticLoginCredentials>) -> Chat { + Chat{ + ratelimiters : ratelimiters, + client : client, + } + } + pub fn init_channel(&mut self, chnl:ChType) -> () { let n = RateLimiter::new(); self.ratelimiters.insert(chnl,n); diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 4035a35..bdaba67 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -129,7 +129,9 @@ pub mod bot_actions { use twitch_irc::message::PrivmsgMessage; pub type ExecBody = Box Pin + Send>> + Send + Sync>; + //pub type ExecBody = Box Pin + Send>> + Send + Sync>; + //pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody where T: Future + Send + 'static, -- 2.46.1 From 8a93ef04696514d9084152f7a2dd5b82745a5e50 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 31 Jan 2024 01:11:45 -0500 Subject: [PATCH 12/39] (cont) BotManagers compile --- src/core/botinstance.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 6b3903f..5e94c56 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -141,14 +141,18 @@ impl Chat { pub struct BotManagers { pub botmodules : ModulesManager, pub identity : IdentityManager, + pub chat : Chat, } impl BotManagers { - pub fn init() -> BotManagers { + pub fn init(ratelimiters:HashMap, + client:TwitchIRCClient, StaticLoginCredentials>) + -> BotManagers { BotManagers { botmodules : ModulesManager::init(), identity : IdentityManager::init(), + chat : Chat::init(ratelimiters,client), } } } @@ -158,7 +162,7 @@ pub struct BotInstance prefix : char, bot_channel : ChType, pub incoming_messages : UnboundedReceiver, - pub chat : Chat, + // pub chat : Chat, // pub botmodules : ModulesManager, twitch_oauth : String, pub bot_channels : Vec, @@ -223,19 +227,19 @@ impl BotInstance bot_channel : Channel(login_name) , incoming_messages : incoming_messages, //client : client, - chat : Chat { - ratelimiters : ratelimiters, - client : client, - } , + // chat : Chat { + // ratelimiters : ratelimiters, + // client : client, + // } , // botmodules : ModulesManager::init(), twitch_oauth : oauth_token, bot_channels : botchannels, // identity : IdentityManager::init(), - botmgrs : BotManagers::init(), + botmgrs : BotManagers::init(ratelimiters,client), }; - println!("{:?}",b.chat.ratelimiters); + println!("{:?}",b.botmgrs.chat.ratelimiters); b @@ -351,7 +355,7 @@ impl BotInstance // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); - c.execute(self.chat.clone(), msg.clone()).await; + c.execute(self.botmgrs.chat.clone(), msg.clone()).await; } Permissible::Block => println!("User Not allowed to run command"), // _ => (), @@ -361,7 +365,7 @@ impl BotInstance } }, - crate::core::botmodules::BotAction::L(l) => l.execute(self.chat.clone(), msg.clone()).await, + crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.chat.clone(), msg.clone()).await, _ => (), } -- 2.46.1 From be2e967e40ce18fc422227b8f4a55d97c132cacb Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:31:14 -0500 Subject: [PATCH 13/39] 2024.01.31 - Latest Borrow Compile Err --- src/core/botinstance.rs | 15 ++++++++++----- src/core/identity.rs | 22 ++++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 5e94c56..850d262 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -154,6 +154,9 @@ impl BotManagers { identity : IdentityManager::init(), chat : Chat::init(ratelimiters,client), } + + + } } @@ -249,7 +252,7 @@ impl BotInstance let join_handle = tokio::spawn(async move { - while let Some(message) = self.incoming_messages.recv().await { + while let Some(message) = &self.incoming_messages.recv().await { // Below can be used to debug if I want to capture all messages // println!("Received message: {:?}", message); @@ -258,7 +261,7 @@ impl BotInstance // if let Some(chnl) = msg.channel_login { // println!("NOTICE : (#{}) {}", chnl, msg.message_text); // } - match msg.channel_login { + match &msg.channel_login { Some(chnl) => println!("NOTICE : (#{}) {}", chnl, msg.message_text), None => println!("NOTICE : {}", msg.message_text), } @@ -269,7 +272,7 @@ impl BotInstance println!("Privmsg section"); // b.listener_main_prvmsg(&msg); - self.listener_main_prvmsg(msg).await; + self.listener_main_prvmsg(&msg).await; // - BotCommand listener should likely need to be called within the above @@ -301,7 +304,7 @@ impl BotInstance // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - async fn listener_main_prvmsg(&self,msg:PrivmsgMessage) -> () { + async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -351,7 +354,9 @@ impl BotInstance // _ => (), // } - match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); diff --git a/src/core/identity.rs b/src/core/identity.rs index f7aed5d..d1278b1 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -101,9 +101,11 @@ pub enum Permissible { Block } -#[derive(Clone)] +//#[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 + // parent_mgr : Box, + parent_mgr : Option>, } pub enum ChatBadge { @@ -122,13 +124,14 @@ impl IdentityManager { IdentityManager { special_roles_users : a, + parent_mgr : None, } } // [ ] 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) -> Permissible + pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> &Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -149,7 +152,7 @@ impl IdentityManager { // } if let Some(sender_badge) = sender_badge { - return self.can_user_run(msg.sender.name.to_owned(), + return &self.can_user_run(msg.sender.name.to_owned(), ChType::Channel(msg.channel_login.to_owned()), sender_badge, cmdreqroles @@ -159,7 +162,7 @@ impl IdentityManager { // [ ] Call can_user_run() - Permissible::Block + &Permissible::Block } pub fn can_user_run(mut self, @@ -241,7 +244,8 @@ impl IdentityManager { // 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_mut(&usr.to_lowercase()) { + match self.special_roles_users.get(&usr.to_lowercase()) { Some(usrroles) => { // println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); // println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); @@ -250,7 +254,13 @@ impl IdentityManager { // Do nothing - this is expected } else { // in this case, they have a ChatBadge::Mod but should have this for the channel - usrroles.push(UserRole::Mod(channelname.clone())); + // let mut a = usrroles; + // usrroles.push(UserRole::Mod(channelname.clone())); + // a.push(UserRole::Mod(channelname.clone())); + self.special_roles_users + .get_mut(&usr.to_lowercase()) + .expect("ERROR") + .push(UserRole::Mod(channelname.clone())); // println!("debug special roles : {:?}",self.special_roles_users); } }, -- 2.46.1 From f8b9cefacbc718a4d7eb3d18655229dec5bb3514 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 31 Jan 2024 18:36:23 -0500 Subject: [PATCH 14/39] Working - BotManagers Added --- src/core/botinstance.rs | 20 ++++++++++---------- src/core/botmodules.rs | 18 ++++++++++-------- src/core/identity.rs | 16 ++++++++++------ src/modules/experiments.rs | 10 ++++++---- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 850d262..23f4a82 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -137,9 +137,9 @@ impl Chat { } - +#[derive(Clone)] pub struct BotManagers { - pub botmodules : ModulesManager, + // pub botmodules : ModulesManager, pub identity : IdentityManager, pub chat : Chat, } @@ -150,7 +150,7 @@ impl BotManagers { client:TwitchIRCClient, StaticLoginCredentials>) -> BotManagers { BotManagers { - botmodules : ModulesManager::init(), + // botmodules : ModulesManager::init(), identity : IdentityManager::init(), chat : Chat::init(ratelimiters,client), } @@ -166,7 +166,7 @@ pub struct BotInstance bot_channel : ChType, pub incoming_messages : UnboundedReceiver, // pub chat : Chat, - // pub botmodules : ModulesManager, + pub botmodules : ModulesManager, twitch_oauth : String, pub bot_channels : Vec, // pub identity : IdentityManager, @@ -234,7 +234,7 @@ impl BotInstance // ratelimiters : ratelimiters, // client : client, // } , - // botmodules : ModulesManager::init(), + botmodules : ModulesManager::init(), twitch_oauth : oauth_token, bot_channels : botchannels, // identity : IdentityManager::init(), @@ -304,13 +304,13 @@ impl BotInstance // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { + async fn listener_main_prvmsg(&self,msg:&PrivmsgMessage) -> () { // 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) - for (_m,acts) in &self.botmgrs.botmodules.botactions { + for (_m,acts) in &self.botmodules.botactions { for a in acts { match a { @@ -356,11 +356,11 @@ impl BotInstance // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); - c.execute(self.botmgrs.chat.clone(), msg.clone()).await; + c.execute(self.botmgrs.clone(), msg.clone()).await; } Permissible::Block => println!("User Not allowed to run command"), // _ => (), @@ -370,7 +370,7 @@ impl BotInstance } }, - crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.chat.clone(), msg.clone()).await, + crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.clone(), msg.clone()).await, _ => (), } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index bdaba67..ab52696 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -66,7 +66,7 @@ pub enum BotAction } impl BotAction { - pub async fn execute(&self,m:botinstance::Chat,n:PrivmsgMessage){ + pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ match self { BotAction::L(a) => a.execute(m,n).await, @@ -96,7 +96,7 @@ pub struct BotCommand { impl BotCommand { - pub async fn execute(&self,m:botinstance::Chat,n:PrivmsgMessage){ + pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ (self.exec_body)(m,n).await; } } @@ -105,7 +105,7 @@ impl BotCommand impl BotActionTrait for BotCommand { fn add_to_bot(self, mut bot:BotInstance) { - let mgr = &mut bot.botmgrs.botmodules; + let mgr = &mut bot.botmodules; self.add_to_modmgr(mgr); } @@ -125,14 +125,16 @@ pub mod bot_actions { use std::boxed::Box; use std::pin::Pin; - use crate::core::botinstance::Chat; + use crate::core::botinstance::{BotManagers, Chat}; use twitch_irc::message::PrivmsgMessage; - pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; //pub type ExecBody = Box Pin + Send>> + Send + Sync>; + pub type ExecBody = Box Pin + Send>> + Send + Sync>; //pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody - pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody + pub fn asyncbox(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody where T: Future + Send + 'static, { @@ -155,7 +157,7 @@ pub struct Listener impl Listener { - pub async fn execute(&self,m:botinstance::Chat,n:PrivmsgMessage){ + pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ (self.exec_body)(m,n).await; } } @@ -164,7 +166,7 @@ impl BotActionTrait for Listener { fn add_to_bot(self, mut bot:BotInstance) { - let mgr = &mut bot.botmgrs.botmodules; + let mgr = &mut bot.botmodules; self.add_to_modmgr(mgr); } diff --git a/src/core/identity.rs b/src/core/identity.rs index d1278b1..3424e14 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -32,7 +32,7 @@ pub fn init(mgr:&mut ModulesManager) ], }.add_to_modmgr(mgr); - async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { + async fn cmd_promote(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); @@ -72,7 +72,7 @@ pub fn init(mgr:&mut ModulesManager) }.add_to_modmgr(mgr); - async fn cmd_demote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) { + async fn cmd_demote(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) { println!("Called cmd demote"); } @@ -101,7 +101,7 @@ pub enum Permissible { Block } -//#[derive(Clone)] +#[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 // parent_mgr : Box, @@ -131,7 +131,7 @@ impl IdentityManager { // [ ] 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) -> &Permissible + pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -152,7 +152,11 @@ impl IdentityManager { // } if let Some(sender_badge) = sender_badge { - return &self.can_user_run(msg.sender.name.to_owned(), + // 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(), ChType::Channel(msg.channel_login.to_owned()), sender_badge, cmdreqroles @@ -162,7 +166,7 @@ impl IdentityManager { // [ ] Call can_user_run() - &Permissible::Block + Permissible::Block } pub fn can_user_run(mut self, diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 7f028fa..86e2a38 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -69,7 +69,7 @@ pub fn init(mgr:&mut ModulesManager) } -async fn good_girl(mut chat:botinstance::Chat,msg:PrivmsgMessage) +async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage) { println!("In GoodGirl()"); //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -88,9 +88,11 @@ async fn good_girl(mut chat:botinstance::Chat,msg:PrivmsgMessage) { // chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; //if rng.gen_ratio(1,5) { - let rollwin = rand::thread_rng().gen_ratio(1,10); + println!("In GoodGirl() > Pausechamp"); + let rollwin = rand::thread_rng().gen_ratio(1,5); if rollwin { - chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; + println!("In GoodGirl() > Win"); + bot.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; } } @@ -100,7 +102,7 @@ async fn good_girl(mut chat:botinstance::Chat,msg:PrivmsgMessage) } -async fn testy(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) +async fn testy(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) { println!("testy triggered!") -- 2.46.1 From b316596f17651c48b514fd068d768d510d66a4ca Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 31 Jan 2024 21:30:08 -0500 Subject: [PATCH 15/39] added identity > getroles --- src/core/botinstance.rs | 8 ++ src/core/identity.rs | 159 +++++++++++++++++++++++++++++++++++-- src/modules/experiments.rs | 2 +- 3 files changed, 163 insertions(+), 6 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 23f4a82..568d4e6 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -326,7 +326,15 @@ impl BotInstance _cmdreqroles:Vec) */ + // for v in msg.message_text.split(" ") { + // println!("args : {v}"); + // } + let inpt = msg.message_text.split("\n").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 diff --git a/src/core/identity.rs b/src/core/identity.rs index 3424e14..8eae489 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -32,11 +32,12 @@ pub fn init(mgr:&mut ModulesManager) ], }.add_to_modmgr(mgr); - async fn cmd_promote(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) { + async fn cmd_promote(bot:botinstance::BotManagers,_msg:PrivmsgMessage) { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); - // -- If the BotCommand.command was called (e.g., promote), this is the current function body to execute + // -- 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 /* - `promote` / `demote` @@ -51,7 +52,18 @@ pub fn init(mgr:&mut ModulesManager) */ - // [ ] Split message based on arguments + /* + Usage : + + promote + + demote + + promote admin + + */ + + @@ -77,6 +89,95 @@ pub fn init(mgr:&mut ModulesManager) } + + 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, + ], + }.add_to_modmgr(mgr); + + + async fn getroles(bot:botinstance::BotManagers,msg:PrivmsgMessage) { + println!("Called cmd getroles"); + + /* + Usage + + getroles + - If channel is provided, provide roles for that channel specifically + + */ + + // IN other code areas , I see this + // ServerMessage::Privmsg(msg) => { + // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + + println!("{}",msg.message_text); + let mut argv = msg.message_text.split(" "); + + // for v in argv { + // println!("args : {v}"); + // } + + + let arg = argv.next(); // Skip the command name + + let arg1 = argv.next(); + + // if arg == None { + // return ; // Do nothing if no arguments + // } + + + let targetuser = match arg1 { + None => return , // exit if no arguments + Some(arg) => arg, + }; + + // match String::from(arg1) { + // a if a == String::from("admin") => (), + // _ => (), + // } + + + // match argv[1] { + // String::from("admin") => (), + + // } + + let arg2 = argv.next(); + + let targetchnl = arg2; + + match targetchnl { + None => { + let a = bot.identity.getspecialuserroles(String::from(targetuser),None); + println!("Retrieved User Roles >> {:?}",a); + }, + Some(targetchnl) => { + let a = bot.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl)))); + println!("Retrieved User Roles >> {:?}",a); + }, + } + + + // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot")))); + // println!("{:?}",a); + + } + + + + + } @@ -105,7 +206,7 @@ pub enum Permissible { pub struct IdentityManager { special_roles_users : HashMap>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel // parent_mgr : Box, - parent_mgr : Option>, + //parent_mgr : Option>, } pub enum ChatBadge { @@ -114,6 +215,13 @@ pub enum ChatBadge { } +enum ChangeResult { + Success(String), + Failed(String), + NoChange(String), +} + + impl IdentityManager { pub fn init() -> IdentityManager { @@ -124,7 +232,7 @@ impl IdentityManager { IdentityManager { special_roles_users : a, - parent_mgr : None, + //parent_mgr : None, } } @@ -327,4 +435,45 @@ impl IdentityManager { Permissible::Block } + + pub fn promote(self,trgchatter:String,channel:ChType) -> ChangeResult { + + ChangeResult::Success(String::from("Promotion Successful")) + } + + pub fn demote(self,trgchatter:String,channel:ChType) -> ChangeResult { + + ChangeResult::Success(String::from("Promotion Successful")) + } + + pub fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option<&Vec> { + + // let a = chattername.to_lowercase(); + + // self.special_roles_users.get(&a) + + + + // for k in self.special_roles_users.keys() { + // println!("Special Roles Keys {k}"); + // for v in + // } + + // for (k,v) in &self.special_roles_users { + // println!("User {k}"); + // println!("> Roles : {:?}",v); + // } + + let a = chattername.to_lowercase(); + + // println!("{a}"); + + self.special_roles_users.get(&a) + + + + // Some(vec![UserRole::Mod(ChType::Channel(String::from("modulatingforcebot")))]) + } + + } diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 86e2a38..0c3709b 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -71,7 +71,7 @@ pub fn init(mgr:&mut ModulesManager) async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage) { - println!("In GoodGirl()"); + println!("In GoodGirl() Listener"); //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // [ ] Uses gen_ratio() to output bool based on a ratio probability . -- 2.46.1 From 768bb5f03ab7b7f31a0857961930e439807805b1 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 1 Feb 2024 08:40:09 -0500 Subject: [PATCH 16/39] (cont) promote --- src/core/identity.rs | 183 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 7 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 8eae489..a6c6337 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -32,7 +32,7 @@ pub fn init(mgr:&mut ModulesManager) ], }.add_to_modmgr(mgr); - async fn cmd_promote(bot:botinstance::BotManagers,_msg:PrivmsgMessage) { + async fn cmd_promote(bot:botinstance::BotManagers,msg:PrivmsgMessage) { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); @@ -63,6 +63,73 @@ pub fn init(mgr:&mut ModulesManager) */ + println!("{}",msg.message_text); + let mut argv = msg.message_text.split(" "); + + argv.next(); // Skip the command name + + let arg1 = argv.next(); + + let arg2 = argv.next(); + + let mut sender_badge:Option = None; + + for b in &msg.badges { + if b.name == "moderator" { + sender_badge = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + sender_badge = Some(ChatBadge::Broadcaster); + } + } + + + match arg1 { + Some(a) if a == String::from("admin") => { + // - BotAdmins can promote admin to give BotAdmin UserRole + let a = bot.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + + if let Some(a) = a { + if a.contains(&UserRole::BotAdmin) { + println!("BotAdmin allowed to promote admin"); + match bot.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // Success(_) => { + // ; + // }, + ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), + ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), + ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + + } + } + } + + }, + Some(_) => { + // - + + }, + _ => (), + } + + + + // match String::from(arg1) { + // a if a == String::from("admin") => (), + // _ => (), + // } + + + // match argv[1] { + // String::from("admin") => (), + + // } + + let arg2 = argv.next(); + + let targetchnl = arg2; + + + @@ -120,7 +187,7 @@ pub fn init(mgr:&mut ModulesManager) // ServerMessage::Privmsg(msg) => { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - println!("{}",msg.message_text); + // println!("{}",msg.message_text); let mut argv = msg.message_text.split(" "); // for v in argv { @@ -128,7 +195,7 @@ pub fn init(mgr:&mut ModulesManager) // } - let arg = argv.next(); // Skip the command name + argv.next(); // Skip the command name let arg1 = argv.next(); @@ -436,14 +503,116 @@ impl IdentityManager { Permissible::Block } - pub fn promote(self,trgchatter:String,channel:ChType) -> ChangeResult { + pub fn promote(mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { - ChangeResult::Success(String::from("Promotion Successful")) + // Note : If channel is none, getspecialuserroles() returns all roles for the user + + // let chatterroles = self.getspecialuserroles(trgchatter, channel); + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()); + + let emptyvec = vec![]; + + let chatterroles = match chatterroles { + Some(a) => a, + _ => &(emptyvec), + }; + + + match trg_role { + Some(UserRole::Mod(a)) => { + if let Some(trg_chnl) = channel { + if chatterroles.contains(&UserRole::Mod(trg_chnl.clone())) { + return ChangeResult::NoChange(String::from("Target User already has Target Role")); + } + // # otherwise, trg_role for the given chnl is not assigned to the trgchatter + // chatterroles.push(UserRole::Mod(trg_chnl.clone())); + self.special_roles_users + .get_mut(&trgchatter) + .expect("Error getting roles") + .push(UserRole::Mod(trg_chnl)); + + return ChangeResult::Success(String::from("Promotion Successful")); + } + + + }, + Some(UserRole::SupMod(a)) => (), + Some(UserRole::BotAdmin) => (), + Some(_) => (), + None => (), + } + + + // match chatterroles { + // Some(chatterroles) => { + + // // [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 + // // match trgRole { + // // Some(trgRole) => { + // // match trgRole { + // // UserRole::Mod(a) => { + + // // }, + // // UserRole::SupMod(a) => (), + // // UserRole::BotAdmin => (), + // // _ => (), // <-- do nothing with al other options + // // } + // // }, + // // None => { + // // /* + // // - 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 + // // */ + // // }, + + // // } + + // // let trgRole = match trgRole { + // // Some(UserRole::Mod(a)) => a, + // // Some(UserRole::SupMod(a)) => a, + // // Some(UserRole::BotAdmin) => UserRole::BotAdmin, + // // None => { + // // /* + // // - 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 + // // */ + // // }, + + // // }; + + + + // // if let Some(trgRole) = trgRole { + + // // // [x] chatter already has the target role + // // if chatterroles.contains(&trgRole) { + // // return ChangeResult::NoChange(String::from("Target User already has Target Role")); + // // } + + // // // [ ] trgRole should be assigned based on the input channel + // // let roletoassign = UserRole:: + // // } + + // }, + // _ => (), + // } + + ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub fn demote(self,trgchatter:String,channel:ChType) -> ChangeResult { + pub fn demote(self,trgchatter:String,channel:Option,trgRole:Option) -> ChangeResult { - ChangeResult::Success(String::from("Promotion Successful")) + ChangeResult::Success(String::from("TEST > Promotion Successful")) } pub fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option<&Vec> { -- 2.46.1 From 8d4db0c657c6721345b0c2a3483ee8d49b1f4b2f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:28:37 -0500 Subject: [PATCH 17/39] 2024.02.04 - LATEST PROBLEM --- Cargo.lock | 62 ++++++ Cargo.toml | 2 + src/core/botinstance.rs | 403 +++++++++++++++++++++++++++++++++---- src/core/botmodules.rs | 125 +++++++++--- src/core/identity.rs | 274 ++++++++++++++++++++----- src/main.rs | 6 +- src/modules.rs | 6 +- src/modules/experiments.rs | 58 +++++- 8 files changed, 815 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a76afd..1425d4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" name = "forcebot_rs" version = "0.1.0" dependencies = [ + "async-trait", "dotenv", + "futures", "rand", "tokio", "twitch-irc", @@ -198,7 +200,67 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", diff --git a/Cargo.toml b/Cargo.toml index 417031d..0043332 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,5 @@ dotenv = "0.15.0" tokio = { version = "1.33.0", features = ["full"] } twitch-irc = "5.0.1" rand = { version = "0.8.5", features = [] } +futures = "0.3" +async-trait = "0.1.77" \ No newline at end of file diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 568d4e6..5f9561d 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -1,4 +1,5 @@ +use futures::lock::Mutex; use tokio::sync::mpsc::UnboundedReceiver; use twitch_irc::login::StaticLoginCredentials; use twitch_irc::ClientConfig; @@ -8,6 +9,10 @@ use twitch_irc::message::PrivmsgMessage; use twitch_irc::message::ServerMessage; use twitch_irc::transport::tcp::TCPTransport; use twitch_irc::transport::tcp::TLS; +// use std::borrow::Borrow; +use std::borrow::BorrowMut; +use std::boxed; +use std::cell::Ref; use std::env; use dotenv::dotenv; @@ -21,9 +26,19 @@ use crate::core::ratelimiter::RateLimiter; use crate::core::ratelimiter; use crate::core::botmodules; -use crate::core::botmodules::ModulesManager; +use crate::core::botmodules::{ModulesManager,BotAction}; use crate::core::identity::{IdentityManager,Permissible}; +use std::rc::Rc; +use std::cell::RefCell; +use std::sync::{Arc, RwLock}; +// use futures::lock::Mutex; + +use std::pin::Pin; + +//use std::borrow::Borrow; +use core::borrow::Borrow; + #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { @@ -41,7 +56,8 @@ pub use ModType::BotModule; #[derive(Clone)] pub struct Chat { - pub ratelimiters : HashMap, // used to limit messages sent per channel + // pub ratelimiters : HashMap, // used to limit messages sent per channel + pub ratelimiters : Arc>>, // used to limit messages sent per channel pub client : TwitchIRCClient,StaticLoginCredentials>, } @@ -51,19 +67,21 @@ impl Chat { pub fn init(ratelimiters:HashMap, client:TwitchIRCClient, StaticLoginCredentials>) -> Chat { Chat{ - ratelimiters : ratelimiters, + ratelimiters : Arc::new(Mutex::new(ratelimiters)), client : client, } } - pub fn init_channel(&mut self, chnl:ChType) -> () { + // pub fn init_channel(&mut self, chnl:ChType) -> () { + pub async fn init_channel(&mut self, chnl:ChType) -> () { let n = RateLimiter::new(); - self.ratelimiters.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(&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 @@ -76,7 +94,12 @@ impl Chat { // self.client.say_in_reply_to(msg,outmsg).await.unwrap(); // // let contextratelimiter = ratelimiters.get_mut(&msg.channel_login).expect("ERROR: Issue with Rate limiters"); - let contextratelimiter = self.ratelimiters + let a = Arc::clone(&self.ratelimiters); + let mut a = a.lock().await; + + // let contextratelimiter = self.ratelimiters + let contextratelimiter = a + // .get_mut() .get_mut(&Channel(String::from(&msg.channel_login))) .expect("ERROR: Issue with Rate limiters"); // let contextratelimiter = self.ratelimiters.get(&msg.channel_login).expect("ERROR: Issue with Rate limiters"); @@ -140,7 +163,7 @@ impl Chat { #[derive(Clone)] pub struct BotManagers { // pub botmodules : ModulesManager, - pub identity : IdentityManager, + pub identity : Arc>, pub chat : Chat, } @@ -148,29 +171,49 @@ impl BotManagers { pub fn init(ratelimiters:HashMap, client:TwitchIRCClient, StaticLoginCredentials>) - -> BotManagers { - BotManagers { + -> Arc> { + let a = Arc::new(Mutex::new(BotManagers { // botmodules : ModulesManager::init(), - identity : IdentityManager::init(), + identity : Arc::new(Mutex::new(IdentityManager::init())), chat : Chat::init(ratelimiters,client), - } - + })); + a + + } + pub fn rIdentity(self) -> Arc> { + self.identity + } + pub fn rChat(&self) -> Arc> { + Arc::new(Mutex::new(self.chat)) } } + +pub struct ArcBox(pub Arc>); + +impl ArcBox{ + pub fn inst(&self) -> &Mutex { + &self.0 + } + +} + +//#[derive(Clone)] +// #[derive(Copy)] // <-- Cannot be derived pub struct BotInstance { - prefix : char, - bot_channel : ChType, + pub prefix : char, + pub bot_channel : ChType, pub incoming_messages : UnboundedReceiver, + // pub incoming_messages : RefCell>, // pub chat : Chat, - pub botmodules : ModulesManager, - twitch_oauth : String, + pub botmodules : Arc>, + pub twitch_oauth : String, pub bot_channels : Vec, // pub identity : IdentityManager, - pub botmgrs : BotManagers, + pub botmgrs : Arc>, } @@ -179,7 +222,8 @@ impl BotInstance { - pub fn init() -> BotInstance + // pub fn init() -> BotInstance + pub fn init() -> Arc { dotenv().ok(); @@ -242,19 +286,113 @@ impl BotInstance }; - println!("{:?}",b.botmgrs.chat.ratelimiters); + //println!("{:?}",b.botmgrs.chat.ratelimiters); - b + Arc::new(b) } - pub async fn runner(mut self) -> () { + // async fn rcv_helper(self) -> Option { + // // self.incoming_messages.get_mut().recv().await + // let mut a = self.incoming_messages; + // a.get_mut().recv().await + // } + + // pub async fn runner(mut self) -> () { + pub async fn runner(mut self) -> () { + + + // let mut boxed_bot = Arc::new(RefCell::new(self)); // <-- [ERROR] Future cannot be handled safely + let join_handle = tokio::spawn(async move { - while let Some(message) = &self.incoming_messages.recv().await { - // Below can be used to debug if I want to capture all messages + // let boxed_bot = Arc::new(Mutex::new(self)); + // let mut boxed_bot = Arc::new(self); + // let bot = Rc::new(RefCell::new(self)); + // let mut bot = Rc::new(RefCell::new(&self)); + //let bot = Arc::new(Mutex::new(&self)); + // let mut boxed_bot = Arc::new(RefCell::new(self)); + let mut boxed_bot = Arc::new(Mutex::new(self)); + + // while let Some(message) = bot.borrow_mut().incoming_messages.recv().await { + + // let bot = Arc::clone(&botinit); + + // while let Some(message) = bot.lock().unwrap().incoming_messages.recv().await { + //let b = Arc::clone(&bot); + + // let mut bot = RefCell::new(&self); + + // let mut bota = bot.clone().borrow(); + + // let boxed_bot = Rc::new(RefCell::new(self)); + // let boxed_bot = Rc::new(self); + // let boxed_bot = Pin::new(Rc::new(self)); + //let mut boxed_bot = Rc::new(RefCell::new(self)); + // let mut a = (*boxed_bot).clone().into_inner(); + // let mut a = Rc::clone(&boxed_bot).borrow_mut(); + //let mut a = Rc::>>::Borrow(Rc::clone(&boxed_bot)); + + + // while let Some(message) = Rc::clone(&boxed_bot).into_inner().incoming_messages.recv().await { + // while let Some(message) = Rc::::borrow(Rc::::as_ref(boxed_bot)) { + + // let a = boxed_bot.borrow(); + + // let boxed_bota = boxed_bot.borrow_mut(); + + // let a = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner(); + + // let boxed_bot = RefCell::new(Rc::new(self)); + //let boxed_bot = Rc::new(RefCell::new(self)); + // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await; + + // let a:Borrowed = boxed_bot.borrow(); + // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await { + // while let Some(message) = RefCell::new(self).borrow_mut().incoming_messages.recv().await { + // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await { + // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().rcv_helper().await { + // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { + // let mut a = Arc::try_unwrap(boxed_bot.clone()) + // .ok().unwrap() + // .into_inner() + // .ok().unwrap(); + // let a = Arc::clone(&boxed_bot).into_inner().unwrap().incoming_messages; + // .into_inner() + // .try_into(). + // .ok().unwrap(); + // while let Some(message) = a.lock().unwrap().incoming_messages.recv().await { + // while let Some(message) = a.recv().await { + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // let mut a = Arc::try_unwrap(boxed_bot.clone()) + // .ok() + // .unwrap(); + // .into_inner() + // .get_mut() + // .ok(); + // .unwrap(); + //let mut a = a.lock().unwrap(); + // let a = *a; + // while let Some(message) = a.lock().ok().unwrap().incoming_messages.recv().await { + // while let Some(message) = a.get_mut().expect("Error").incoming_messages.recv().await { + //let tempbot = boxed_bot.clone(); + // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().ok().unwrap().incoming_messages.recv().await { + // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().incoming_messages.recv().await { + // while let Some(message) = boxed_bot.to_owned().incoming_messages.recv().await { + // while let Some(message) = self.incoming_messages.recv().await { + // let a:Arc> = Arc::clone(&boxed_bot); + // while let Some(message) = a.incoming_messages.recv().await { + // let a = Arc::clone(&boxed_bot).into_inner(); + // while let Some(message) = a.incoming_messages.recv().await { + let tempbot = boxed_bot.clone(); + while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { + // while let Some(message) = tempbot.into_inner().incoming_messages.recv().await { + //while let Some(message) = boxed_bot.borrow().incoming_messages.recv().await { + // // Below can be used to debug if I want to capture all messages // println!("Received message: {:?}", message); + + // let boxed_bot = Arc::new(self); match message { ServerMessage::Notice(msg) => { @@ -272,7 +410,35 @@ impl BotInstance println!("Privmsg section"); // b.listener_main_prvmsg(&msg); - self.listener_main_prvmsg(&msg).await; + // self.listener_main_prvmsg(&msg).await; + // bot.into_inner().listener_main_prvmsg(&msg).await; + //let bot = Rc::>::clone(&bot); + + // bot.borrow().listener_main_prvmsg(&msg).await; + // let mut a = Rc::Clone(&bot); + // a.borrow_mut().listener_main_prvmsg(&msg).await; + // bot.borrow_mut().into_inner().listener_main_prvmsg(&msg).await; + // bot.listener_main_prvmsg(&msg).await; + // bot.lock().unwrap().listener_main_prvmsg(&msg).await; + // bot.borrow_mut().listener_main_prvmsg(&msg).await; + // Rc::clone(&boxed_bot).into_inner().listener_main_prvmsg(&msg).await; + // boxed_bot.borrow().listener_main_prvmsg(&msg).await; + // let bottemp = boxed_bot.borrow_mut(); + // let a = **bottemp; + // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await; + // Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await; + // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().ok().unwrap().listener_main_prvmsg(&msg).await; + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // let mut a = a.lock().unwrap(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // a.listener_main_prvmsg(&msg).await; + + // (*a).listener_main_prvmsg(&msg).await; + // let a:Arc> = Arc::clone(&boxed_bot); + // a.into_inner().listener_main_prvmsg(&msg).await; + let tempbot = boxed_bot.clone(); + Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await ; + // - BotCommand listener should likely need to be called within the above @@ -296,24 +462,103 @@ impl BotInstance join_handle.await.unwrap(); + + } + + pub fn get_botmodules(self) -> Arc> { + // let a = self.botmodules; + // Arc::clone(&Arc::new(Mutex::new(self.botmodules))) + self.botmodules + + } + + pub fn get_botactions(&self) -> &HashMap> { + self.get_botactions() + } + + pub async fn get_botmgrs(self) -> Arc> { + // Arc::new(self.botmgrs) + // Arc::clone(&Arc::new(Mutex::new(self.botmgrs))) + let a = self.botmgrs; + // let a = *a.lock().await; + // let a = a.rIdentity(); + a + } + + pub async fn get_identity(self) -> Arc> { + // let a = self.botmgrs; + // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) + // let a = self.botmgrs; + // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) + let a = self.get_botmgrs().await; + let a = a.lock().await; + // let a = a.rIdentity(); + let a = a.clone().identity; + a.clone() + } + + pub fn get_prefix(&self) -> String { + self.prefix.to_string() + } + // ----------------- // PRIVATE FUNCTIONS // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - async fn listener_main_prvmsg(&self,msg:&PrivmsgMessage) -> () { + async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { // 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) - for (_m,acts) in &self.botmodules.botactions { + // let botmgr = Rc::new(&self.botmgrs); + + // let mut boxedbot = Rc::new(RefCell::new(self)); + // let boxed_bot = Rc::new(RefCell::new(self)); + // let boxed_bot = Arc::new(Mutex::new(self)); + // let boxed_bot = Arc::new(self); + //let boxed_bot = Arc::clone(self); + // let mut boxed_bot = Arc::new(RefCell::new(self)); + // let mut boxed_bot = Arc::new(RwLock::new(self)); + // let boxed_bot = Arc::new(RwLock::new(self)); + // let boxed_bot = Arc::new(Mutex::new(self)); + let boxed_bot = Arc::new(Mutex::new(self)); + + + // for (_m,acts) in &self.botmodules.botactions { + // for (_m,acts) in &self.botmodules.botactions { + // for (_m,acts) in bot.into_inner().botmodules.botactions { + // let mut bot = Rc::clone(&bot); + // for (_m,acts) in bot.into_inner().botmodules.botactions { + // for (_m,acts) in bot.into_inner().botmodules.botactions { + // for (_m,acts) in Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions { + // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().botmodules.botactions { + // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().botmodules.botactions { + // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions { + // let a = Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmodules.botactions + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // let b = a.read().unwrap(); + // for (_m,acts) in a.read().unwrap().botmodules.botactions { + // for (_m,acts) in b.rbotmodules().botactions { + // for (_m,acts) in b.rbotactions() { + // for (_m,acts) in (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).rbotactions() { + // let a = boxed_bot.clone().into_inner(); + let a = boxed_bot.lock().await; + //let a = a.lock().in + // for (_m,acts) in self.rbotactions() { + // for (_m,acts) in a.read().ok().unwrap().rbotactions() { + // for (_m,acts) in a.into_inner().ok().unwrap().rbotactions() { + for (_m,acts) in a.get_botactions() { + for a in acts { - match a { + + + let _act = match a { crate::core::botmodules::BotAction::C(c) => { /* @@ -340,13 +585,43 @@ impl BotInstance // [x] prefix + command let mut confirmed_bot_command = false; - if inpt == self.prefix.to_string() + c.command.as_str() { + + // if inpt == self.prefix.to_string() + c.command.as_str() { + // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + c.command.as_str() { + // let a = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()); + // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).prefix.to_string(); + // let a = self.prefix.to_string(); + // let a = boxed_bot.clone(); + + // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() { + // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() + let a = boxed_bot.lock().await; + // + // if inpt == a.into_inner().prefix.to_string() + c.command.as_str() { + if inpt == a.get_prefix() + c.command.as_str() { confirmed_bot_command = true; } // [x] prefix + alias for alias in &c.alias { - if inpt == self.prefix.to_string() + alias.as_str() { + // if inpt == self.prefix.to_string() + alias.as_str() { + // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + alias.as_str() { + // + // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string() + alias.as_str() { + // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner() + // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string() + alias.as_str() { + // if inpt == Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().prefix.to_string() + alias.as_str() { + // if inpt == self.prefix.to_string() + alias.as_str() { + // let a = boxed_bot.clone(); + let a = boxed_bot.lock().await; + // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + alias.as_str() { + // if inpt == a.into_inner().prefix.to_string() + alias.as_str() { + if inpt == a.get_prefix() + alias.as_str() { confirmed_bot_command = true; } } @@ -364,24 +639,80 @@ impl BotInstance // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + + // let botref = Rc::clone(&botmgr); + // if let Rc(botmgr) = botref { + // () + // } + + // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match boxed_bot.clone().into_inner().botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + //let boxed_bot1 = Arc::clone(&boxed_bot); + //let a = boxed_bot1.into_inner().ok().unwrap(); + // match boxed_bot1.into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match Arc::try_unwrap(boxed_bot.clone()) + // .ok() + // .unwrap().into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner(); + // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); + // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner() + // match a.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match (boxed_bot.clone().into_inner().ok().unwrap()).botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // let a = boxed_bot.clone(); + // let a = boxed_bot.lock().await; + // // let a = a.read().ok().unwrap().botmgrs.identity; + // let a = a.get_identity(); + // // let a = a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()) ; + + // match a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await { + + { + let le = boxed_bot.lock().await; + // let le = le.lock().await; + let le = le.get_identity().await; + let le = *le; + let le = le.lock().await; + let le = le.clone(); + let le = le.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + match le { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); - c.execute(self.botmgrs.clone(), msg.clone()).await; + // c.execute(bot, msg.clone()).await; + // if let bot = Rc::>::clone(*bot) { + // c.execute(bot, msg.clone()).await; + // } + // let boxed_bot = Arc::new(RwLock::new(self)); + c.execute(boxed_bot.clone(), msg.clone()).await; + } - Permissible::Block => println!("User Not allowed to run command"), + Permissible::Block => { + println!("User Not allowed to run command") + }, // _ => (), - } + }; // c.execute(self.chat.clone(), msg.clone()).await; + } } }, - crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.clone(), msg.clone()).await, + crate::core::botmodules::BotAction::L(l) => { + // if let bot = Rc::clone(&bot) { + // l.into_inner().execute(bot, msg.clone()).await + // } + //let bot = Rc::clone(&bot).into_inner(); + // l.execute(boxed_bot.clone(), msg.clone()).await + // let boxed_bot = Arc::new(RwLock::new(self)); + l.execute(boxed_bot.clone(), msg.clone()).await; + }, _ => (), - } + }; } }; diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index ab52696..a05db7d 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -5,6 +5,18 @@ use std::collections::HashMap; use crate::core::identity; +use std::cell::RefCell; +use std::sync::{Arc, RwLock}; + +use std::future::Future; +use futures::lock::Mutex; + + + +use crate::core::botinstance::{self, BotInstance}; +use std::rc::Rc; + +use async_trait::async_trait; /* @@ -43,8 +55,6 @@ pub enum ChType { pub use ChType::Channel; use twitch_irc::message::PrivmsgMessage; -use crate::core::botinstance::{self, BotInstance}; - #[derive(Debug)] enum StatusLvl { @@ -57,7 +67,8 @@ pub enum ModStatusType { Enabled(StatusLvl), Disabled(StatusLvl), } - + +// #[derive(Clone)] pub enum BotAction { C(BotCommand), @@ -66,7 +77,8 @@ pub enum BotAction } impl BotAction { - pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ match self { BotAction::L(a) => a.execute(m,n).await, @@ -77,13 +89,14 @@ impl BotAction { } } +#[async_trait] pub trait BotActionTrait { - fn add_to_bot(self, bot:BotInstance); - fn add_to_modmgr(self,modmgr:&mut ModulesManager); + 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 @@ -96,20 +109,26 @@ pub struct BotCommand { impl BotCommand { - pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + // pub async fn execute(&self,m:Rc<&botinstance::BotManagers>,n:PrivmsgMessage){ + pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ (self.exec_body)(m,n).await; } } - +#[async_trait] impl BotActionTrait for BotCommand { - fn add_to_bot(self, mut bot:BotInstance) { - let mgr = &mut bot.botmodules; - self.add_to_modmgr(mgr); + async fn add_to_bot(&self, mut bot:BotInstance) { + // let mgr = &mut bot.botmodules; + // let mut mgr = *mgr.lock().await; + // let mut mgr = &mut mgr; + self.add_to_modmgr(bot.botmodules); } - fn add_to_modmgr(self, modmgr:&mut ModulesManager) { + async fn add_to_modmgr(self, modmgr:Arc>) { + // modmgr.add_botaction(self.module.clone(), BotAction::C(self)) + let modmgr = *modmgr.lock().await; modmgr.add_botaction(self.module.clone(), BotAction::C(self)) } @@ -125,18 +144,53 @@ pub mod bot_actions { use std::boxed::Box; use std::pin::Pin; - use crate::core::botinstance::{BotManagers, Chat}; + use std::rc::Rc; + + use crate::core::botinstance::{BotInstance, BotManagers, Chat}; use twitch_irc::message::PrivmsgMessage; + use std::cell::RefCell; + use std::sync::{Arc, RwLock}; + use futures::lock::Mutex; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; //pub type ExecBody = Box Pin + Send>> + Send + Sync>; - pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + + //pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody // pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody - pub fn asyncbox(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Rc<&BotManagers>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc<&BotInstance>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody where - T: Future + Send + 'static, + //T: Future + Send + 'static + T: Future + Send + 'static { Box::new(move |a,b| Box::pin(f(a,b))) } @@ -157,21 +211,24 @@ pub struct Listener impl Listener { - pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ (self.exec_body)(m,n).await; } } +#[async_trait] impl BotActionTrait for Listener { - fn add_to_bot(self, mut bot:BotInstance) { - - let mgr = &mut bot.botmodules; + async fn add_to_bot(&self, mut bot:BotInstance) { + // let mgr = &mut bot.botmodules; + let mgr = bot.botmodules; self.add_to_modmgr(mgr); } - fn add_to_modmgr(self, modmgr:&mut ModulesManager) { + // fn add_to_modmgr(self, modmgr:&mut ModulesManager) { + async fn add_to_modmgr(self, modmgr:Arc>) { + let modmgr = *modmgr.lock().await; modmgr.add_botaction(self.module.clone(), BotAction::L(self)) } @@ -182,6 +239,8 @@ impl BotActionTrait for Listener #[derive(Debug)] struct Routine {} +// #[derive(Clone)] + pub struct ModulesManager { statusdb: HashMap>, @@ -191,7 +250,7 @@ pub struct ModulesManager impl ModulesManager { - pub fn init() -> ModulesManager + pub fn init() -> Arc> { @@ -203,19 +262,31 @@ impl ModulesManager botactions : act, }; - // initialize core modules - crate::core::identity::init(&mut mgr); + // :: [x] initialize core modules + // crate::core::identity::init(&mut mgr); + + let a = Arc::new(Mutex::new(mgr)); + // let a = a.clone(); + crate::core::identity::init(a.clone()); // initialize custom crate modules - crate::modules::init(&mut mgr); + // crate::modules::init(&mut mgr); + // let a = a.clone(); + crate::modules::init(a.clone()); println!(">> Modules Manager : End of Init"); - mgr + // mgr + a } + pub fn rbotactions(self) -> HashMap> { + self.botactions + } + + pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { // Example usage : botmanager.modstatus( // BotModule("GambaCore"), diff --git a/src/core/identity.rs b/src/core/identity.rs index a6c6337..224aa20 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1,21 +1,32 @@ +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::botinstance::{self}; +use crate::core::botinstance::{self,BotInstance}; +use futures::lock::Mutex; use twitch_irc::message::{Badge, PrivmsgMessage}; use crate::core::botmodules::ChType; +use crate::core::botinstance::ArcBox; + + +use std::rc::Rc; +use std::cell::RefCell; + +use std::sync::{Arc, RwLock}; + fn adminvector() -> Vec { vec![String::from("ModulatingForce")] } -pub fn init(mgr:&mut ModulesManager) +// pub fn init(mgr:&mut ModulesManager) +pub fn init(mgr:Arc>) { BotCommand { @@ -32,7 +43,8 @@ pub fn init(mgr:&mut ModulesManager) ], }.add_to_modmgr(mgr); - async fn cmd_promote(bot:botinstance::BotManagers,msg:PrivmsgMessage) { + async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) + { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); @@ -63,6 +75,8 @@ pub fn init(mgr:&mut ModulesManager) */ + //let bot = Rcbot; + println!("{}",msg.message_text); let mut argv = msg.message_text.split(" "); @@ -84,21 +98,104 @@ pub fn init(mgr:&mut ModulesManager) match arg1 { - Some(a) if a == String::from("admin") => { + Some(a1) if a1 == String::from("admin") => { // - BotAdmins can promote admin to give BotAdmin UserRole - let a = bot.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + //let mut bot = Rc::clone(&bot); + // let a = bot.botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + // let a = Rc::try_unwrap(bot).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + // let a = Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + + // let a = Rc::try_unwrap(bot).ok().unwrap() + // // .borrow_mut() + // .into_inner() + // .botmgrs + // .identity + // .getspecialuserroles(msg.sender.name.to_lowercase(), + // Some(ChType::Channel(msg.channel_login.to_lowercase()))); + // let p = Rc::try_unwrap(bot.clone()) + // let p = Arc::try_unwrap(bot.clone()) + // .ok() + // .unwrap() + // //.into_inner() + // //.to_owned() + // // .get_mut() + // .into_inner(); + // // .ok() + // // .unwrap(); + // // let p = p.ok().unwrap(); + + // let p = bot.lock().await.get_identity(); + // let p = p.lock().await; + // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + // // let ta = *ta.await; + // let ta = *ta.lock().await; + + // if let Some(a) = ta { + + + let p = bot.lock().await.get_identity(); + let mut p = p.lock().await; + let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + + if let Some(a) = ta { - if let Some(a) = a { if a.contains(&UserRole::BotAdmin) { println!("BotAdmin allowed to promote admin"); - match bot.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // Success(_) => { - // ; - // }, - ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), - ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), - ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + // let bota = Rc::clone(&bot); + // let bota = Rc::get_mut(&bota); + // match bota.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + //let mut bot = Rc::clone(&bot); + // let bot = Rc::<&botinstance::BotInstance>::get_mut(&mut bot); + // let mut bot = Rc::make_mut(&mut bot); + // let mut bot = Rc::make_mut(&bot); + // match Rc::<&botinstance::BotInstance>::get_mut(bot) { + // Some(bot) => { + // match bot.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // // Success(_) => { + // // ; + // // }, + // ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), + // ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), + // ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + + // } + // }, + // None => (), + // } + //let bot = Rc::::make_mut(bot); + // match Rc::::make_mut(&mut Rc::new(bot.botmgrs.identity)).promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // match Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().ok().unwrap().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // match bot.read().ok().unwrap().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // let a = bot.get_mut(); + // match a.get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // let a = (*bot).clone(); + { + // let a = bot.lock().await.get_botmgrs().clone(); + // let a = bot.lock().await; + // let mut mutex = Arc::clone(&bot); + // match mutex.get_mut().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { + // slet ee = ArcBox(bot); + // println!("tester: {:?}",(*bot).lock().await.get_prefix()); + // let mutex = Arc::clone(&bot); + // let mut mutex2 = Arc::new(*mutex).into_inner().get_identity(); + // let mut mutex2 = Arc::clone(&mutex).into_inner().get_identity(); + // let a = (*bot).lock().await.get_identity(); + // let mut a = a.lock().await; + let p = bot.lock().await.get_identity(); + let mut p = p.lock().await; + let ta = p.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + match ta { + // Success(_) => { + // ; + // }, + ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), + ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), + ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + + } } } } @@ -151,7 +248,7 @@ pub fn init(mgr:&mut ModulesManager) }.add_to_modmgr(mgr); - async fn cmd_demote(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) { + async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { println!("Called cmd demote"); } @@ -172,7 +269,7 @@ pub fn init(mgr:&mut ModulesManager) }.add_to_modmgr(mgr); - async fn getroles(bot:botinstance::BotManagers,msg:PrivmsgMessage) { + async fn getroles(bot:Arc>,msg:PrivmsgMessage) { println!("Called cmd getroles"); /* @@ -224,17 +321,57 @@ pub fn init(mgr:&mut ModulesManager) let targetchnl = arg2; - match targetchnl { + // // let a = bot.read().ok().unwrap().get_identity(); + // let a = bot.lock().await; + // // let a = a.lock().await; + // // let a = a.get_identity().await; + // let a = a.botmgrs; + // // let a = *(*a).lock().await; + // let a = *a.lock().await; + // let a = a.identity; + // let a = *a.lock().await; + + // let a = bot.clone(); + // let a = a.into_inner(); + // let a = a.botmgrs; + // let a = a.into_inner(); + // let a = a.identity; + // let a = a.into_inner(); + let a = bot.clone(); + let a = a.lock().await; + let a = a.get_identity().await; + // let a = a.lock().await; + let sproles = match targetchnl { None => { - let a = bot.identity.getspecialuserroles(String::from(targetuser),None); - println!("Retrieved User Roles >> {:?}",a); + // let bot = Rc::clone(&bot); + //let bot = Arc::clone(&bot); + // let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser),None); + // let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap(); + // let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner(); + // let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser),None); + // let a = a.ok().getspecialuserroles(String::from(targetuser),None); + // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); + // println!("Retrieved User Roles >> {:?}",a); + a.lock().await.getspecialuserroles(String::from(targetuser),None).await }, Some(targetchnl) => { - let a = bot.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl)))); - println!("Retrieved User Roles >> {:?}",a); - }, - } + // let bot = Rc::clone(&bot); + // let bot = Arc::clone(&bot); + // let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl)))); + // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner() + // let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap(); + // let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner(); + // let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl)))); + // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); + // println!("Retrieved User Roles >> {:?}",a); + // bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None) + a.lock().await.getspecialuserroles(String::from(targetuser),None).await + }, + }; + + + println!("Retrieved User Roles >> {:?}",sproles); // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot")))); // println!("{:?}",a); @@ -271,7 +408,8 @@ pub enum Permissible { #[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 : 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 // parent_mgr : Box, //parent_mgr : Option>, } @@ -298,7 +436,7 @@ impl IdentityManager { }; IdentityManager { - special_roles_users : a, + special_roles_users : Arc::new(Mutex::new(a)), //parent_mgr : None, } } @@ -306,7 +444,8 @@ impl IdentityManager { // [ ] 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) -> Permissible + // 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 { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -331,11 +470,28 @@ impl IdentityManager { // ChType::Channel(msg.channel_login.to_owned()), // sender_badge, // cmdreqroles - 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; + self.can_user_run(msg.sender.name.to_owned(), + ChType::Channel(msg.channel_login.to_owned()), + sender_badge, + cmdreqroles + ) ; } @@ -344,7 +500,7 @@ impl IdentityManager { Permissible::Block } - pub fn can_user_run(mut self, + pub async fn can_user_run(&self, usr:String, channelname:ChType, chat_badge:ChatBadge, @@ -424,7 +580,8 @@ impl IdentityManager { // 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()) { + // match self.special_roles_users.get(&usr.to_lowercase()) { + match self.special_roles_users.lock().await.get(&usr.to_lowercase()) { Some(usrroles) => { // println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); // println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); @@ -437,6 +594,7 @@ impl IdentityManager { // usrroles.push(UserRole::Mod(channelname.clone())); // a.push(UserRole::Mod(channelname.clone())); self.special_roles_users + .lock().await .get_mut(&usr.to_lowercase()) .expect("ERROR") .push(UserRole::Mod(channelname.clone())); @@ -463,7 +621,7 @@ impl IdentityManager { println!("Mod Role required"); - if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) { + if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { if a.contains(&UserRole::Mod(channelname.clone())) || a.contains(&UserRole::SupMod(channelname.clone())){ // return Ok(Permissible::Allow); return Permissible::Allow @@ -476,7 +634,7 @@ impl IdentityManager { if cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { - if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) { + if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { if a.contains(&UserRole::SupMod(channelname.clone())) { // return Ok(Permissible::Allow); return Permissible::Allow @@ -490,8 +648,8 @@ impl IdentityManager { println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); if cmdreqroles.contains(&UserRole::BotAdmin) { - println!("special roles get : {:?}",self.special_roles_users.get(&usr.to_lowercase())); - if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) { + println!("special roles get : {:?}",self.special_roles_users.lock().await.get(&usr.to_lowercase())); + if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { println!("special roles contains BotAdmin: {}",a.contains(&UserRole::BotAdmin)); if a.contains(&UserRole::BotAdmin) { // return Ok(Permissible::Allow); @@ -503,20 +661,31 @@ impl IdentityManager { Permissible::Block } - pub fn promote(mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { + pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { // Note : If channel is none, getspecialuserroles() returns all roles for the user // let chatterroles = self.getspecialuserroles(trgchatter, channel); - let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()); + // let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()); + // let chatterroles = *self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + // let chatterroles = chatterroles.lock().await; + // // let chatterroles = *chatterroles; + // let chatterroles = chatterroles.unwrap(); - let emptyvec = vec![]; - let chatterroles = match chatterroles { - Some(a) => a, - _ => &(emptyvec), - }; + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + // let chatterroles = chatterroles.lock().await; + // let chatterroles = *chatterroles; + let chatterroles = chatterroles.unwrap(); + + + // let emptyvec = vec![]; + + // let chatterroles = match chatterroles { + // Some(a) => a, + // _ => &(emptyvec), + // }; match trg_role { @@ -528,6 +697,7 @@ impl IdentityManager { // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); self.special_roles_users + .lock().await .get_mut(&trgchatter) .expect("Error getting roles") .push(UserRole::Mod(trg_chnl)); @@ -615,7 +785,7 @@ impl IdentityManager { ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option<&Vec> { + pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option> { // let a = chattername.to_lowercase(); @@ -637,7 +807,21 @@ impl IdentityManager { // println!("{a}"); - self.special_roles_users.get(&a) + // let b = self.special_roles_users.lock().await.get(&a); + // match b + // { + // Some(b) => Some(*b), + // None => None, + // } + + let b = self.special_roles_users.lock().await.remove(&a); + let outp = b; + // let b = Arc::new(Mutex::new(outp)); + outp + + + // let b = Arc::new(Mutex::new(b)); + // b diff --git a/src/main.rs b/src/main.rs index cd71f0f..3ef7654 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ pub mod core; pub mod modules; use std::process::Output; +use crate::core::botinstance::ArcBox; + use crate::core::botinstance::BotInstance; #[tokio::main] @@ -11,6 +13,8 @@ pub async fn main() { let bot = BotInstance::init(); - bot.runner().await; + bot.clone().runner().await; + + println!("ERROR : EXIT Game loop"); } \ No newline at end of file diff --git a/src/modules.rs b/src/modules.rs index 5fbaa8a..13e39ae 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -10,7 +10,8 @@ pub use crate::core::botmodules::ModulesManager; // use crate::core::botinstance; pub use crate::core::botinstance::BotInstance; - +use std::sync::Arc; +use futures::lock::Mutex; // [ ] Load submodules @@ -25,7 +26,8 @@ mod experiments; // // F: std::future::Future + Send, // // F : Send, // F : Send + ?Sized, -pub fn init(mgr:&mut ModulesManager) +// pub fn init(mgr:&mut ModulesManager) +pub fn init(mgr:Arc>) { // Modules initializer loads modules into the bot // this is achieved by calling submodules that also have fn init() defined diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 0c3709b..828d9f2 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -17,7 +17,8 @@ use std::future::Future; use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType}; use crate::core::botmodules::bot_actions::actions_util; -use crate::core::botinstance::{self}; +use crate::core::botinstance::{self,BotInstance}; +use futures::lock::Mutex; use twitch_irc::message::PrivmsgMessage; use crate::core::identity; @@ -25,8 +26,13 @@ use crate::core::identity; use rand::Rng; +use std::rc::Rc; -pub fn init(mgr:&mut ModulesManager) +use std::sync::{Arc, RwLock}; + + +// pub fn init(mgr:&mut ModulesManager) +pub fn init(mgr:Arc>) { @@ -69,7 +75,7 @@ pub fn init(mgr:&mut ModulesManager) } -async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage) +async fn good_girl(mut bot:Arc>,msg:PrivmsgMessage) { println!("In GoodGirl() Listener"); //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -82,6 +88,13 @@ async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage) // let roll = rand::thread_rng().gen_range(1..=5); + // let mut bot = Rc::clone(&bot); + // let mut bot = Rc::get_mut(&mut bot); + // let bot = match bot { + // Some(bot) => bot, + // None => (), + // } + if msg.sender.name == "ModulatingForce" // && msg.message_text.contains("GoodGirl") @@ -92,17 +105,42 @@ async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage) let rollwin = rand::thread_rng().gen_ratio(1,5); if rollwin { println!("In GoodGirl() > Win"); - bot.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; + // let bot = Rc::get_mut(&bot).expect("Error"); + // bot.botmgrs.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; + // Rc::::get_mut(mut bot) + // if let Some(bot) = Rc::<&botinstance::BotInstance>::get_mut(bot) { + + // match bot{ + // Some(bot) => { + // bot + // .botmgrs + // .chat + // .say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; + // } + // None => (), + // } + // Arc::try_unwrap(bot).ok().unwrap().botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + let a = bot.clone(); + // let a = a.read().ok().unwrap(); + // let a = a.lock().await.get_botmgrs(); + // let a = a.lock().await.rChat(); + + let a = (*bot).lock().await.get_botmgrs(); + let a = a.lock().await.rChat(); + let mut a = (*a).lock().await; + + // a.rbotmgrs().chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + // a.lock().await.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + a.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; } - + + } - - - - + } -async fn testy(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) + +async fn testy(mut _chat:Arc>,_msg:PrivmsgMessage) { println!("testy triggered!") -- 2.46.1 From 2a7b53ddf892ae691cca17d84a3e319cc632cdc9 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:25:12 -0500 Subject: [PATCH 18/39] 2024.02.12 - WORKS --- src/core/botinstance.rs | 292 +++++++++++++++++++++++++++++-------- src/core/botmodules.rs | 169 +++++++++++++++------ src/core/identity.rs | 67 ++++++--- src/main.rs | 5 +- src/modules.rs | 2 +- src/modules/experiments.rs | 30 ++-- 6 files changed, 422 insertions(+), 143 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 5f9561d..090b0d5 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -1,6 +1,7 @@ -use futures::lock::Mutex; +// 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; @@ -20,6 +21,9 @@ use std::collections::HashMap; use rand::Rng; +// Important to use tokios Mutex here since std Mutex doesn't work with async functions +use tokio::sync::Mutex; + use crate::core::ratelimiter::RateLimiter; @@ -31,7 +35,7 @@ use crate::core::identity::{IdentityManager,Permissible}; use std::rc::Rc; use std::cell::RefCell; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; // use futures::lock::Mutex; use std::pin::Pin; @@ -39,6 +43,9 @@ use std::pin::Pin; //use std::borrow::Borrow; use core::borrow::Borrow; +// pub type BotAR = Arc>; +use super::botmodules::bot_actions::actions_util::BotAR; + #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { @@ -48,11 +55,14 @@ pub enum ChType { pub use ChType::Channel; -pub enum ModType { - BotModule(String), -} -pub use ModType::BotModule; + +// pub enum ModType { +// BotModule(String), +// } + +// pub use ModType::BotModule; + #[derive(Clone)] pub struct Chat { @@ -163,7 +173,7 @@ impl Chat { #[derive(Clone)] pub struct BotManagers { // pub botmodules : ModulesManager, - pub identity : Arc>, + pub identity : Arc>, pub chat : Chat, } @@ -171,23 +181,27 @@ impl BotManagers { pub fn init(ratelimiters:HashMap, client:TwitchIRCClient, StaticLoginCredentials>) - -> Arc> { - let a = Arc::new(Mutex::new(BotManagers { + -> BotManagers { + // let a = Arc::new(Mutex::new(BotManagers { + // // botmodules : ModulesManager::init(), + // identity : Arc::new(Mutex::new(IdentityManager::init())), + // chat : Chat::init(ratelimiters,client), + // })); + // a + BotManagers { // botmodules : ModulesManager::init(), - identity : Arc::new(Mutex::new(IdentityManager::init())), + identity : Arc::new(RwLock::new(IdentityManager::init())), chat : Chat::init(ratelimiters,client), - })); - a - + } } - pub fn rIdentity(self) -> Arc> { + pub fn rIdentity(self) -> Arc> { self.identity } - pub fn rChat(&self) -> Arc> { - Arc::new(Mutex::new(self.chat)) - } + // pub fn rChat(&self) -> Arc> { + // Arc::new(Mutex::new(self.chat)) + // } } @@ -206,14 +220,16 @@ pub struct BotInstance { pub prefix : char, pub bot_channel : ChType, - pub incoming_messages : UnboundedReceiver, + // pub incoming_messages : UnboundedReceiver, + pub incoming_messages : Arc>>, // pub incoming_messages : RefCell>, // pub chat : Chat, - pub botmodules : Arc>, + pub botmodules : Arc, pub twitch_oauth : String, pub bot_channels : Vec, // pub identity : IdentityManager, - pub botmgrs : Arc>, + // pub botmgrs : Arc>, + pub botmgrs : BotManagers, } @@ -223,7 +239,8 @@ impl BotInstance // pub fn init() -> BotInstance - pub fn init() -> Arc + // pub fn init() -> Arc + pub fn init() -> BotInstance { dotenv().ok(); @@ -272,7 +289,7 @@ impl BotInstance let b = BotInstance { prefix : prefix, bot_channel : Channel(login_name) , - incoming_messages : incoming_messages, + incoming_messages : Arc::new(RwLock::new(incoming_messages)), //client : client, // chat : Chat { // ratelimiters : ratelimiters, @@ -289,7 +306,9 @@ impl BotInstance //println!("{:?}",b.botmgrs.chat.ratelimiters); - Arc::new(b) + // Arc::new(b) + //Arc::new(RwLock::new(b)) + b } // async fn rcv_helper(self) -> Option { @@ -299,10 +318,14 @@ impl BotInstance // } // pub async fn runner(mut self) -> () { - pub async fn runner(mut self) -> () { + // pub async fn runner(&'static mut self) -> () { + pub async fn runner(self) -> () { + // let bot_am = Arc::new(Mutex::new(self)); // let mut boxed_bot = Arc::new(RefCell::new(self)); // <-- [ERROR] Future cannot be handled safely + + let bot = Arc::new(RwLock::new(self)); let join_handle = tokio::spawn(async move { @@ -313,7 +336,7 @@ impl BotInstance // let mut bot = Rc::new(RefCell::new(&self)); //let bot = Arc::new(Mutex::new(&self)); // let mut boxed_bot = Arc::new(RefCell::new(self)); - let mut boxed_bot = Arc::new(Mutex::new(self)); + // let mut boxed_bot = Arc::new(Mutex::new(self)); // while let Some(message) = bot.borrow_mut().incoming_messages.recv().await { @@ -385,8 +408,16 @@ impl BotInstance // while let Some(message) = a.incoming_messages.recv().await { // let a = Arc::clone(&boxed_bot).into_inner(); // while let Some(message) = a.incoming_messages.recv().await { - let tempbot = boxed_bot.clone(); - while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { + // let tempbot = boxed_bot.clone(); + // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { + + // let tempbot = Arc::clone(&boxed_bot); + + // while let Some(message) = tempbot.lock().await.incoming_messages.recv().await { + let a = bot.read().await; + let mut a = a.incoming_messages.write().await; + while let Some(message) = a.recv().await { + // while let Some(message) = tempbot.into_inner().incoming_messages.recv().await { //while let Some(message) = boxed_bot.borrow().incoming_messages.recv().await { // // Below can be used to debug if I want to capture all messages @@ -436,8 +467,28 @@ impl BotInstance // (*a).listener_main_prvmsg(&msg).await; // let a:Arc> = Arc::clone(&boxed_bot); // a.into_inner().listener_main_prvmsg(&msg).await; - let tempbot = boxed_bot.clone(); - Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await ; + // let tempbot = boxed_bot.clone(); + // Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await ; + + // let tempbot = Arc::clone(&tempbot); + // // let a = tempbot.lock().await; + // tempbot.lock().await.listener_main_prvmsg(&msg).await; + // self.listener_main_prvmsg(&msg).await; + // bot.read().await.listener_main_prvmsg(&msg).await; + + // let a = bot.read().await; + // a.listener_main_prvmsg(&msg).await; + // a.listener_main_prvmsg(&msg).await; + // let a = bot.read().await; + BotInstance::listener_main_prvmsg(Arc::clone(&bot), &msg).await; + // let a = bot.read().await; + // a.lis + + + + + + //self.listener_main_prvmsg(&msg).await; // - BotCommand listener should likely need to be called within the above @@ -468,18 +519,32 @@ impl BotInstance - pub fn get_botmodules(self) -> Arc> { + pub fn get_botmodules(self) -> Arc { // let a = self.botmodules; // Arc::clone(&Arc::new(Mutex::new(self.botmodules))) + // *self.botmodules self.botmodules } - pub fn get_botactions(&self) -> &HashMap> { - self.get_botactions() - } + // pub fn get_botactions(self:&Self) -> (Self,HashMap>) { + // // self.get_botactions() + // // (*self,(*self).botmodules.rbotactions()) + // (Self { bot_channel},(*self).botmodules.rbotactions()) + // } - pub async fn get_botmgrs(self) -> Arc> { + // pub fn get_botactions(&self) -> (Self,HashMap>) { + // pub fn get_botactions(&self) -> HashMap> { + // // self.get_botactions() + // // (*self,(*self).botmodules.rbotactions()) + // // (self,self.botmodules.rbotactions()) + // // (*self).botmodules.rbotactions() + // // let a = (*self).botmodules.rbotactions(); + // let a = + // a + // } + + pub async fn get_botmgrs(self) -> BotManagers { // Arc::new(self.botmgrs) // Arc::clone(&Arc::new(Mutex::new(self.botmgrs))) let a = self.botmgrs; @@ -488,29 +553,75 @@ impl BotInstance a } - pub async fn get_identity(self) -> Arc> { - // let a = self.botmgrs; - // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) - // let a = self.botmgrs; - // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) - let a = self.get_botmgrs().await; - let a = a.lock().await; - // let a = a.rIdentity(); - let a = a.clone().identity; - a.clone() + // pub fn get_identity(self:&Self) -> (Self,IdentityManager) { + pub fn get_identity(&self) -> Arc> { + // // let a = self.botmgrs; + // // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) + // // let a = self.botmgrs; + // // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) + // let a = self.get_botmgrs().await; + // let a = a.lock().await; + // // let a = a.rIdentity(); + // let a = a.clone().identity; + // a.clone() + // let id = (*self).botmgrs.identity; + // id + Arc::clone(&self.botmgrs.identity) } - pub fn get_prefix(&self) -> String { - self.prefix.to_string() + + // pub fn get_prefix(self) -> (Self,char) { + pub fn get_prefix(&self) -> char { + // self.prefix.to_string() + // let a = self.prefix; + // a.clone().to_string() + // (self,self.prefix) + + (*self).prefix } + // pub fn get_prefix(self:&Self) -> (Self,String) { + // (*self,(*self).prefix.to_string()) + // } + // pub fn get_prefix(self:Self) -> (Self,String) { + // let str1 = self.prefix.to_string(); + // (self,str1) + // } + + // pub fn get_prefix(&self) -> String { + // // self.prefix.to_string() + // let a = self.prefix; + // a.clone().to_string() + // } + + // pub fn get_prefix(self) -> (Self,String) { + // // self.prefix.to_string() + // // let a = self.prefix; + // // a.clone().to_string() + // (Self { + // prefix : self.prefix , + // bot_channel : self.bot_channel , + // incoming_messages : self.incoming_messages , + // botmodules : self.botmodules, + // twitch_oauth : self.twitch_oauth, + // bot_channels : self.bot_channels , + // // identity : IdentityManager::init(), + // botmgrs: self.botmgrs , + // }, + // self.prefix.to_string()) + // } + // ----------------- // PRIVATE FUNCTIONS // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { + // async fn listener_main_prvmsg(&mut self,msg:&PrivmsgMessage) -> () { + // async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { + // async fn listener_main_prvmsg(self:Arc,msg:&PrivmsgMessage) -> () { + pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { + // 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) @@ -526,7 +637,8 @@ impl BotInstance // let mut boxed_bot = Arc::new(RwLock::new(self)); // let boxed_bot = Arc::new(RwLock::new(self)); // let boxed_bot = Arc::new(Mutex::new(self)); - let boxed_bot = Arc::new(Mutex::new(self)); + //let boxed_bot = Arc::new(Mutex::new(self)); + // let bot = Arc::new(RwLock::new(self)); // for (_m,acts) in &self.botmodules.botactions { @@ -547,12 +659,27 @@ impl BotInstance // for (_m,acts) in b.rbotactions() { // for (_m,acts) in (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).rbotactions() { // let a = boxed_bot.clone().into_inner(); - let a = boxed_bot.lock().await; + // let a = boxed_bot.lock().await; //let a = a.lock().in // for (_m,acts) in self.rbotactions() { // for (_m,acts) in a.read().ok().unwrap().rbotactions() { // for (_m,acts) in a.into_inner().ok().unwrap().rbotactions() { - for (_m,acts) in a.get_botactions() { + + // let bot = self; + // let mut instr:char; + + // let hacts = self.get_botactions(); + // let hacts = boxed_bot.clone().lock().await.get_botactions(); + // let hacts = bot.read().await.get_botactions(); + let botlock = bot.read().await; + let hacts = botlock.botmodules.botactions.read().await; + // let hacts = hacts + for (_m,acts) in &(*hacts) { + + + + + // let bot = bot; for a in acts { @@ -600,10 +727,16 @@ impl BotInstance // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() { // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() - let a = boxed_bot.lock().await; + // let a = boxed_bot.lock().await; // // if inpt == a.into_inner().prefix.to_string() + c.command.as_str() { - if inpt == a.get_prefix() + c.command.as_str() { + // if inpt == a.get_prefix() + c.command.as_str() { + // if inpt == self.get_prefix() + c.command.as_str() { + // let instr = self.get_prefix(); + // let instr = boxed_bot.clone().lock().await.get_prefix(); + // let instr = bot.read().await.get_prefix(); + let instr = bot.read().await.get_prefix(); + if inpt == String::from(instr) + c.command.as_str() { confirmed_bot_command = true; } @@ -618,10 +751,16 @@ impl BotInstance // if inpt == Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().prefix.to_string() + alias.as_str() { // if inpt == self.prefix.to_string() + alias.as_str() { // let a = boxed_bot.clone(); - let a = boxed_bot.lock().await; + // let a = boxed_bot.lock().await; // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + alias.as_str() { // if inpt == a.into_inner().prefix.to_string() + alias.as_str() { - if inpt == a.get_prefix() + alias.as_str() { + // if inpt == a.get_prefix() + alias.as_str() { + // if inpt == self.get_prefix() + alias.as_str() { + // let instr = self.get_prefix(); + // let instr = boxed_bot.clone().lock().await.get_prefix(); + // let instr = bot.read().await.get_prefix(); + let instr = bot.read().await.get_prefix(); + if inpt == String::from(instr) + alias.as_str() { confirmed_bot_command = true; } } @@ -671,14 +810,27 @@ impl BotInstance // match a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await { { - let le = boxed_bot.lock().await; + // let le = boxed_bot.lock().await; + // // let le = le.lock().await; + // let le = le.get_identity().await; + // let le = *le; // let le = le.lock().await; - let le = le.get_identity().await; - let le = *le; - let le = le.lock().await; - let le = le.clone(); - let le = le.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; - match le { + // let le = le.clone(); + // let le = le.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + // let le = self.get_identity().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + // let le = self.botmgrs; + // let le = le.identity; + // let (bot,id) = self.get_identity(); + // let id = boxed_bot.clone().lock().await.get_identity(); + // let id = bot.read().await.get_identity(); + // let id = Arc::clone(&self.botmgrs.identity); + // let id = id.write().await; + // let id = &(*self.get_identity()); + let botlock = bot.read().await; + let id = botlock.get_identity(); + let id = id.read().await; + let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()); + match eval { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); @@ -687,7 +839,15 @@ impl BotInstance // c.execute(bot, msg.clone()).await; // } // let boxed_bot = Arc::new(RwLock::new(self)); - c.execute(boxed_bot.clone(), msg.clone()).await; + // c.execute(boxed_bot.clone(), msg.clone()).await; + // c.execute(self, msg.clone()).await; + //let mut a = *self; + // c.execute(self, msg.clone()); + // let a = self; + // let a = Arc::clone(&self); + let a = Arc::clone(&bot); + // let a = Arc::clone(&bot); + c.execute(a, msg.clone()); } Permissible::Block => { @@ -708,7 +868,10 @@ impl BotInstance //let bot = Rc::clone(&bot).into_inner(); // l.execute(boxed_bot.clone(), msg.clone()).await // let boxed_bot = Arc::new(RwLock::new(self)); - l.execute(boxed_bot.clone(), msg.clone()).await; + // l.execute(boxed_bot.clone(), msg.clone()).await; + // let a = Arc::clone(&self); + let a = Arc::clone(&bot); + l.execute(a, msg.clone()); }, _ => (), @@ -720,6 +883,9 @@ impl BotInstance println!("End of Separate Listener Main prvmsg"); + // self + // bot + } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index a05db7d..38f1fc6 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -6,16 +6,24 @@ use std::collections::HashMap; use crate::core::identity; use std::cell::RefCell; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; +use tokio::sync::RwLock; use std::future::Future; -use futures::lock::Mutex; +// use futures::lock::Mutex; + +// Important to use tokios Mutex here since std Mutex doesn't work with async functions +use tokio::sync::Mutex; use crate::core::botinstance::{self, BotInstance}; use std::rc::Rc; +// use tokio::sync::RwLock; + + + use async_trait::async_trait; /* @@ -55,6 +63,9 @@ pub enum ChType { pub use ChType::Channel; use twitch_irc::message::PrivmsgMessage; +use self::bot_actions::actions_util; +use self::bot_actions::actions_util::BotAR; + #[derive(Debug)] enum StatusLvl { @@ -78,11 +89,12 @@ pub enum BotAction impl BotAction { // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ - pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ + pub 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), + BotAction::C(a) => a.execute(m,n), _ => (), } @@ -92,8 +104,9 @@ impl BotAction { #[async_trait] pub trait BotActionTrait { - async fn add_to_bot(&self, bot:BotInstance); - async fn add_to_modmgr(self,modmgr:Arc>); + async fn add_to_bot(self, bot:BotInstance); + // async fn add_to_modmgr(self,modmgr:&'static ModulesManager); + async fn add_to_modmgr(self,modmgr:Arc); } // #[derive(Clone)] @@ -111,25 +124,38 @@ impl BotCommand { // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ // pub async fn execute(&self,m:Rc<&botinstance::BotManagers>,n:PrivmsgMessage){ - pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ - (self.exec_body)(m,n).await; + // pub async fn execute(&self,m:BotInstance,n:PrivmsgMessage){ + // (self.exec_body)(m,n).await; + // } + // pub fn execute(&self,m:&mut BotInstance,n:PrivmsgMessage) -> () { + // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { + pub fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { + // ((*self).exec_body)(m,n); + // ((*self).exec_body)(*m,n); + // m + // ((*self).exec_body)( + ((*self).exec_body)(m,n); + // m } } #[async_trait] impl BotActionTrait for BotCommand { - async fn add_to_bot(&self, mut bot:BotInstance) { + async fn add_to_bot(self, bot:BotInstance) { // let mgr = &mut bot.botmodules; // let mut mgr = *mgr.lock().await; // let mut mgr = &mut mgr; + // (*self).add_to_modmgr(bot.botmodules); self.add_to_modmgr(bot.botmodules); } - async fn add_to_modmgr(self, modmgr:Arc>) { + // 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)) - let modmgr = *modmgr.lock().await; - modmgr.add_botaction(self.module.clone(), BotAction::C(self)) + // let modmgr = *modmgr.lock().await; + // modmgr.add_botaction(self.module.clone(), BotAction::C(self)) + modmgr.add_botaction(self.module.clone(), BotAction::C(self)).await } } @@ -149,8 +175,13 @@ pub mod bot_actions { use crate::core::botinstance::{BotInstance, BotManagers, Chat}; use twitch_irc::message::PrivmsgMessage; use std::cell::RefCell; - use std::sync::{Arc, RwLock}; - use futures::lock::Mutex; + use std::sync::{Arc}; + // use futures::lock::Mutex; + // Important to use tokios Mutex here since std Mutex doesn't work with async functions + use tokio::sync::{Mutex,RwLock}; + + pub type BotAM = Arc>; + pub type BotAR = Arc>; // pub type ExecBody = Box Pin + Send>> + Send + Sync>; @@ -170,8 +201,14 @@ pub mod bot_actions { // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - + // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box Pin + Send>> + Send + Sync>; + pub type ExecBody = Box Pin + Send>> + Send + Sync>; + // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; + //pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody @@ -187,9 +224,14 @@ pub mod bot_actions { // pub fn asyncbox(f: fn(Arc,PrivmsgMessage) -> T) -> ExecBody // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(BotInstance,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(&'static BotInstance,PrivmsgMessage) -> T) -> ExecBody + // pub fn asyncbox(f: fn(&mut BotInstance,PrivmsgMessage) -> T) -> ExecBody + pub fn asyncbox(f: fn(BotAR,PrivmsgMessage) -> T) -> ExecBody where //T: Future + Send + 'static + // T: Future + Send + 'static T: Future + Send + 'static { Box::new(move |a,b| Box::pin(f(a,b))) @@ -211,25 +253,41 @@ pub struct Listener impl Listener { - pub async fn execute(&self,m:Arc>,n:PrivmsgMessage){ - (self.exec_body)(m,n).await; + // pub async fn execute(&self,m:BotInstance,n:PrivmsgMessage){ + // (self.exec_body)(m,n).await; + // } + // pub fn execute(&self,m:BotInstance,n:PrivmsgMessage){ + // (self.exec_body)(m,n); + // } + // pub fn execute(&self,m:&BotInstance,n:PrivmsgMessage) -> &BotInstance { + // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { + pub fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { + // let mut m = Arc::*m; + ((*self).exec_body)(m,n); + // *self + // &m } } #[async_trait] impl BotActionTrait for Listener { - async fn add_to_bot(&self, mut bot:BotInstance) { + async fn add_to_bot(self, bot:BotInstance) { // let mgr = &mut bot.botmodules; - let mgr = bot.botmodules; - self.add_to_modmgr(mgr); + // let mgr = bot.botmodules; + // self.add_to_modmgr(Arc::new(*mgr)); + self.add_to_modmgr(bot.botmodules); } // fn add_to_modmgr(self, modmgr:&mut ModulesManager) { - async fn add_to_modmgr(self, modmgr:Arc>) { - let modmgr = *modmgr.lock().await; - modmgr.add_botaction(self.module.clone(), BotAction::L(self)) + // async fn add_to_modmgr(self, modmgr:Arc>) { + // async fn add_to_modmgr(self, modmgr:&'static ModulesManager) { + // async fn add_to_modmgr(self, modmgr:&'static ModulesManager) { + async fn add_to_modmgr(self, modmgr:Arc) { + // let modmgr = *modmgr.lock().await; + modmgr.add_botaction(self.module.clone(), BotAction::L(self)).await; + // modmgr.add_botaction(self.module.clone(), BotAction:L(self)) } } @@ -243,14 +301,17 @@ struct Routine {} pub struct ModulesManager { - statusdb: HashMap>, - pub botactions: HashMap>, + // statusdb: HashMap>, + statusdb: Arc>>>, + // pub botactions: HashMap>, + pub botactions: Arc>>>, } impl ModulesManager { - pub fn init() -> Arc> + // pub fn init() -> Arc> + pub fn init() -> Arc { @@ -258,33 +319,40 @@ impl ModulesManager let act = HashMap::new(); let mut mgr = ModulesManager { - statusdb : m, - botactions : act, + statusdb : Arc::new(RwLock::new(m)), + botactions : Arc::new(RwLock::new(act)), }; // :: [x] initialize core modules // crate::core::identity::init(&mut mgr); - let a = Arc::new(Mutex::new(mgr)); - // let a = a.clone(); - crate::core::identity::init(a.clone()); + // let a = Arc::new(Mutex::new(mgr)); + // // let a = a.clone(); + // crate::core::identity::init(a.clone()); + + // crate::core::identity::init(&mgr); + let mgra = Arc::new(mgr); + crate::core::identity::init(Arc::clone(&mgra)); // initialize custom crate modules // crate::modules::init(&mut mgr); // let a = a.clone(); - crate::modules::init(a.clone()); + // crate::modules::init(a.clone()); + crate::modules::init(Arc::clone(&mgra)); println!(">> Modules Manager : End of Init"); // mgr - a + mgra } - pub fn rbotactions(self) -> HashMap> { - self.botactions - } + // pub async fn rbotactions(&self) -> HashMap> { + // // (*self).botactions + // let a = self.botactions.read().await; + // *a + // } pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { @@ -314,7 +382,7 @@ impl ModulesManager //pub fn add_botaction(mut self, in_module:ModType, in_action:BotAction ) -> ModulesManager { // pub fn add_botaction(mut self, in_module:ModType, in_action:BotAction ) -> ModulesManager { //pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) -> () { - pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) { + pub async fn add_botaction(&self, in_module:ModType, in_action:BotAction ) { /* adds a BotAction to the Modules Manager - This will require a BotModule passed as well This will including the logic of a valid add @@ -342,7 +410,7 @@ impl ModulesManager // - 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 - fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option + async fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option { // Some(BotModule(String::from("GambaCore"))) @@ -360,7 +428,8 @@ impl ModulesManager // let n = & mgr.botactions; - let d = &mgr.botactions; + let d = mgr.botactions.read().await; + let d = &(*d); for (module,moduleactions) in d { @@ -431,20 +500,30 @@ impl ModulesManager // // () // return because there was a conflict? // panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , probmod ); // } - match find_conflict_module(&self, &in_action) { + 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 ), None => (), } - let statusvector = self.statusdb + // { + // let mut lala = self; + // let statusvector = (*lala).statusdb + // // .entry(BotModule(String::from("experiments"))) + // .entry(in_module.clone()) + // .or_insert(Vec::new()); + // } + + let mut dbt = self.statusdb.write().await; + let statusvector = dbt // .entry(BotModule(String::from("experiments"))) .entry(in_module.clone()) .or_insert(Vec::new()); statusvector.push(ModStatusType::Enabled(StatusLvl::Instance)); // Pushes the Module as Enabled at Instance Level - let modactions = self.botactions + let mut a = self.botactions.write().await; + let modactions = a //.entry( BotModule(String::from("experiments"))) .entry( in_module.clone()) .or_insert(Vec::new()); diff --git a/src/core/identity.rs b/src/core/identity.rs index 224aa20..7026835 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -20,15 +20,20 @@ use std::cell::RefCell; use std::sync::{Arc, RwLock}; +use super::botmodules::bot_actions::actions_util::BotAR; + + fn adminvector() -> Vec { vec![String::from("ModulatingForce")] } // pub fn init(mgr:&mut ModulesManager) -pub fn init(mgr:Arc>) +pub fn init(mgr:Arc) { + let a = actions_util::asyncbox(cmd_promote) ; + BotCommand { module : BotModule(String::from("identity")), command : String::from("promote"), // command call name @@ -41,9 +46,11 @@ pub fn init(mgr:Arc>) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(mgr); + }.add_to_modmgr(Arc::clone(&mgr)); - async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) + // async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) + // async fn cmd_promote(mut bot:&BotInstance,msg:PrivmsgMessage) -> &BotInstance + async fn cmd_promote(bot:BotAR,msg:PrivmsgMessage) -> () { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("Called cmd promote"); @@ -133,9 +140,11 @@ pub fn init(mgr:Arc>) // if let Some(a) = ta { - let p = bot.lock().await.get_identity(); - let mut p = p.lock().await; - let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + // let p = bot.lock().await.get_identity(); + // let mut p = p.lock().await; + // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + let botlock = bot.read().await; + let ta = botlock.get_identity().read().await.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; if let Some(a) = ta { @@ -183,9 +192,13 @@ pub fn init(mgr:Arc>) // let mut mutex2 = Arc::clone(&mutex).into_inner().get_identity(); // let a = (*bot).lock().await.get_identity(); // let mut a = a.lock().await; - let p = bot.lock().await.get_identity(); - let mut p = p.lock().await; - let ta = p.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + // let p = bot.lock().await.get_identity(); + // let mut p = p.lock().await; + // let ta = p.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + let botlock = Arc::clone(&bot.read().await.get_identity()); + let idlock = botlock.write().await; + // let mut idlock = *idlock; + let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; match ta { // Success(_) => { @@ -227,7 +240,7 @@ pub fn init(mgr:Arc>) - + // bot @@ -245,10 +258,11 @@ pub fn init(mgr:Arc>) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(mgr); + }.add_to_modmgr(Arc::clone(&mgr)); - async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { + // async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { + async fn cmd_demote(mut _chat:BotAR,_msg:PrivmsgMessage) { println!("Called cmd demote"); } @@ -266,10 +280,11 @@ pub fn init(mgr:Arc>) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(mgr); + }.add_to_modmgr(Arc::clone(&mgr)); - async fn getroles(bot:Arc>,msg:PrivmsgMessage) { + // async fn getroles(bot:Arc>,msg:PrivmsgMessage) { + async fn getroles(bot:BotAR,msg:PrivmsgMessage) { println!("Called cmd getroles"); /* @@ -337,10 +352,14 @@ pub fn init(mgr:Arc>) // let a = a.into_inner(); // let a = a.identity; // let a = a.into_inner(); - let a = bot.clone(); - let a = a.lock().await; - let a = a.get_identity().await; + // let a = bot.clone(); // let a = a.lock().await; + // let a = a.get_identity(); + // let a = a.lock().await; + // let a = bot.get_identity(); + let botlock = bot.read().await; + let idlock = botlock.get_identity(); + let idlock = idlock.read().await; let sproles = match targetchnl { None => { // let bot = Rc::clone(&bot); @@ -352,7 +371,8 @@ pub fn init(mgr:Arc>) // let a = a.ok().getspecialuserroles(String::from(targetuser),None); // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); // println!("Retrieved User Roles >> {:?}",a); - a.lock().await.getspecialuserroles(String::from(targetuser),None).await + // let a = idlock.read().await; + idlock.getspecialuserroles(String::from(targetuser),None).await }, Some(targetchnl) => { // let bot = Rc::clone(&bot); @@ -365,7 +385,8 @@ pub fn init(mgr:Arc>) // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); // println!("Retrieved User Roles >> {:?}",a); // bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None) - a.lock().await.getspecialuserroles(String::from(targetuser),None).await + // let a = a.read().await; + idlock.getspecialuserroles(String::from(targetuser),None).await }, }; @@ -445,7 +466,8 @@ impl IdentityManager { // 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(self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible + pub fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -497,9 +519,11 @@ impl IdentityManager { // [ ] Call can_user_run() + // (self,Permissible::Block) Permissible::Block } + pub async fn can_user_run(&self, usr:String, channelname:ChType, @@ -661,7 +685,8 @@ impl IdentityManager { Permissible::Block } - pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { + // pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { + pub async fn promote(&self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { // Note : If channel is none, getspecialuserroles() returns all roles for the user diff --git a/src/main.rs b/src/main.rs index 3ef7654..4278813 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,13 +7,16 @@ use std::process::Output; use crate::core::botinstance::ArcBox; use crate::core::botinstance::BotInstance; +use tokio::sync::RwLock; +use std::sync::Arc; +pub type BotAR = Arc>; #[tokio::main] pub async fn main() { let bot = BotInstance::init(); - bot.clone().runner().await; + bot.runner().await; println!("ERROR : EXIT Game loop"); diff --git a/src/modules.rs b/src/modules.rs index 13e39ae..5d533c6 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -27,7 +27,7 @@ mod experiments; // // F : Send, // F : Send + ?Sized, // pub fn init(mgr:&mut ModulesManager) -pub fn init(mgr:Arc>) +pub fn init(mgr:Arc) { // Modules initializer loads modules into the bot // this is achieved by calling submodules that also have fn init() defined diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 828d9f2..6548320 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -15,7 +15,7 @@ use std::future::Future; use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType}; -use crate::core::botmodules::bot_actions::actions_util; +use crate::core::botmodules::bot_actions::actions_util::{self, BotAR}; use crate::core::botinstance::{self,BotInstance}; use futures::lock::Mutex; @@ -32,7 +32,7 @@ use std::sync::{Arc, RwLock}; // pub fn init(mgr:&mut ModulesManager) -pub fn init(mgr:Arc>) +pub fn init(mgr:Arc) { @@ -49,7 +49,7 @@ pub fn init(mgr:Arc>) // }.add_to_modmgr(mgr); - BotCommand { + 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 @@ -58,7 +58,9 @@ pub fn init(mgr:Arc>) required_roles : vec![ identity::UserRole::BotAdmin ], - }.add_to_modmgr(mgr); + }; + + botc1.add_to_modmgr(Arc::clone(&mgr)); @@ -69,13 +71,13 @@ pub fn init(mgr:Arc>) help : String::from("") }; - list1.add_to_modmgr(mgr); + list1.add_to_modmgr(Arc::clone(&mgr)); } -async fn good_girl(mut bot:Arc>,msg:PrivmsgMessage) +async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) { println!("In GoodGirl() Listener"); //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -120,18 +122,22 @@ async fn good_girl(mut bot:Arc>,msg:PrivmsgMessage) // None => (), // } // Arc::try_unwrap(bot).ok().unwrap().botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; - let a = bot.clone(); + // let a = bot.clone(); + let a = Arc::clone(&bot); // let a = a.read().ok().unwrap(); // let a = a.lock().await.get_botmgrs(); // let a = a.lock().await.rChat(); - let a = (*bot).lock().await.get_botmgrs(); - let a = a.lock().await.rChat(); - let mut a = (*a).lock().await; + // let a = (*bot).lock().await.get_botmgrs(); + // let a = a.lock().await.rChat(); + // let mut a = (*a).lock().await; + // let a = a.botmgrs.chat.say_in_reply_to(&msg, outmsg) // a.rbotmgrs().chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; // a.lock().await.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; - a.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + // a.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; + let botlock = a.read().await; + botlock.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; } @@ -140,7 +146,7 @@ async fn good_girl(mut bot:Arc>,msg:PrivmsgMessage) } -async fn testy(mut _chat:Arc>,_msg:PrivmsgMessage) +async fn testy(mut _chat:BotAR,_msg:PrivmsgMessage) { println!("testy triggered!") -- 2.46.1 From cc11479bf2b51dd921aa7de286cf754357f1a7a3 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 02:34:32 -0500 Subject: [PATCH 19/39] 2024.02.12 - GetRole() Works --- src/core/botinstance.rs | 26 ++++++++++++------ src/core/botmodules.rs | 12 ++++++--- src/core/identity.rs | 59 ++++++++++++++++++++++++++++++++--------- src/main.rs | 19 ++++++++++++- 4 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 090b0d5..03b68a4 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -240,7 +240,7 @@ impl BotInstance // pub fn init() -> BotInstance // pub fn init() -> Arc - pub fn init() -> BotInstance + pub async fn init() -> BotInstance { dotenv().ok(); @@ -295,7 +295,7 @@ impl BotInstance // ratelimiters : ratelimiters, // client : client, // } , - botmodules : ModulesManager::init(), + botmodules : ModulesManager::init().await, twitch_oauth : oauth_token, bot_channels : botchannels, // identity : IdentityManager::init(), @@ -620,6 +620,7 @@ impl BotInstance // async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { // async fn listener_main_prvmsg(self:Arc,msg:&PrivmsgMessage) -> () { pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { + println!(">> Inner listenermain_prvmsg()"); // let a = a; // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -672,18 +673,25 @@ impl BotInstance // let hacts = boxed_bot.clone().lock().await.get_botactions(); // let hacts = bot.read().await.get_botactions(); let botlock = bot.read().await; - let hacts = botlock.botmodules.botactions.read().await; - // let hacts = hacts - for (_m,acts) in &(*hacts) { - + let hacts = Arc::clone(&botlock.botmodules.botactions); + // let hacts = hacts.read().await; + let a = hacts.read().await; + println!("hacts size : {}",(*a).len()); + println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); + // println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions : {:?}",*hacts); + // let hacts = hacts + // let l = *hacts; + for (_m,acts) in &*hacts.read().await { + + println!(">> Inner listenermain_prvmsg() >> checking bot actions"); // let bot = bot; for a in acts { - + println!(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); let _act = match a { @@ -702,6 +710,8 @@ impl BotInstance // println!("args : {v}"); // } + println!("Reviewing internal commands"); + let inpt = msg.message_text.split("\n").next().expect("ERROR during BotCommand"); let inpt = msg.message_text.split(" ").next().expect("ERROR during BotCommand"); @@ -829,7 +839,7 @@ impl BotInstance let botlock = bot.read().await; let id = botlock.get_identity(); let id = id.read().await; - let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()); + let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; match eval { // Ok(Permissible::Allow) => (), Permissible::Allow => { diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 38f1fc6..3d55f3c 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -277,7 +277,8 @@ impl BotActionTrait for Listener // let mgr = &mut bot.botmodules; // let mgr = bot.botmodules; // self.add_to_modmgr(Arc::new(*mgr)); - self.add_to_modmgr(bot.botmodules); + println!("Adding action to bot"); + self.add_to_modmgr(bot.botmodules).await; } // fn add_to_modmgr(self, modmgr:&mut ModulesManager) { @@ -286,6 +287,7 @@ impl BotActionTrait for Listener // async fn add_to_modmgr(self, modmgr:&'static ModulesManager) { async fn add_to_modmgr(self, modmgr:Arc) { // let modmgr = *modmgr.lock().await; + println!("Adding action to module manager"); modmgr.add_botaction(self.module.clone(), BotAction::L(self)).await; // modmgr.add_botaction(self.module.clone(), BotAction:L(self)) } @@ -311,7 +313,7 @@ impl ModulesManager { // pub fn init() -> Arc> - pub fn init() -> Arc + pub async fn init() -> Arc { @@ -331,8 +333,9 @@ impl ModulesManager // crate::core::identity::init(a.clone()); // crate::core::identity::init(&mgr); + println!("ModulesManager > init() > Adding modules"); let mgra = Arc::new(mgr); - crate::core::identity::init(Arc::clone(&mgra)); + crate::core::identity::init(Arc::clone(&mgra)).await; // initialize custom crate modules // crate::modules::init(&mut mgr); @@ -340,7 +343,7 @@ impl ModulesManager // crate::modules::init(a.clone()); crate::modules::init(Arc::clone(&mgra)); - + println!(">> Modules Manager : End of Init"); @@ -383,6 +386,7 @@ impl ModulesManager // pub fn add_botaction(mut self, in_module:ModType, in_action:BotAction ) -> ModulesManager { //pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) -> () { pub async fn add_botaction(&self, in_module:ModType, in_action:BotAction ) { + println!("Add botaction called"); /* adds a BotAction to the Modules Manager - This will require a BotModule passed as well This will including the logic of a valid add diff --git a/src/core/identity.rs b/src/core/identity.rs index 7026835..70d9508 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -29,12 +29,14 @@ fn adminvector() -> Vec { // pub fn init(mgr:&mut ModulesManager) -pub fn init(mgr:Arc) +pub async fn init(mgr:Arc) { - let a = actions_util::asyncbox(cmd_promote) ; + println!("Went into Identiy Module init"); - BotCommand { + // 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 @@ -46,7 +48,9 @@ pub fn init(mgr:Arc) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(Arc::clone(&mgr)); + }; + + tempb.add_to_modmgr(Arc::clone(&mgr)); // async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) // async fn cmd_promote(mut bot:&BotInstance,msg:PrivmsgMessage) -> &BotInstance @@ -246,7 +250,21 @@ pub fn init(mgr:Arc) } - BotCommand { + // 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![ + // UserRole::Mod(ChType::Channel(String::new())), + // UserRole::SupMod(ChType::Channel(String::new())), + // UserRole::Broadcaster, + // UserRole::BotAdmin, + // ], + // }.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 @@ -258,8 +276,9 @@ pub fn init(mgr:Arc) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(Arc::clone(&mgr)); - + }; + + tempb.add_to_modmgr(Arc::clone(&mgr)).await; // async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { async fn cmd_demote(mut _chat:BotAR,_msg:PrivmsgMessage) { @@ -268,7 +287,21 @@ pub fn init(mgr:Arc) - BotCommand { + // 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, + // ], + // }.add_to_modmgr(Arc::clone(&mgr)); + + let tempcomm = BotCommand { module : BotModule(String::from("identity")), command : String::from("getroles"), // command call name alias : vec![], // String of alternative names @@ -280,7 +313,9 @@ pub fn init(mgr:Arc) UserRole::Broadcaster, UserRole::BotAdmin, ], - }.add_to_modmgr(Arc::clone(&mgr)); + }; + + tempcomm.add_to_modmgr(Arc::clone(&mgr)).await; // async fn getroles(bot:Arc>,msg:PrivmsgMessage) { @@ -401,7 +436,7 @@ pub fn init(mgr:Arc) - + println!("End of Init MOdule add"); } @@ -467,7 +502,7 @@ impl IdentityManager { // 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 fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible + pub async fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -513,7 +548,7 @@ impl IdentityManager { ChType::Channel(msg.channel_login.to_owned()), sender_badge, cmdreqroles - ) ; + ).await ; } diff --git a/src/main.rs b/src/main.rs index 4278813..7847da3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,24 @@ pub type BotAR = Arc>; #[tokio::main] pub async fn main() { - let bot = BotInstance::init(); + let bot = BotInstance::init().await; + + let a = Arc::clone(&bot.botmodules.botactions); + let a = a.read().await; + // let a = *a; + + for (_,acts) in &*a { + for act in acts { + match act { + crate::core::botmodules::BotAction::C(b) => println!("bot actiions: {}",b.command), + crate::core::botmodules::BotAction::L(l) => println!("bot actiions: {}",l.name), + _ => println!("Not a valid match??"), + } + + } + }; + + println!("Starting runner.."); bot.runner().await; -- 2.46.1 From 372893af150d7988f673aad851eda245511f76f9 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 05:25:38 -0500 Subject: [PATCH 20/39] 2024.02.12 - Working getuserroles --- src/core/botinstance.rs | 24 +++++-- src/core/botmodules.rs | 16 ++--- src/core/identity.rs | 151 +++++++++++++++++++++++++++------------- 3 files changed, 128 insertions(+), 63 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 03b68a4..bb1ec78 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -776,7 +776,7 @@ impl BotInstance } if confirmed_bot_command { - + println!("Confirmed bot command"); // self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()); // [ ] Around here, validate if permissable before executing @@ -819,7 +819,7 @@ impl BotInstance // match a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await { - { + // let le = boxed_bot.lock().await; // // let le = le.lock().await; // let le = le.get_identity().await; @@ -836,10 +836,19 @@ impl BotInstance // let id = Arc::clone(&self.botmgrs.identity); // let id = id.write().await; // let id = &(*self.get_identity()); + println!("Going for botlock"); let botlock = bot.read().await; + println!("Going for identity"); let id = botlock.get_identity(); - let id = id.read().await; - let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + // let mut id = id.write().await; + // println!("Unlocking identity"); + // let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + let eval = { + let mut id = id.write().await; + println!("Unlocking identity"); + id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await + }; + println!("Checking if permissible"); match eval { // Ok(Permissible::Allow) => (), Permissible::Allow => { @@ -857,7 +866,8 @@ impl BotInstance // let a = Arc::clone(&self); let a = Arc::clone(&bot); // let a = Arc::clone(&bot); - c.execute(a, msg.clone()); + c.execute(a, msg.clone()).await; + println!("exit out of execution"); } Permissible::Block => { @@ -867,7 +877,7 @@ impl BotInstance }; // c.execute(self.chat.clone(), msg.clone()).await; - } + } }, @@ -881,7 +891,7 @@ impl BotInstance // l.execute(boxed_bot.clone(), msg.clone()).await; // let a = Arc::clone(&self); let a = Arc::clone(&bot); - l.execute(a, msg.clone()); + l.execute(a, msg.clone()).await; }, _ => (), diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 3d55f3c..a46b479 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -89,12 +89,12 @@ pub enum BotAction impl BotAction { // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ - pub 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), - BotAction::C(a) => a.execute(m,n), + BotAction::L(a) => a.execute(m,n).await, + BotAction::C(a) => a.execute(m,n).await, _ => (), } @@ -129,12 +129,12 @@ impl BotCommand // } // pub fn execute(&self,m:&mut BotInstance,n:PrivmsgMessage) -> () { // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { - pub fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { + pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { // ((*self).exec_body)(m,n); // ((*self).exec_body)(*m,n); // m // ((*self).exec_body)( - ((*self).exec_body)(m,n); + ((*self).exec_body)(m,n).await; // m } } @@ -147,7 +147,7 @@ impl BotActionTrait for BotCommand // let mut mgr = *mgr.lock().await; // let mut mgr = &mut mgr; // (*self).add_to_modmgr(bot.botmodules); - self.add_to_modmgr(bot.botmodules); + self.add_to_modmgr(bot.botmodules).await; } // async fn add_to_modmgr(self, modmgr:Arc>) { @@ -261,9 +261,9 @@ impl Listener // } // pub fn execute(&self,m:&BotInstance,n:PrivmsgMessage) -> &BotInstance { // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { - pub fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { + pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { // let mut m = Arc::*m; - ((*self).exec_body)(m,n); + ((*self).exec_body)(m,n).await; // *self // &m } diff --git a/src/core/identity.rs b/src/core/identity.rs index 70d9508..8bc3ce6 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -18,7 +18,9 @@ use crate::core::botinstance::ArcBox; use std::rc::Rc; use std::cell::RefCell; -use std::sync::{Arc, RwLock}; +use std::sync::{Arc}; +use tokio::sync::RwLock; + use super::botmodules::bot_actions::actions_util::BotAR; @@ -50,7 +52,7 @@ pub async fn init(mgr:Arc) ], }; - tempb.add_to_modmgr(Arc::clone(&mgr)); + tempb.add_to_modmgr(Arc::clone(&mgr)).await; // async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) // async fn cmd_promote(mut bot:&BotInstance,msg:PrivmsgMessage) -> &BotInstance @@ -148,9 +150,14 @@ pub async fn init(mgr:Arc) // let mut p = p.lock().await; // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; let botlock = bot.read().await; - let ta = botlock.get_identity().read().await.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - - if let Some(a) = ta { + let ta = botlock.get_identity(); + let ta = ta.read().await; + let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; + let ta = ta.unwrap(); + let a = ta.read().await; + // let ta = *ta; + // let ta = *ta; + // if let Some(a) = *ta { if a.contains(&UserRole::BotAdmin) { println!("BotAdmin allowed to promote admin"); @@ -217,12 +224,12 @@ pub async fn init(mgr:Arc) } } - }, - Some(_) => { - // - + // }, + // Some(_) => { + // // - - }, - _ => (), + // }, + _ => (), } @@ -318,6 +325,7 @@ pub async fn init(mgr:Arc) tempcomm.add_to_modmgr(Arc::clone(&mgr)).await; + // async fn getroles(bot:Arc>,msg:PrivmsgMessage) { async fn getroles(bot:BotAR,msg:PrivmsgMessage) { println!("Called cmd getroles"); @@ -393,8 +401,11 @@ pub async fn init(mgr:Arc) // let a = a.lock().await; // let a = bot.get_identity(); let botlock = bot.read().await; + println!("botlock read"); let idlock = botlock.get_identity(); - let idlock = idlock.read().await; + println!("got identity"); + let idlock = idlock.read().await; // <-- 02.12 - Latest where it gest stuck - before or at this point + println!("id lock"); let sproles = match targetchnl { None => { // let bot = Rc::clone(&bot); @@ -465,7 +476,9 @@ pub enum Permissible { #[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>>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel + // special_roles_users : Arc>>>, + special_roles_users : Arc>>>>>, // parent_mgr : Box, //parent_mgr : Option>, } @@ -488,11 +501,11 @@ impl IdentityManager { pub fn init() -> IdentityManager { let mut a = HashMap::new(); for admn in adminvector() { - a.insert(admn.to_lowercase(),vec![UserRole::BotAdmin]); + a.insert(admn.to_lowercase(),Arc::new(RwLock::new(vec![UserRole::BotAdmin]))); }; IdentityManager { - special_roles_users : Arc::new(Mutex::new(a)), + special_roles_users : Arc::new(RwLock::new(a)), //parent_mgr : None, } } @@ -502,11 +515,12 @@ impl IdentityManager { // 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(&self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible + pub async fn can_user_run_PRVMSG(&mut self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // [ ] Check what Badges in PrivmsgMessage + println!{"Checking within PRVMSG"}; let mut sender_badge:Option = None; @@ -544,11 +558,11 @@ impl IdentityManager { // cmdreqroles // ) ; // return a; - self.can_user_run(msg.sender.name.to_owned(), + return self.can_user_run(msg.sender.name.to_owned(), ChType::Channel(msg.channel_login.to_owned()), sender_badge, cmdreqroles - ).await ; + ).await } @@ -559,13 +573,14 @@ impl IdentityManager { } - pub async fn can_user_run(&self, + pub async fn can_user_run(&mut self, usr:String, channelname:ChType, chat_badge:ChatBadge, cmdreqroles:Vec // ) -> Result> { ) -> Permissible { + println!{"Checking within can_user_run()"}; /* canUserRun - @@ -604,6 +619,8 @@ impl IdentityManager { // [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow) + // let idar = Arc::new(RwLock::new(self)); + if cmdreqroles.len() == 0 { // return Ok(Permissible::Allow) return Permissible::Allow @@ -632,7 +649,7 @@ impl IdentityManager { ChatBadge::Mod => { - // println!("Mod Chatbadge detected"); + println!("Mod Chatbadge detected"); // println!("debug special roles : {:?}",self.special_roles_users); // println!("debug usr : {}",&usr.to_lowercase()); @@ -640,27 +657,39 @@ impl IdentityManager { // 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()) { - match self.special_roles_users.lock().await.get(&usr.to_lowercase()) { - Some(usrroles) => { - // println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone()))); - // println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone()))); - if usrroles.contains(&UserRole::Mod(channelname.clone())) || - usrroles.contains(&UserRole::SupMod(channelname.clone())) { + println!("Creating clone"); + let roleslock = Arc::clone(&(*self).special_roles_users); + println!("Read lock on : Special_Roles_User"); // <-- after this is slightly different between working and problem + let mut roleslock = roleslock.write().await; + match (*roleslock).get(&usr.to_lowercase()) { + Some(usrroles) => { // <-- 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()))); + if usrroles.read().await.contains(&UserRole::Mod(channelname.clone())) || + usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())) { // Do nothing - this is expected + println!("Already a mod in roles"); } else { // in this case, they have a ChatBadge::Mod but should have this for the channel // let mut a = usrroles; // usrroles.push(UserRole::Mod(channelname.clone())); // a.push(UserRole::Mod(channelname.clone())); - self.special_roles_users - .lock().await - .get_mut(&usr.to_lowercase()) - .expect("ERROR") - .push(UserRole::Mod(channelname.clone())); + println!("Was in the else loop"); + + // let a = &*self; + // let mut lock = a.special_roles_users.write().await; + println!("lock created > adding with a mod role o7"); + roleslock.get_mut(&usr.to_lowercase()) + // .expect("ERROR") + .unwrap() + .write().await + // .get_mut() + .push(UserRole::Mod(channelname.clone())); // println!("debug special roles : {:?}",self.special_roles_users); + } }, - _ => () + _ => ( ) // <-- I'm assuming problem got to here } }, @@ -680,9 +709,11 @@ impl IdentityManager { println!("Mod Role required"); - if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { - if a.contains(&UserRole::Mod(channelname.clone())) || a.contains(&UserRole::SupMod(channelname.clone())){ + if let Some(a) = (&*self).special_roles_users.read().await.get(&usr.to_lowercase()) { + println!("Special roles found for user"); + 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 "); return Permissible::Allow } } @@ -693,8 +724,8 @@ impl IdentityManager { if cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { - if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { - if a.contains(&UserRole::SupMod(channelname.clone())) { + 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 } @@ -707,10 +738,10 @@ impl IdentityManager { println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); if cmdreqroles.contains(&UserRole::BotAdmin) { - println!("special roles get : {:?}",self.special_roles_users.lock().await.get(&usr.to_lowercase())); - if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) { - println!("special roles contains BotAdmin: {}",a.contains(&UserRole::BotAdmin)); - if a.contains(&UserRole::BotAdmin) { + println!("special roles get : {:?}",(&*self).special_roles_users.read().await.get(&usr.to_lowercase())); + 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)); + if a.read().await.contains(&UserRole::BotAdmin) { // return Ok(Permissible::Allow); return Permissible::Allow } @@ -737,7 +768,7 @@ impl IdentityManager { let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; // let chatterroles = chatterroles.lock().await; // let chatterroles = *chatterroles; - let chatterroles = chatterroles.unwrap(); + // let chatterroles = chatterroles.unwrap(); // let emptyvec = vec![]; @@ -747,19 +778,26 @@ impl IdentityManager { // _ => &(emptyvec), // }; + let chatterroles = chatterroles.unwrap(); + let chatterroles = chatterroles.read().await; + let rolemap = &(*chatterroles); + + match trg_role { Some(UserRole::Mod(a)) => { if let Some(trg_chnl) = channel { - if chatterroles.contains(&UserRole::Mod(trg_chnl.clone())) { + // let rolemap = rolemap.unwrap(); + if rolemap.contains(&UserRole::Mod(trg_chnl.clone())) { return ChangeResult::NoChange(String::from("Target User already has Target Role")); } // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); self.special_roles_users - .lock().await + .write().await .get_mut(&trgchatter) .expect("Error getting roles") + .write().await .push(UserRole::Mod(trg_chnl)); return ChangeResult::Success(String::from("Promotion Successful")); @@ -845,7 +883,10 @@ impl IdentityManager { ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option> { + pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { + /* + Note : Ideally this be called for a given chatter name ? + */ // let a = chattername.to_lowercase(); @@ -863,7 +904,7 @@ impl IdentityManager { // println!("> Roles : {:?}",v); // } - let a = chattername.to_lowercase(); + let chattername = chattername.to_lowercase(); // println!("{a}"); @@ -873,12 +914,26 @@ impl IdentityManager { // Some(b) => Some(*b), // None => None, // } + // println!("Write Lock on Special Roles @ Getspecialuserroles()"); + // let b = self.special_roles_users.write().await.remove(&a); + // let outp = b; + // // let b = Arc::new(Mutex::new(outp)); + // outp - let b = self.special_roles_users.lock().await.remove(&a); - let outp = b; - // let b = Arc::new(Mutex::new(outp)); - outp + let rolesa = Arc::clone(&self.special_roles_users); + let a = rolesa.read().await; + // let a = Arc::clone(a) + let a = a; + let outr = &(*a); + let outr = outr.get(&chattername); + match outr { + Some(a) => Some(Arc::clone(a)), + None => None, + + } + + // Arc::new(RwLock::new(outr)) // let b = Arc::new(Mutex::new(b)); // b -- 2.46.1 From a16f7fbf04daf6d0abee55daab85ddaaf9edc995 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 1 Feb 2024 09:43:39 -0500 Subject: [PATCH 21/39] Problem - with botmanagers --- src/core/botinstance.rs | 53 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 568d4e6..020185f 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -17,6 +17,7 @@ use rand::Rng; +use crate::core::botmodules::BotAction; use crate::core::ratelimiter::RateLimiter; use crate::core::ratelimiter; @@ -313,7 +314,10 @@ impl BotInstance for (_m,acts) in &self.botmodules.botactions { for a in acts { - match a { + // match a { + // let Some((b,msg)) = match a { + let b = match a { + crate::core::botmodules::BotAction::C(c) => { /* @@ -364,27 +368,64 @@ impl BotInstance // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // let a = match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); - c.execute(self.botmgrs.clone(), msg.clone()).await; + // c.execute(self.botmgrs.clone(), msg.clone()).await; + // c.execute(self.botmgrs, msg.clone()).await; + // Some((BotAction::C(c),msg.clone())) + Some(msg) + //Some(BotAction::C(*c)) + //Some(String::from("Hello")) } - Permissible::Block => println!("User Not allowed to run command"), + Permissible::Block => { + println!("User Not allowed to run command"); + // None::<(BotAction,PrivmsgMessage)> + None::<&PrivmsgMessage> + //None + //Some(String::from("Hello")) + }, // _ => (), - } + }; // c.execute(self.chat.clone(), msg.clone()).await; + } + None::<&PrivmsgMessage> // [ ] Command not confirmed? }, - crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.clone(), msg.clone()).await, + // crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.clone(), msg.clone()).await, + //crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs, msg.clone()).await, - _ => (), + _ => None::<&PrivmsgMessage> , // -- [ ] If not any known botaction + }; + + // b = BotAction either found or not + match b { + Some(b) => { + // a.execute(self.botmgrs.clone(), b.clone()).await; // This compiles but issue - botmgrs aren't updating + a.execute(self.botmgrs, b.clone()).await; // This throws the following + /* + error[E0507]: cannot move out of `self.botmgrs` which is behind a shared reference + --> src\core\botinstance.rs:409:35 + | + 409 | a.execute(self.botmgrs, b.clone()).await; // This throws + | ^^^^^^^^^^^^ move occurs because `self.botmgrs` has type `BotManagers`, which does not implement the `Copy` trait + */ + } + None => (), } + + + + } }; + + // // [ ] There should be a BotCommand Listener to check for prefixes ran println!("End of Separate Listener Main prvmsg"); -- 2.46.1 From 760461a9b49948a186606f73f349ff8b8282a907 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 06:18:57 -0500 Subject: [PATCH 22/39] smol add awaits --- src/core/botmodules.rs | 3 ++- src/modules.rs | 4 ++-- src/modules/experiments.rs | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index a46b479..bbc9f66 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -341,7 +341,7 @@ impl ModulesManager // crate::modules::init(&mut mgr); // let a = a.clone(); // crate::modules::init(a.clone()); - crate::modules::init(Arc::clone(&mgra)); + crate::modules::init(Arc::clone(&mgra)).await; @@ -536,6 +536,7 @@ impl ModulesManager modactions.push(in_action); println!(">> Modules Manager : Called Add bot Action"); + println!("add_botaction - botactions size : {}",modactions.len()); //println!(">> Modules Manager : {:?}",&self); //(); diff --git a/src/modules.rs b/src/modules.rs index 5d533c6..651ea38 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -27,12 +27,12 @@ mod experiments; // // F : Send, // F : Send + ?Sized, // pub fn init(mgr:&mut ModulesManager) -pub 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) + experiments::init(mgr).await //(); } \ No newline at end of file diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 6548320..f7968c9 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -32,7 +32,7 @@ use std::sync::{Arc, RwLock}; // pub fn init(mgr:&mut ModulesManager) -pub fn init(mgr:Arc) +pub async fn init(mgr:Arc) { @@ -60,7 +60,7 @@ pub fn init(mgr:Arc) ], }; - botc1.add_to_modmgr(Arc::clone(&mgr)); + botc1.add_to_modmgr(Arc::clone(&mgr)).await; @@ -71,7 +71,7 @@ pub fn init(mgr:Arc) help : String::from("") }; - list1.add_to_modmgr(Arc::clone(&mgr)); + list1.add_to_modmgr(Arc::clone(&mgr)).await; } -- 2.46.1 From 00796f36287afac68b54e366588c373d9dbf17c1 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 1 Feb 2024 19:23:27 -0500 Subject: [PATCH 23/39] 20240201 - latest issue --- src/core/botinstance.rs | 26 ++++++++++++++++---------- src/core/identity.rs | 4 ++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 020185f..32e44af 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -305,7 +305,7 @@ impl BotInstance // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - async fn listener_main_prvmsg(&self,msg:&PrivmsgMessage) -> () { + async fn listener_main_prvmsg(&mut self,msg:&PrivmsgMessage) -> () { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -369,13 +369,15 @@ impl BotInstance // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // let a = match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { + match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); // c.execute(self.botmgrs.clone(), msg.clone()).await; // c.execute(self.botmgrs, msg.clone()).await; // Some((BotAction::C(c),msg.clone())) + // Some((msg,self)) Some(msg) //Some(BotAction::C(*c)) //Some(String::from("Hello")) @@ -383,6 +385,7 @@ impl BotInstance Permissible::Block => { println!("User Not allowed to run command"); // None::<(BotAction,PrivmsgMessage)> + // None::<(&PrivmsgMessage,&mut BotInstance)> None::<&PrivmsgMessage> //None //Some(String::from("Hello")) @@ -406,14 +409,17 @@ impl BotInstance match b { Some(b) => { // a.execute(self.botmgrs.clone(), b.clone()).await; // This compiles but issue - botmgrs aren't updating - a.execute(self.botmgrs, b.clone()).await; // This throws the following - /* - error[E0507]: cannot move out of `self.botmgrs` which is behind a shared reference - --> src\core\botinstance.rs:409:35 - | - 409 | a.execute(self.botmgrs, b.clone()).await; // This throws - | ^^^^^^^^^^^^ move occurs because `self.botmgrs` has type `BotManagers`, which does not implement the `Copy` trait - */ + // a.execute(self.botmgrs, b.clone()).await; // This throws the following + // /* + // error[E0507]: cannot move out of `self.botmgrs` which is behind a shared reference + // --> src\core\botinstance.rs:409:35 + // | + // 409 | a.execute(self.botmgrs, b.clone()).await; // This throws + // | ^^^^^^^^^^^^ move occurs because `self.botmgrs` has type `BotManagers`, which does not implement the `Copy` trait + // */ + let (msg) = b; + // a.execute(self.botmgrs.clone(), msg.clone()).await; + a.execute(self.botmgrs, msg.clone()).await; } None => (), } diff --git a/src/core/identity.rs b/src/core/identity.rs index a6c6337..5485879 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -306,7 +306,7 @@ impl IdentityManager { // [ ] 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) -> Permissible + pub fn can_user_run_PRVMSG(&mut self,msg:&PrivmsgMessage,cmdreqroles:Vec) -> Permissible { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -344,7 +344,7 @@ impl IdentityManager { Permissible::Block } - pub fn can_user_run(mut self, + pub fn can_user_run(&mut self, usr:String, channelname:ChType, chat_badge:ChatBadge, -- 2.46.1 From a83e77ddcff508e397517c8280a8000f8533e46c Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 06:31:28 -0500 Subject: [PATCH 24/39] 20240212 - working fn param botinstance --- src/core/botinstance.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 01f61c6..fa0180b 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -32,7 +32,7 @@ use crate::core::ratelimiter::RateLimiter; use crate::core::ratelimiter; use crate::core::botmodules; -use crate::core::botmodules::{ModulesManager,BotAction}; +use crate::core::botmodules::ModulesManager; use crate::core::identity::{IdentityManager,Permissible}; use std::rc::Rc; @@ -882,8 +882,7 @@ impl BotInstance // c.execute(self.chat.clone(), msg.clone()).await; } - None::<&PrivmsgMessage> // [ ] Command not confirmed? - None::<&PrivmsgMessage> // [ ] Command not confirmed? + // None::<&PrivmsgMessage> // [ ] Command not confirmed? }, crate::core::botmodules::BotAction::L(l) => { -- 2.46.1 From bac99f58459fbb187cdde729a21a405f841be6b6 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:54:35 -0500 Subject: [PATCH 25/39] comments cleanup --- src/core/botinstance.rs | 464 +------------------------------------ src/core/botmodules.rs | 134 +---------- src/core/identity.rs | 145 +----------- src/modules.rs | 7 - src/modules/experiments.rs | 44 +--- 5 files changed, 19 insertions(+), 775 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index fa0180b..b2c065c 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -57,18 +57,8 @@ pub enum ChType { pub use ChType::Channel; - - -// pub enum ModType { -// BotModule(String), -// } - -// pub use ModType::BotModule; - - #[derive(Clone)] pub struct Chat { - // pub ratelimiters : HashMap, // used to limit messages sent per channel pub ratelimiters : Arc>>, // used to limit messages sent per channel pub client : TwitchIRCClient,StaticLoginCredentials>, } @@ -84,7 +74,6 @@ impl Chat { } } - // pub 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); @@ -103,31 +92,23 @@ impl Chat { */ - // self.client.say_in_reply_to(msg,outmsg).await.unwrap(); - - // // let contextratelimiter = ratelimiters.get_mut(&msg.channel_login).expect("ERROR: Issue with Rate limiters"); let a = Arc::clone(&self.ratelimiters); let mut a = a.lock().await; - // let contextratelimiter = self.ratelimiters let contextratelimiter = a // .get_mut() .get_mut(&Channel(String::from(&msg.channel_login))) .expect("ERROR: Issue with Rate limiters"); - // let contextratelimiter = self.ratelimiters.get(&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); - //let mut outmsg = "GotTrolled ".to_owned(); - // let mut outmsg = "annytfLurk ".to_owned(); for _i in 1..maxblanks { let blankspace: &str = "ó €€"; outmsg.push_str(blankspace); } - // 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"); contextratelimiter.increment_counter(); @@ -184,14 +165,8 @@ impl BotManagers { pub fn init(ratelimiters:HashMap, client:TwitchIRCClient, StaticLoginCredentials>) -> BotManagers { - // let a = Arc::new(Mutex::new(BotManagers { - // // botmodules : ModulesManager::init(), - // identity : Arc::new(Mutex::new(IdentityManager::init())), - // chat : Chat::init(ratelimiters,client), - // })); - // a + BotManagers { - // botmodules : ModulesManager::init(), identity : Arc::new(RwLock::new(IdentityManager::init())), chat : Chat::init(ratelimiters,client), } @@ -201,9 +176,6 @@ impl BotManagers { self.identity } - // pub fn rChat(&self) -> Arc> { - // Arc::new(Mutex::new(self.chat)) - // } } @@ -222,15 +194,10 @@ pub struct BotInstance { pub prefix : char, pub bot_channel : ChType, - // pub incoming_messages : UnboundedReceiver, pub incoming_messages : Arc>>, - // pub incoming_messages : RefCell>, - // pub chat : Chat, pub botmodules : Arc, pub twitch_oauth : String, pub bot_channels : Vec, - // pub identity : IdentityManager, - // pub botmgrs : Arc>, pub botmgrs : BotManagers, } @@ -240,8 +207,6 @@ impl BotInstance { - // pub fn init() -> BotInstance - // pub fn init() -> Arc pub async fn init() -> BotInstance { dotenv().ok(); @@ -284,154 +249,34 @@ impl BotInstance - // let bm = &mut ModulesManager::init(); - - - let b = BotInstance { prefix : prefix, bot_channel : Channel(login_name) , incoming_messages : Arc::new(RwLock::new(incoming_messages)), - //client : client, - // chat : Chat { - // ratelimiters : ratelimiters, - // client : client, - // } , botmodules : ModulesManager::init().await, twitch_oauth : oauth_token, bot_channels : botchannels, - // identity : IdentityManager::init(), botmgrs : BotManagers::init(ratelimiters,client), }; - //println!("{:?}",b.botmgrs.chat.ratelimiters); - - - // Arc::new(b) - //Arc::new(RwLock::new(b)) b } - // async fn rcv_helper(self) -> Option { - // // self.incoming_messages.get_mut().recv().await - // let mut a = self.incoming_messages; - // a.get_mut().recv().await - // } - - // pub async fn runner(mut self) -> () { - // pub async fn runner(&'static mut self) -> () { pub async fn runner(self) -> () { - // let bot_am = Arc::new(Mutex::new(self)); - - // let mut boxed_bot = Arc::new(RefCell::new(self)); // <-- [ERROR] Future cannot be handled safely - let bot = Arc::new(RwLock::new(self)); let join_handle = tokio::spawn(async move { - // let boxed_bot = Arc::new(Mutex::new(self)); - // let mut boxed_bot = Arc::new(self); - // let bot = Rc::new(RefCell::new(self)); - // let mut bot = Rc::new(RefCell::new(&self)); - //let bot = Arc::new(Mutex::new(&self)); - // let mut boxed_bot = Arc::new(RefCell::new(self)); - // let mut boxed_bot = Arc::new(Mutex::new(self)); - - // while let Some(message) = bot.borrow_mut().incoming_messages.recv().await { - - // let bot = Arc::clone(&botinit); - - // while let Some(message) = bot.lock().unwrap().incoming_messages.recv().await { - //let b = Arc::clone(&bot); - - // let mut bot = RefCell::new(&self); - - // let mut bota = bot.clone().borrow(); - - // let boxed_bot = Rc::new(RefCell::new(self)); - // let boxed_bot = Rc::new(self); - // let boxed_bot = Pin::new(Rc::new(self)); - //let mut boxed_bot = Rc::new(RefCell::new(self)); - // let mut a = (*boxed_bot).clone().into_inner(); - // let mut a = Rc::clone(&boxed_bot).borrow_mut(); - //let mut a = Rc::>>::Borrow(Rc::clone(&boxed_bot)); - - - // while let Some(message) = Rc::clone(&boxed_bot).into_inner().incoming_messages.recv().await { - // while let Some(message) = Rc::::borrow(Rc::::as_ref(boxed_bot)) { - - // let a = boxed_bot.borrow(); - - // let boxed_bota = boxed_bot.borrow_mut(); - - // let a = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner(); - - // let boxed_bot = RefCell::new(Rc::new(self)); - //let boxed_bot = Rc::new(RefCell::new(self)); - // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await; - - // let a:Borrowed = boxed_bot.borrow(); - // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await { - // while let Some(message) = RefCell::new(self).borrow_mut().incoming_messages.recv().await { - // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await { - // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().rcv_helper().await { - // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { - // let mut a = Arc::try_unwrap(boxed_bot.clone()) - // .ok().unwrap() - // .into_inner() - // .ok().unwrap(); - // let a = Arc::clone(&boxed_bot).into_inner().unwrap().incoming_messages; - // .into_inner() - // .try_into(). - // .ok().unwrap(); - // while let Some(message) = a.lock().unwrap().incoming_messages.recv().await { - // while let Some(message) = a.recv().await { - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // let mut a = Arc::try_unwrap(boxed_bot.clone()) - // .ok() - // .unwrap(); - // .into_inner() - // .get_mut() - // .ok(); - // .unwrap(); - //let mut a = a.lock().unwrap(); - // let a = *a; - // while let Some(message) = a.lock().ok().unwrap().incoming_messages.recv().await { - // while let Some(message) = a.get_mut().expect("Error").incoming_messages.recv().await { - //let tempbot = boxed_bot.clone(); - // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().ok().unwrap().incoming_messages.recv().await { - // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().incoming_messages.recv().await { - // while let Some(message) = boxed_bot.to_owned().incoming_messages.recv().await { - // while let Some(message) = self.incoming_messages.recv().await { - // let a:Arc> = Arc::clone(&boxed_bot); - // while let Some(message) = a.incoming_messages.recv().await { - // let a = Arc::clone(&boxed_bot).into_inner(); - // while let Some(message) = a.incoming_messages.recv().await { - // let tempbot = boxed_bot.clone(); - // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await { - - // let tempbot = Arc::clone(&boxed_bot); - - // while let Some(message) = tempbot.lock().await.incoming_messages.recv().await { let a = bot.read().await; let mut a = a.incoming_messages.write().await; while let Some(message) = a.recv().await { - // while let Some(message) = tempbot.into_inner().incoming_messages.recv().await { - //while let Some(message) = boxed_bot.borrow().incoming_messages.recv().await { - // // Below can be used to debug if I want to capture all messages - // println!("Received message: {:?}", message); - - // let boxed_bot = Arc::new(self); - match message { ServerMessage::Notice(msg) => { - // if let Some(chnl) = msg.channel_login { - // println!("NOTICE : (#{}) {}", chnl, msg.message_text); - // } + match &msg.channel_login { Some(chnl) => println!("NOTICE : (#{}) {}", chnl, msg.message_text), None => println!("NOTICE : {}", msg.message_text), @@ -442,59 +287,8 @@ impl BotInstance println!("Privmsg section"); - // b.listener_main_prvmsg(&msg); - // self.listener_main_prvmsg(&msg).await; - // bot.into_inner().listener_main_prvmsg(&msg).await; - //let bot = Rc::>::clone(&bot); - - // bot.borrow().listener_main_prvmsg(&msg).await; - // let mut a = Rc::Clone(&bot); - // a.borrow_mut().listener_main_prvmsg(&msg).await; - // bot.borrow_mut().into_inner().listener_main_prvmsg(&msg).await; - // bot.listener_main_prvmsg(&msg).await; - // bot.lock().unwrap().listener_main_prvmsg(&msg).await; - // bot.borrow_mut().listener_main_prvmsg(&msg).await; - // Rc::clone(&boxed_bot).into_inner().listener_main_prvmsg(&msg).await; - // boxed_bot.borrow().listener_main_prvmsg(&msg).await; - // let bottemp = boxed_bot.borrow_mut(); - // let a = **bottemp; - // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await; - // Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await; - // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().ok().unwrap().listener_main_prvmsg(&msg).await; - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // let mut a = a.lock().unwrap(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // a.listener_main_prvmsg(&msg).await; - - // (*a).listener_main_prvmsg(&msg).await; - // let a:Arc> = Arc::clone(&boxed_bot); - // a.into_inner().listener_main_prvmsg(&msg).await; - // let tempbot = boxed_bot.clone(); - // Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await ; - - // let tempbot = Arc::clone(&tempbot); - // // let a = tempbot.lock().await; - // tempbot.lock().await.listener_main_prvmsg(&msg).await; - // self.listener_main_prvmsg(&msg).await; - // bot.read().await.listener_main_prvmsg(&msg).await; - - // let a = bot.read().await; - // a.listener_main_prvmsg(&msg).await; - // a.listener_main_prvmsg(&msg).await; - // let a = bot.read().await; BotInstance::listener_main_prvmsg(Arc::clone(&bot), &msg).await; - // let a = bot.read().await; - // a.lis - - - - - //self.listener_main_prvmsg(&msg).await; - - // - BotCommand listener should likely need to be called within the above - - }, ServerMessage::Whisper(msg) => { println!("(w) {}: {}", msg.sender.name, msg.message_text); @@ -522,105 +316,31 @@ impl BotInstance pub fn get_botmodules(self) -> Arc { - // let a = self.botmodules; - // Arc::clone(&Arc::new(Mutex::new(self.botmodules))) - // *self.botmodules + self.botmodules - } - - // pub fn get_botactions(self:&Self) -> (Self,HashMap>) { - // // self.get_botactions() - // // (*self,(*self).botmodules.rbotactions()) - // (Self { bot_channel},(*self).botmodules.rbotactions()) - // } - - // pub fn get_botactions(&self) -> (Self,HashMap>) { - // pub fn get_botactions(&self) -> HashMap> { - // // self.get_botactions() - // // (*self,(*self).botmodules.rbotactions()) - // // (self,self.botmodules.rbotactions()) - // // (*self).botmodules.rbotactions() - // // let a = (*self).botmodules.rbotactions(); - // let a = - // a - // } + } pub async fn get_botmgrs(self) -> BotManagers { - // Arc::new(self.botmgrs) - // Arc::clone(&Arc::new(Mutex::new(self.botmgrs))) let a = self.botmgrs; - // let a = *a.lock().await; - // let a = a.rIdentity(); a } - // pub fn get_identity(self:&Self) -> (Self,IdentityManager) { pub fn get_identity(&self) -> Arc> { - // // let a = self.botmgrs; - // // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) - // // let a = self.botmgrs; - // // Arc::clone(&Arc::new(Mutex::new(a.rIdentity()))) - // let a = self.get_botmgrs().await; - // let a = a.lock().await; - // // let a = a.rIdentity(); - // let a = a.clone().identity; - // a.clone() - // let id = (*self).botmgrs.identity; - // id Arc::clone(&self.botmgrs.identity) } - // pub fn get_prefix(self) -> (Self,char) { pub fn get_prefix(&self) -> char { - // self.prefix.to_string() - // let a = self.prefix; - // a.clone().to_string() - // (self,self.prefix) (*self).prefix } - // pub fn get_prefix(self:&Self) -> (Self,String) { - // (*self,(*self).prefix.to_string()) - // } - // pub fn get_prefix(self:Self) -> (Self,String) { - // let str1 = self.prefix.to_string(); - // (self,str1) - // } - - // pub fn get_prefix(&self) -> String { - // // self.prefix.to_string() - // let a = self.prefix; - // a.clone().to_string() - // } - - // pub fn get_prefix(self) -> (Self,String) { - // // self.prefix.to_string() - // // let a = self.prefix; - // // a.clone().to_string() - // (Self { - // prefix : self.prefix , - // bot_channel : self.bot_channel , - // incoming_messages : self.incoming_messages , - // botmodules : self.botmodules, - // twitch_oauth : self.twitch_oauth, - // bot_channels : self.bot_channels , - // // identity : IdentityManager::init(), - // botmgrs: self.botmgrs , - // }, - // self.prefix.to_string()) - // } // ----------------- // PRIVATE FUNCTIONS - // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () { - // async fn listener_main_prvmsg(&mut self,msg:&PrivmsgMessage) -> () { - // async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () { - // async fn listener_main_prvmsg(self:Arc,msg:&PrivmsgMessage) -> () { pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { println!(">> Inner listenermain_prvmsg()"); @@ -629,51 +349,6 @@ impl BotInstance // // [ ] 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 botmgr = Rc::new(&self.botmgrs); - - // let mut boxedbot = Rc::new(RefCell::new(self)); - // let boxed_bot = Rc::new(RefCell::new(self)); - // let boxed_bot = Arc::new(Mutex::new(self)); - // let boxed_bot = Arc::new(self); - //let boxed_bot = Arc::clone(self); - // let mut boxed_bot = Arc::new(RefCell::new(self)); - // let mut boxed_bot = Arc::new(RwLock::new(self)); - // let boxed_bot = Arc::new(RwLock::new(self)); - // let boxed_bot = Arc::new(Mutex::new(self)); - //let boxed_bot = Arc::new(Mutex::new(self)); - // let bot = Arc::new(RwLock::new(self)); - - - // for (_m,acts) in &self.botmodules.botactions { - // for (_m,acts) in &self.botmodules.botactions { - // for (_m,acts) in bot.into_inner().botmodules.botactions { - // let mut bot = Rc::clone(&bot); - // for (_m,acts) in bot.into_inner().botmodules.botactions { - // for (_m,acts) in bot.into_inner().botmodules.botactions { - // for (_m,acts) in Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions { - // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().botmodules.botactions { - // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().botmodules.botactions { - // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions { - // let a = Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmodules.botactions - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // let b = a.read().unwrap(); - // for (_m,acts) in a.read().unwrap().botmodules.botactions { - // for (_m,acts) in b.rbotmodules().botactions { - // for (_m,acts) in b.rbotactions() { - // for (_m,acts) in (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).rbotactions() { - // let a = boxed_bot.clone().into_inner(); - // let a = boxed_bot.lock().await; - //let a = a.lock().in - // for (_m,acts) in self.rbotactions() { - // for (_m,acts) in a.read().ok().unwrap().rbotactions() { - // for (_m,acts) in a.into_inner().ok().unwrap().rbotactions() { - - // let bot = self; - // let mut instr:char; - - // let hacts = self.get_botactions(); - // let hacts = boxed_bot.clone().lock().await.get_botactions(); - // let hacts = bot.read().await.get_botactions(); let botlock = bot.read().await; let hacts = Arc::clone(&botlock.botmodules.botactions); // let hacts = hacts.read().await; @@ -681,9 +356,7 @@ impl BotInstance println!("hacts size : {}",(*a).len()); println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); - // println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions : {:?}",*hacts); - // let hacts = hacts - // let l = *hacts; + for (_m,acts) in &*hacts.read().await { println!(">> Inner listenermain_prvmsg() >> checking bot actions"); @@ -725,28 +398,6 @@ impl BotInstance let mut confirmed_bot_command = false; - // if inpt == self.prefix.to_string() + c.command.as_str() { - // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + c.command.as_str() { - // let a = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()); - // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).prefix.to_string(); - // let a = self.prefix.to_string(); - // let a = boxed_bot.clone(); - - // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() { - // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() - // let a = boxed_bot.lock().await; - // - // if inpt == a.into_inner().prefix.to_string() + c.command.as_str() { - // if inpt == a.get_prefix() + c.command.as_str() { - // if inpt == self.get_prefix() + c.command.as_str() { - // let instr = self.get_prefix(); - // let instr = boxed_bot.clone().lock().await.get_prefix(); - // let instr = bot.read().await.get_prefix(); let instr = bot.read().await.get_prefix(); if inpt == String::from(instr) + c.command.as_str() { confirmed_bot_command = true; @@ -754,23 +405,7 @@ impl BotInstance // [x] prefix + alias for alias in &c.alias { - // if inpt == self.prefix.to_string() + alias.as_str() { - // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + alias.as_str() { - // - // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string() + alias.as_str() { - // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner() - // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string() + alias.as_str() { - // if inpt == Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().prefix.to_string() + alias.as_str() { - // if inpt == self.prefix.to_string() + alias.as_str() { - // let a = boxed_bot.clone(); - // let a = boxed_bot.lock().await; - // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + alias.as_str() { - // if inpt == a.into_inner().prefix.to_string() + alias.as_str() { - // if inpt == a.get_prefix() + alias.as_str() { - // if inpt == self.get_prefix() + alias.as_str() { - // let instr = self.get_prefix(); - // let instr = boxed_bot.clone().lock().await.get_prefix(); - // let instr = bot.read().await.get_prefix(); + let instr = bot.read().await.get_prefix(); if inpt == String::from(instr) + alias.as_str() { confirmed_bot_command = true; @@ -779,72 +414,12 @@ impl BotInstance if confirmed_bot_command { println!("Confirmed bot command"); - // self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()); - // [ ] Around here, validate if permissable before executing - // match self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // Ok(Permissible::Allow) => c.execute(self.chat.clone(), msg.clone()).await, - // Ok(Permissible::Block) => println!("User Not allowed to run command"), - // _ => (), - // } - - // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - - // let botref = Rc::clone(&botmgr); - // if let Rc(botmgr) = botref { - // () - // } - - // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match boxed_bot.clone().into_inner().botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - //let boxed_bot1 = Arc::clone(&boxed_bot); - //let a = boxed_bot1.into_inner().ok().unwrap(); - // match boxed_bot1.into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match Arc::try_unwrap(boxed_bot.clone()) - // .ok() - // .unwrap().into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner(); - // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap(); - // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner() - // match a.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // match (boxed_bot.clone().into_inner().ok().unwrap()).botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) { - // let a = boxed_bot.clone(); - // let a = boxed_bot.lock().await; - // // let a = a.read().ok().unwrap().botmgrs.identity; - // let a = a.get_identity(); - // // let a = a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()) ; - - // match a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await { - - - // let le = boxed_bot.lock().await; - // // let le = le.lock().await; - // let le = le.get_identity().await; - // let le = *le; - // let le = le.lock().await; - // let le = le.clone(); - // let le = le.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; - // let le = self.get_identity().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; - // let le = self.botmgrs; - // let le = le.identity; - // let (bot,id) = self.get_identity(); - // let id = boxed_bot.clone().lock().await.get_identity(); - // let id = bot.read().await.get_identity(); - // let id = Arc::clone(&self.botmgrs.identity); - // let id = id.write().await; - // let id = &(*self.get_identity()); println!("Going for botlock"); let botlock = bot.read().await; println!("Going for identity"); let id = botlock.get_identity(); - // let mut id = id.write().await; - // println!("Unlocking identity"); - // let eval= id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await; + let eval = { let mut id = id.write().await; println!("Unlocking identity"); @@ -852,22 +427,9 @@ impl BotInstance }; println!("Checking if permissible"); match eval { - // Ok(Permissible::Allow) => (), Permissible::Allow => { println!("Executed as permissible"); - // c.execute(bot, msg.clone()).await; - // if let bot = Rc::>::clone(*bot) { - // c.execute(bot, msg.clone()).await; - // } - // let boxed_bot = Arc::new(RwLock::new(self)); - // c.execute(boxed_bot.clone(), msg.clone()).await; - // c.execute(self, msg.clone()).await; - //let mut a = *self; - // c.execute(self, msg.clone()); - // let a = self; - // let a = Arc::clone(&self); let a = Arc::clone(&bot); - // let a = Arc::clone(&bot); c.execute(a, msg.clone()).await; println!("exit out of execution"); @@ -879,21 +441,12 @@ impl BotInstance }; }; - // c.execute(self.chat.clone(), msg.clone()).await; } - // None::<&PrivmsgMessage> // [ ] Command not confirmed? + }, crate::core::botmodules::BotAction::L(l) => { - // if let bot = Rc::clone(&bot) { - // l.into_inner().execute(bot, msg.clone()).await - // } - //let bot = Rc::clone(&bot).into_inner(); - // l.execute(boxed_bot.clone(), msg.clone()).await - // let boxed_bot = Arc::new(RwLock::new(self)); - // l.execute(boxed_bot.clone(), msg.clone()).await; - // let a = Arc::clone(&self); let a = Arc::clone(&bot); l.execute(a, msg.clone()).await; }, @@ -904,7 +457,6 @@ impl BotInstance }; - // // [ ] There should be a BotCommand Listener to check for prefixes ran println!("End of Separate Listener Main prvmsg"); diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index bbc9f66..20698cf 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -88,7 +88,7 @@ pub enum BotAction } impl BotAction { - // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ + pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { @@ -105,7 +105,6 @@ impl BotAction { pub trait BotActionTrait { async fn add_to_bot(self, bot:BotInstance); - // async fn add_to_modmgr(self,modmgr:&'static ModulesManager); async fn add_to_modmgr(self,modmgr:Arc); } @@ -122,20 +121,8 @@ pub struct BotCommand { impl BotCommand { - // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){ - // pub async fn execute(&self,m:Rc<&botinstance::BotManagers>,n:PrivmsgMessage){ - // pub async fn execute(&self,m:BotInstance,n:PrivmsgMessage){ - // (self.exec_body)(m,n).await; - // } - // pub fn execute(&self,m:&mut BotInstance,n:PrivmsgMessage) -> () { - // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { - // ((*self).exec_body)(m,n); - // ((*self).exec_body)(*m,n); - // m - // ((*self).exec_body)( ((*self).exec_body)(m,n).await; - // m } } @@ -143,18 +130,11 @@ impl BotCommand impl BotActionTrait for BotCommand { async fn add_to_bot(self, bot:BotInstance) { - // let mgr = &mut bot.botmodules; - // let mut mgr = *mgr.lock().await; - // let mut mgr = &mut mgr; - // (*self).add_to_modmgr(bot.botmodules); 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)) - // let modmgr = *modmgr.lock().await; - // modmgr.add_botaction(self.module.clone(), BotAction::C(self)) modmgr.add_botaction(self.module.clone(), BotAction::C(self)).await } @@ -183,55 +163,10 @@ pub mod bot_actions { pub type BotAM = Arc>; pub type BotAR = Arc>; - - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - //pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box>,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box Pin + Send>> + Send + Sync>; - pub type ExecBody = Box Pin + Send>> + Send + Sync>; - // pub type ExecBody = Box,PrivmsgMessage) -> Pin + Send>> + Send + Sync>; - + pub type ExecBody = Box Pin + Send>> + Send + Sync>; - - //pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Rc<&BotManagers>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc<&BotInstance>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Rc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(Arc>,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(BotInstance,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(&'static BotInstance,PrivmsgMessage) -> T) -> ExecBody - // pub fn asyncbox(f: fn(&mut BotInstance,PrivmsgMessage) -> T) -> ExecBody pub fn asyncbox(f: fn(BotAR,PrivmsgMessage) -> T) -> ExecBody where - //T: Future + Send + 'static - // T: Future + Send + 'static T: Future + Send + 'static { Box::new(move |a,b| Box::pin(f(a,b))) @@ -253,19 +188,9 @@ pub struct Listener impl Listener { - // pub async fn execute(&self,m:BotInstance,n:PrivmsgMessage){ - // (self.exec_body)(m,n).await; - // } - // pub fn execute(&self,m:BotInstance,n:PrivmsgMessage){ - // (self.exec_body)(m,n); - // } - // pub fn execute(&self,m:&BotInstance,n:PrivmsgMessage) -> &BotInstance { - // pub fn execute(&self,m:actions_util::BotAR,n:PrivmsgMessage) -> () { + pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { - // let mut m = Arc::*m; ((*self).exec_body)(m,n).await; - // *self - // &m } } @@ -274,22 +199,14 @@ impl BotActionTrait for Listener { async fn add_to_bot(self, bot:BotInstance) { - // let mgr = &mut bot.botmodules; - // let mgr = bot.botmodules; - // self.add_to_modmgr(Arc::new(*mgr)); println!("Adding action to bot"); self.add_to_modmgr(bot.botmodules).await; } - // fn add_to_modmgr(self, modmgr:&mut ModulesManager) { - // async fn add_to_modmgr(self, modmgr:Arc>) { - // async fn add_to_modmgr(self, modmgr:&'static ModulesManager) { - // async fn add_to_modmgr(self, modmgr:&'static ModulesManager) { async fn add_to_modmgr(self, modmgr:Arc) { // let modmgr = *modmgr.lock().await; println!("Adding action to module manager"); modmgr.add_botaction(self.module.clone(), BotAction::L(self)).await; - // modmgr.add_botaction(self.module.clone(), BotAction:L(self)) } } @@ -303,16 +220,13 @@ struct Routine {} pub struct ModulesManager { - // statusdb: HashMap>, statusdb: Arc>>>, - // pub botactions: HashMap>, pub botactions: Arc>>>, } impl ModulesManager { - // pub fn init() -> Arc> pub async fn init() -> Arc { @@ -326,38 +240,21 @@ impl ModulesManager }; // :: [x] initialize core modules - // crate::core::identity::init(&mut mgr); - - // let a = Arc::new(Mutex::new(mgr)); - // // let a = a.clone(); - // crate::core::identity::init(a.clone()); - - // crate::core::identity::init(&mgr); + println!("ModulesManager > init() > Adding modules"); let mgra = Arc::new(mgr); crate::core::identity::init(Arc::clone(&mgra)).await; - // initialize custom crate modules - // crate::modules::init(&mut mgr); - // let a = a.clone(); - // crate::modules::init(a.clone()); + crate::modules::init(Arc::clone(&mgra)).await; println!(">> Modules Manager : End of Init"); - // mgr mgra } - // pub async fn rbotactions(&self) -> HashMap> { - // // (*self).botactions - // let a = self.botactions.read().await; - // *a - // } - - pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { // Example usage : botmanager.modstatus( // BotModule("GambaCore"), @@ -382,9 +279,7 @@ impl ModulesManager Ok("") } - //pub fn add_botaction(mut self, in_module:ModType, in_action:BotAction ) -> ModulesManager { - // pub fn add_botaction(mut self, in_module:ModType, in_action:BotAction ) -> ModulesManager { - //pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) -> () { + pub async fn add_botaction(&self, in_module:ModType, in_action:BotAction ) { println!("Add botaction called"); /* @@ -510,14 +405,6 @@ impl ModulesManager None => (), } - // { - // let mut lala = self; - // let statusvector = (*lala).statusdb - // // .entry(BotModule(String::from("experiments"))) - // .entry(in_module.clone()) - // .or_insert(Vec::new()); - // } - let mut dbt = self.statusdb.write().await; let statusvector = dbt // .entry(BotModule(String::from("experiments"))) @@ -537,14 +424,7 @@ impl ModulesManager println!(">> Modules Manager : Called Add bot Action"); println!("add_botaction - botactions size : {}",modactions.len()); - //println!(">> Modules Manager : {:?}",&self); - - //(); - //let mgr = self; - - //mgr - - //self + } diff --git a/src/core/identity.rs b/src/core/identity.rs index 8bc3ce6..477a9e5 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -54,8 +54,6 @@ pub async fn init(mgr:Arc) tempb.add_to_modmgr(Arc::clone(&mgr)).await; - // async fn cmd_promote(mut bot:Arc>,msg:PrivmsgMessage) - // async fn cmd_promote(mut bot:&BotInstance,msg:PrivmsgMessage) -> &BotInstance async fn cmd_promote(bot:BotAR,msg:PrivmsgMessage) -> () { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -88,7 +86,6 @@ pub async fn init(mgr:Arc) */ - //let bot = Rcbot; println!("{}",msg.message_text); let mut argv = msg.message_text.split(" "); @@ -113,42 +110,7 @@ pub async fn init(mgr:Arc) match arg1 { Some(a1) if a1 == String::from("admin") => { // - BotAdmins can promote admin to give BotAdmin UserRole - //let mut bot = Rc::clone(&bot); - // let a = bot.botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); - // let a = Rc::try_unwrap(bot).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); - // let a = Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); - // let a = Rc::try_unwrap(bot).ok().unwrap() - // // .borrow_mut() - // .into_inner() - // .botmgrs - // .identity - // .getspecialuserroles(msg.sender.name.to_lowercase(), - // Some(ChType::Channel(msg.channel_login.to_lowercase()))); - // let p = Rc::try_unwrap(bot.clone()) - // let p = Arc::try_unwrap(bot.clone()) - // .ok() - // .unwrap() - // //.into_inner() - // //.to_owned() - // // .get_mut() - // .into_inner(); - // // .ok() - // // .unwrap(); - // // let p = p.ok().unwrap(); - - // let p = bot.lock().await.get_identity(); - // let p = p.lock().await; - // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - // // let ta = *ta.await; - // let ta = *ta.lock().await; - - // if let Some(a) = ta { - - - // let p = bot.lock().await.get_identity(); - // let mut p = p.lock().await; - // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; let botlock = bot.read().await; let ta = botlock.get_identity(); let ta = ta.read().await; @@ -161,60 +123,14 @@ pub async fn init(mgr:Arc) if a.contains(&UserRole::BotAdmin) { println!("BotAdmin allowed to promote admin"); - // let bota = Rc::clone(&bot); - // let bota = Rc::get_mut(&bota); - // match bota.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - //let mut bot = Rc::clone(&bot); - // let bot = Rc::<&botinstance::BotInstance>::get_mut(&mut bot); - // let mut bot = Rc::make_mut(&mut bot); - // let mut bot = Rc::make_mut(&bot); - // match Rc::<&botinstance::BotInstance>::get_mut(bot) { - // Some(bot) => { - // match bot.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // // Success(_) => { - // // ; - // // }, - // ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), - // ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), - // ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), - - // } - // }, - // None => (), - // } - //let bot = Rc::::make_mut(bot); - // match Rc::::make_mut(&mut Rc::new(bot.botmgrs.identity)).promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // match Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().ok().unwrap().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // match bot.read().ok().unwrap().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // let a = bot.get_mut(); - // match a.get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // let a = (*bot).clone(); { - // let a = bot.lock().await.get_botmgrs().clone(); - // let a = bot.lock().await; - // let mut mutex = Arc::clone(&bot); - // match mutex.get_mut().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) { - // slet ee = ArcBox(bot); - // println!("tester: {:?}",(*bot).lock().await.get_prefix()); - // let mutex = Arc::clone(&bot); - // let mut mutex2 = Arc::new(*mutex).into_inner().get_identity(); - // let mut mutex2 = Arc::clone(&mutex).into_inner().get_identity(); - // let a = (*bot).lock().await.get_identity(); - // let mut a = a.lock().await; - // let p = bot.lock().await.get_identity(); - // let mut p = p.lock().await; - // let ta = p.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + let botlock = Arc::clone(&bot.read().await.get_identity()); let idlock = botlock.write().await; // let mut idlock = *idlock; let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; match ta { - // Success(_) => { - // ; - // }, ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), @@ -223,38 +139,18 @@ pub async fn init(mgr:Arc) } } } - - // }, - // Some(_) => { - // // - - + // }, _ => (), } - // match String::from(arg1) { - // a if a == String::from("admin") => (), - // _ => (), - // } - - - // match argv[1] { - // String::from("admin") => (), - - // } - let arg2 = argv.next(); let targetchnl = arg2; - - // bot - - - } // BotCommand { @@ -888,38 +784,9 @@ impl IdentityManager { Note : Ideally this be called for a given chatter name ? */ - // let a = chattername.to_lowercase(); - - // self.special_roles_users.get(&a) - - - - // for k in self.special_roles_users.keys() { - // println!("Special Roles Keys {k}"); - // for v in - // } - - // for (k,v) in &self.special_roles_users { - // println!("User {k}"); - // println!("> Roles : {:?}",v); - // } let chattername = chattername.to_lowercase(); - // println!("{a}"); - - // let b = self.special_roles_users.lock().await.get(&a); - // match b - // { - // Some(b) => Some(*b), - // None => None, - // } - // println!("Write Lock on Special Roles @ Getspecialuserroles()"); - // let b = self.special_roles_users.write().await.remove(&a); - // let outp = b; - // // let b = Arc::new(Mutex::new(outp)); - // outp - let rolesa = Arc::clone(&self.special_roles_users); let a = rolesa.read().await; @@ -933,14 +800,6 @@ impl IdentityManager { } - // Arc::new(RwLock::new(outr)) - - // let b = Arc::new(Mutex::new(b)); - // b - - - - // Some(vec![UserRole::Mod(ChType::Channel(String::from("modulatingforcebot")))]) } diff --git a/src/modules.rs b/src/modules.rs index 651ea38..49f3583 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -20,13 +20,6 @@ mod experiments; // [ ] init() function that accepts bot instance - this is passed to init() on submodules -// pub fn init(mgr:ModulesManager) -> ModulesManager -// pub fn init(mgr:ModulesManager) -// where -// // F: std::future::Future + Send, -// // F : Send, -// F : Send + ?Sized, -// pub fn init(mgr:&mut ModulesManager) pub async fn init(mgr:Arc) { // Modules initializer loads modules into the bot diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index f7968c9..000f72a 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -86,56 +86,16 @@ async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) // - 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 - //let mut rng = thread_rng(); - // let roll = rand::thread_rng().gen_range(1..=5); - - // let mut bot = Rc::clone(&bot); - // let mut bot = Rc::get_mut(&mut bot); - // let bot = match bot { - // Some(bot) => bot, - // None => (), - // } - - - - if msg.sender.name == "ModulatingForce" // && msg.message_text.contains("GoodGirl") + if msg.sender.name == "ModulatingForce" || msg.sender.name == "mzNToRi" // && 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"); - let rollwin = rand::thread_rng().gen_ratio(1,5); + let rollwin = rand::thread_rng().gen_ratio(1,10); if rollwin { println!("In GoodGirl() > Win"); - // let bot = Rc::get_mut(&bot).expect("Error"); - // bot.botmgrs.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; - // Rc::::get_mut(mut bot) - // if let Some(bot) = Rc::<&botinstance::BotInstance>::get_mut(bot) { - - // match bot{ - // Some(bot) => { - // bot - // .botmgrs - // .chat - // .say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await; - // } - // None => (), - // } - // Arc::try_unwrap(bot).ok().unwrap().botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; - // let a = bot.clone(); let a = Arc::clone(&bot); - // let a = a.read().ok().unwrap(); - // let a = a.lock().await.get_botmgrs(); - // let a = a.lock().await.rChat(); - - // let a = (*bot).lock().await.get_botmgrs(); - // let a = a.lock().await.rChat(); - // let mut a = (*a).lock().await; - // let a = a.botmgrs.chat.say_in_reply_to(&msg, outmsg) - - // a.rbotmgrs().chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; - // a.lock().await.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; - // a.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; let botlock = a.read().await; botlock.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; } -- 2.46.1 From 017d2426d22c2b99263344b050ead541a07830b6 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:27:52 -0500 Subject: [PATCH 26/39] mods are auto given mod user role --- src/core/identity.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 477a9e5..2ea8669 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -585,7 +585,15 @@ impl IdentityManager { } }, - _ => ( ) // <-- I'm assuming problem got to here + _ => { + println!("lock created > adding with a mod role o7"); + roleslock.get_mut(&usr.to_lowercase()) + // .expect("ERROR") + .unwrap() + .write().await + // .get_mut() + .push(UserRole::Mod(channelname.clone())); + }// <-- I'm assuming problem got to here } }, -- 2.46.1 From b78a2cd2b93bfec19857c177b4c331163e01a605 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:32:53 -0500 Subject: [PATCH 27/39] reorg can_user_run inner code --- src/core/identity.rs | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 2ea8669..d60a6d5 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -558,33 +558,27 @@ impl IdentityManager { println!("Read lock on : Special_Roles_User"); // <-- after this is slightly different between working and problem let mut roleslock = roleslock.write().await; match (*roleslock).get(&usr.to_lowercase()) { - Some(usrroles) => { // <-- 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()))); - if usrroles.read().await.contains(&UserRole::Mod(channelname.clone())) || - usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())) { + 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()))); + // if usrroles.read().await.contains(&UserRole::Mod(channelname.clone())) || + // usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())) { // Do nothing - this is expected println!("Already a mod in roles"); - } else { - // in this case, they have a ChatBadge::Mod but should have this for the channel - // let mut a = usrroles; - // usrroles.push(UserRole::Mod(channelname.clone())); - // a.push(UserRole::Mod(channelname.clone())); - println!("Was in the else loop"); - // let a = &*self; // let mut lock = a.special_roles_users.write().await; - println!("lock created > adding with a mod role o7"); - roleslock.get_mut(&usr.to_lowercase()) - // .expect("ERROR") - .unwrap() - .write().await - // .get_mut() - .push(UserRole::Mod(channelname.clone())); + // println!("lock created > adding with a mod role o7"); + // roleslock.get_mut(&usr.to_lowercase()) + // // .expect("ERROR") + // .unwrap() + // .write().await + // // .get_mut() + // .push(UserRole::Mod(channelname.clone())); // println!("debug special roles : {:?}",self.special_roles_users); - } - }, + } _ => { println!("lock created > adding with a mod role o7"); roleslock.get_mut(&usr.to_lowercase()) @@ -593,7 +587,7 @@ impl IdentityManager { .write().await // .get_mut() .push(UserRole::Mod(channelname.clone())); - }// <-- I'm assuming problem got to here + } // <-- I'm assuming problem got to here } }, -- 2.46.1 From eb6c5ec58c19f3f323343a40c700f1160e2414fd Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 13 Feb 2024 07:54:35 -0500 Subject: [PATCH 28/39] (init) botlog module --- .gitignore | 6 +- Cargo.lock | 171 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/core/botinstance.rs | 157 ++++++++++++++++++++++++++++------ src/core/botmodules.rs | 8 +- src/core/identity.rs | 69 ++++++++------- src/main.rs | 32 +++++-- src/modules/experiments.rs | 4 +- 8 files changed, 382 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index 188c46a..ec4d862 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,8 @@ target/ # env .envrc -.env \ No newline at end of file +.env + + +# log +.log \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1425d4b..56bc71f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,30 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "async-trait" version = "0.1.77" @@ -61,12 +85,29 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "casual_logger" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d02b2f025328b7f0a232815634c840e206350cf7c8e8fb36ab7095e264f59c" +dependencies = [ + "chrono", + "lazy_static", + "regex", +] + [[package]] name = "cc" version = "1.0.83" @@ -88,7 +129,12 @@ version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", "num-traits", + "wasm-bindgen", + "windows-targets 0.48.5", ] [[package]] @@ -152,6 +198,7 @@ name = "forcebot_rs" version = "0.1.0" dependencies = [ "async-trait", + "casual_logger", "dotenv", "futures", "rand", @@ -289,6 +336,38 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -549,6 +628,35 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -818,6 +926,69 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 0043332..3b8edd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ tokio = { version = "1.33.0", features = ["full"] } twitch-irc = "5.0.1" rand = { version = "0.8.5", features = [] } futures = "0.3" -async-trait = "0.1.77" \ No newline at end of file +async-trait = "0.1.77" +casual_logger = "0.6.5" \ No newline at end of file diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index b2c065c..b0ef047 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -33,7 +33,7 @@ use crate::core::ratelimiter; use crate::core::botmodules; use crate::core::botmodules::ModulesManager; -use crate::core::identity::{IdentityManager,Permissible}; +use crate::core::identity::{IdentityManager,Permissible,ChangeResult}; use std::rc::Rc; use std::cell::RefCell; @@ -49,6 +49,51 @@ use core::borrow::Borrow; use super::botmodules::bot_actions::actions_util::BotAR; +use casual_logger::{Level,Log}; + + +pub mod botlog { + + /* + 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 twitch_irc::message::PrivmsgMessage; + + // trace, debug, info, notice, warn, error, fatal + + fn trace(in_msg:&str,module:Option,prvmsg:Option,) -> () { + + } + + fn debug(prvmsg:Option,in_msg:&str) -> () { + + } + + fn info(prvmsg:Option,in_msg:&str) -> () { + + } + + fn notice(prvmsg:Option,in_msg:&str) -> () { + + } + + fn warn(prvmsg:Option,in_msg:&str) -> () { + + } + + fn error(prvmsg:Option,in_msg:&str) -> () { + + } + +} + + + #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum ChType { Channel(String), @@ -110,15 +155,18 @@ impl Chat { } self.client.say_in_reply_to(msg,outmsg).await.unwrap(); - println!("(#{}) > {}", msg.channel_login, "rate limit counter increase"); + // println!("(#{}) > {}", msg.channel_login, "rate limit counter increase"); + Log::trace(&format!("(#{}) > {}", msg.channel_login, "rate limit counter increase")); contextratelimiter.increment_counter(); - println!("{:?}",self.ratelimiters); + // println!("{:?}",self.ratelimiters); + Log::trace(&format!("{:?}",self.ratelimiters)); }, ratelimiter::LimiterResp::Skip => { (); // do nothing otherwise } } + Log::flush(); } async fn say(&self, _:String, _:String) -> () { @@ -278,29 +326,42 @@ impl BotInstance ServerMessage::Notice(msg) => { match &msg.channel_login { - Some(chnl) => println!("NOTICE : (#{}) {}", chnl, msg.message_text), - None => println!("NOTICE : {}", msg.message_text), + Some(chnl) => { + // println!("NOTICE : (#{}) {}", chnl, msg.message_text) + Log::notice(&format!("NOTICE : (#{}) {}", chnl, msg.message_text)); + + }, + None => { + // println!("NOTICE : {}", msg.message_text); + Log::notice(&format!("NOTICE : {}", msg.message_text)); + }, } } ServerMessage::Privmsg(msg) => { - println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); + Log::trace(&format!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text)); - println!("Privmsg section"); + // println!("Privmsg section"); + Log::debug(&format!("Privmsg section")); - BotInstance::listener_main_prvmsg(Arc::clone(&bot), &msg).await; + BotInstance::listener_main_prvmsg(Arc::clone(&bot), &msg).await; }, ServerMessage::Whisper(msg) => { - println!("(w) {}: {}", msg.sender.name, msg.message_text); + // println!("(w) {}: {}", msg.sender.name, msg.message_text); + Log::trace(&format!("(w) {}: {}", msg.sender.name, msg.message_text)); }, ServerMessage::Join(msg) => { - println!("JOINED: {}", msg.channel_login); + // println!("JOINED: {}", msg.channel_login); + Log::notice(&format!("JOINED: {}", msg.channel_login)); }, ServerMessage::Part(msg) => { - println!("PARTED: {}", msg.channel_login); + // println!("PARTED: {}", msg.channel_login); + Log::notice(&format!("PARTED: {}", msg.channel_login)); }, _ => {} - } + }; + Log::flush(); } }); @@ -342,7 +403,8 @@ impl BotInstance pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { - println!(">> Inner listenermain_prvmsg()"); + // println!(">> Inner listenermain_prvmsg()"); + Log::trace(">> Inner listenermain_prvmsg()"); // let a = a; // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); @@ -353,20 +415,24 @@ impl BotInstance let hacts = Arc::clone(&botlock.botmodules.botactions); // let hacts = hacts.read().await; let a = hacts.read().await; - println!("hacts size : {}",(*a).len()); + // println!("hacts size : {}",(*a).len()); + Log::debug(&format!("hacts size : {}",(*a).len())); - println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); + // println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); + Log::trace(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); for (_m,acts) in &*hacts.read().await { - println!(">> Inner listenermain_prvmsg() >> checking bot actions"); + // println!(">> Inner listenermain_prvmsg() >> checking bot actions"); + Log::trace(">> Inner listenermain_prvmsg() >> checking bot actions"); // let bot = bot; for a in acts { - println!(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); + // println!(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); + Log::trace(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); let _act = match a { @@ -385,7 +451,8 @@ impl BotInstance // println!("args : {v}"); // } - println!("Reviewing internal commands"); + // println!("Reviewing internal commands"); + Log::trace("Reviewing internal commands"); let inpt = msg.message_text.split("\n").next().expect("ERROR during BotCommand"); let inpt = msg.message_text.split(" ").next().expect("ERROR during BotCommand"); @@ -413,29 +480,60 @@ impl BotInstance } if confirmed_bot_command { - println!("Confirmed bot command"); + // println!("Confirmed bot command"); + Log::debug("Confirmed bot command"); - println!("Going for botlock"); + // println!("Going for botlock"); + Log::trace("Going for botlock"); let botlock = bot.read().await; - println!("Going for identity"); + // println!("Going for identity"); + Log::trace("Going for identity"); let id = botlock.get_identity(); let eval = { let mut id = id.write().await; - println!("Unlocking identity"); - id.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await + // println!("Unlocking identity"); + Log::trace("Unlocking identity"); + 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 = + // } + // } + (a,b) }; - println!("Checking if permissible"); + // println!("Checking if permissible"); + Log::trace("Checking if permissible"); + + let (eval , rolechange) = eval; + + if let ChangeResult::Success(b) = rolechange { + + if b.to_lowercase().contains(&"Auto Promoted Mod".to_lowercase()) { + // println!("Read() lock Bot"); + Log::trace("Read() lock Bot"); + 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; + } + } + match eval { Permissible::Allow => { - println!("Executed as permissible"); + // println!("Executed as permissible"); + Log::debug("Executed as permissible"); let a = Arc::clone(&bot); c.execute(a, msg.clone()).await; - println!("exit out of execution"); + // println!("exit out of execution"); + Log::trace("exit out of execution"); } Permissible::Block => { - println!("User Not allowed to run command") + // println!("User Not allowed to run command"); + Log::info("User Not allowed to run command"); }, // _ => (), }; @@ -459,11 +557,14 @@ impl BotInstance // // [ ] There should be a BotCommand Listener to check for prefixes ran - println!("End of Separate Listener Main prvmsg"); + // println!("End of Separate Listener Main prvmsg"); + Log::trace("End of Separate Listener Main prvmsg"); // self // bot + Log::flush(); + } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 20698cf..7075484 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -25,6 +25,7 @@ use std::rc::Rc; use async_trait::async_trait; +use casual_logger::{Level,Log}; /* @@ -199,13 +200,16 @@ impl BotActionTrait for Listener { async fn add_to_bot(self, bot:BotInstance) { - println!("Adding action to bot"); + // println!("Adding action to bot"); + Log::trace("Adding action to bot"); self.add_to_modmgr(bot.botmodules).await; } async fn add_to_modmgr(self, modmgr:Arc) { // let modmgr = *modmgr.lock().await; - println!("Adding action to module manager"); + // println!("Adding action to module manager"); + Log::trace("Adding action to module manager"); + modmgr.add_botaction(self.module.clone(), BotAction::L(self)).await; } diff --git a/src/core/identity.rs b/src/core/identity.rs index d60a6d5..c02e269 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -385,7 +385,7 @@ pub enum ChatBadge { } -enum ChangeResult { +pub enum ChangeResult { Success(String), Failed(String), NoChange(String), @@ -411,7 +411,7 @@ impl IdentityManager { // 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 + 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); @@ -454,6 +454,15 @@ impl IdentityManager { // 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 return self.can_user_run(msg.sender.name.to_owned(), ChType::Channel(msg.channel_login.to_owned()), sender_badge, @@ -465,7 +474,7 @@ impl IdentityManager { // [ ] Call can_user_run() // (self,Permissible::Block) - Permissible::Block + (Permissible::Block,ChangeResult::NoChange("".to_string())) } @@ -475,7 +484,8 @@ impl IdentityManager { chat_badge:ChatBadge, cmdreqroles:Vec // ) -> Result> { - ) -> Permissible { + ) -> (Permissible,ChangeResult) { + println!{"Checking within can_user_run()"}; /* canUserRun - @@ -519,10 +529,12 @@ impl IdentityManager { if cmdreqroles.len() == 0 { // return Ok(Permissible::Allow) - return Permissible::Allow + return (Permissible::Allow , ChangeResult::NoChange("Command has no required cmdreqroles".to_string())) } + let mut modrolechange = ChangeResult::NoChange("".to_string()); + match chat_badge { @@ -535,7 +547,7 @@ impl IdentityManager { cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) || cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { // return Ok(Permissible::Allow) - return Permissible::Allow + return (Permissible::Allow , ChangeResult::NoChange("Broadcaster Role".to_string())) } }, @@ -563,30 +575,29 @@ impl IdentityManager { 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()))); - // if usrroles.read().await.contains(&UserRole::Mod(channelname.clone())) || - // usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())) { - // Do nothing - this is expected + + // 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"); - // let a = &*self; - // let mut lock = a.special_roles_users.write().await; - // println!("lock created > adding with a mod role o7"); - // roleslock.get_mut(&usr.to_lowercase()) - // // .expect("ERROR") - // .unwrap() - // .write().await - // // .get_mut() - // .push(UserRole::Mod(channelname.clone())); - // println!("debug special roles : {:?}",self.special_roles_users); } _ => { + // 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"); - roleslock.get_mut(&usr.to_lowercase()) - // .expect("ERROR") - .unwrap() - .write().await - // .get_mut() - .push(UserRole::Mod(channelname.clone())); + 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 } @@ -612,7 +623,7 @@ impl IdentityManager { 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 "); - return Permissible::Allow + return (Permissible::Allow , modrolechange) } } } @@ -625,7 +636,7 @@ impl IdentityManager { 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 + return (Permissible::Allow,modrolechange) } } } @@ -641,12 +652,12 @@ impl IdentityManager { println!("special roles contains BotAdmin: {}",a.read().await.contains(&UserRole::BotAdmin)); if a.read().await.contains(&UserRole::BotAdmin) { // return Ok(Permissible::Allow); - return Permissible::Allow + return (Permissible::Allow,modrolechange) } } } - Permissible::Block + (Permissible::Block , ChangeResult::NoChange("Not any permissiable condition".to_string())) } // pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { diff --git a/src/main.rs b/src/main.rs index 7847da3..07e4a13 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,15 +7,23 @@ use std::process::Output; use crate::core::botinstance::ArcBox; use crate::core::botinstance::BotInstance; +use casual_logger::Extension; use tokio::sync::RwLock; use std::sync::Arc; pub type BotAR = Arc>; +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); + let bot = BotInstance::init().await; + Log::debug("Checking bot actions"); let a = Arc::clone(&bot.botmodules.botactions); let a = a.read().await; // let a = *a; @@ -23,18 +31,32 @@ pub async fn main() { for (_,acts) in &*a { for act in acts { match act { - crate::core::botmodules::BotAction::C(b) => println!("bot actiions: {}",b.command), - crate::core::botmodules::BotAction::L(l) => println!("bot actiions: {}",l.name), - _ => println!("Not a valid match??"), + crate::core::botmodules::BotAction::C(b) => { + // println!("bot actiions: {}",b.command) + Log::info(&format!("bot actions: {}",b.command)); + }, + crate::core::botmodules::BotAction::L(l) => { + // println!("bot actiions: {}",l.name) + Log::info(&format!("bot actions: {}",l.name)); + }, + _ => { + // println!("Not a valid match??") + Log::info("Not a valid match??"); + }, } } }; - println!("Starting runner.."); + // println!("Starting runner.."); + Log::notice("Starting Bot Runner"); + + Log::flush(); bot.runner().await; - println!("ERROR : EXIT Game loop"); + // println!("ERROR : EXIT Game loop"); + // let msg = Log::fatal("ERROR : EXIT Game loop"); + panic!("{}",Log::fatal("ERROR : EXIT Game loop")); } \ No newline at end of file diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 000f72a..f63192c 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -87,12 +87,12 @@ async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) // - More Info : https://rust-random.github.io/rand/rand/trait.Rng.html#method.gen_ratio - if msg.sender.name == "ModulatingForce" || msg.sender.name == "mzNToRi" // && 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"); - let rollwin = rand::thread_rng().gen_ratio(1,10); + let rollwin = rand::thread_rng().gen_ratio(1,8); if rollwin { println!("In GoodGirl() > Win"); let a = Arc::clone(&bot); -- 2.46.1 From fd80921ebb8ca630f117315942697c35f422583f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 13 Feb 2024 07:56:11 -0500 Subject: [PATCH 29/39] gitignore log --- .gitignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ec4d862..c8270c9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,9 @@ target/ /target # env -.envrc -.env +*.envrc +*.env # log -.log \ No newline at end of file +*.log \ No newline at end of file -- 2.46.1 From 51d5db3f4e4545788908210c38ba75be4dc92374 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:11:49 -0500 Subject: [PATCH 30/39] (cont) botlog module --- src/core/botinstance.rs | 283 ++++++++++++++++++++++++++++++++----- src/core/botmodules.rs | 45 ++++-- src/core/identity.rs | 114 +++++++++++---- src/main.rs | 22 ++- src/modules/experiments.rs | 25 +++- 5 files changed, 411 insertions(+), 78 deletions(-) diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index b0ef047..7823673 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -57,7 +57,7 @@ pub mod botlog { /* Module intends to add some layers to logging with the module user only requiring to pass : - String Log message - - Option - Code Module + - Option - Code_Module - Option - this is used to parse out Chatter & Channel into the logs */ @@ -66,28 +66,160 @@ pub mod botlog { // trace, debug, info, notice, warn, error, fatal - fn trace(in_msg:&str,module:Option,prvmsg:Option,) -> () { + 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) + } + }; + + Log::trace_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); } - fn debug(prvmsg:Option,in_msg:&str) -> () { + 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) + } + }; + + Log::debug_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); } - fn info(prvmsg:Option,in_msg:&str) -> () { + 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) + } + }; + + Log::info_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); } - fn notice(prvmsg:Option,in_msg:&str) -> () { + 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) + } + }; + + Log::notice_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); } - fn warn(prvmsg:Option,in_msg:&str) -> () { + 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) + } + }; + + Log::warn_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); } - fn error(prvmsg:Option,in_msg:&str) -> () { + 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) + } + }; + + Log::error_t( + in_msg, + casual_logger::Table::default() // + .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 { + 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) + } + }; + + Log::fatal_t( + in_msg, + casual_logger::Table::default() // + .str("Channel",&format!("{:?}",chnl)) + .str("Chatter",&format!("{:?}",chatter)) + .str("Code_Module",&format!("{:?}",in_module)) + ); + + in_msg } } @@ -156,10 +288,16 @@ impl Chat { 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")); + // 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)); contextratelimiter.increment_counter(); // println!("{:?}",self.ratelimiters); - Log::trace(&format!("{:?}",self.ratelimiters)); + // Log::trace(&format!("{:?}",self.ratelimiters)); + botlog::trace(&format!("{:?}",self.ratelimiters), + Some("Chat > say_in_reply_to".to_string()) , + Some(&msg)); }, ratelimiter::LimiterResp::Skip => { (); // do nothing otherwise @@ -328,36 +466,57 @@ impl BotInstance match &msg.channel_login { Some(chnl) => { // println!("NOTICE : (#{}) {}", chnl, msg.message_text) - Log::notice(&format!("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); }, None => { // println!("NOTICE : {}", msg.message_text); - Log::notice(&format!("NOTICE : {}", msg.message_text)); + // Log::notice(&format!("NOTICE : {}", msg.message_text)); + 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)); + // 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)); // println!("Privmsg section"); - Log::debug(&format!("Privmsg section")); + // Log::debug(&format!("Privmsg section")); + 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)); + // 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); }, ServerMessage::Join(msg) => { // println!("JOINED: {}", msg.channel_login); - Log::notice(&format!("JOINED: {}", msg.channel_login)); + // Log::notice(&format!("JOINED: {}", msg.channel_login)); + 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)); + // Log::notice(&format!("PARTED: {}", msg.channel_login)); + botlog::notice(&format!("PARTED: {}", msg.channel_login), + Some("BotInstance > runner()".to_string()) , + None); }, _ => {} }; @@ -404,7 +563,10 @@ impl BotInstance pub async fn listener_main_prvmsg(bot:BotAR,msg:&PrivmsgMessage) -> () { // println!(">> Inner listenermain_prvmsg()"); - Log::trace(">> Inner listenermain_prvmsg()"); + // Log::trace(">> Inner listenermain_prvmsg()"); + 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); @@ -416,23 +578,35 @@ impl BotInstance // let hacts = hacts.read().await; let a = hacts.read().await; // println!("hacts size : {}",(*a).len()); - Log::debug(&format!("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)); // println!(">> Inner listenermain_prvmsg() >> before for loop of bot actions"); - Log::trace(">> 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 { // println!(">> Inner listenermain_prvmsg() >> checking bot actions"); - Log::trace(">> 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)); + // let bot = bot; for a in acts { // println!(">> Inner listenermain_prvmsg() >> checking bot actions >> 2"); - Log::trace(">> 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)); let _act = match a { @@ -452,9 +626,12 @@ impl BotInstance // } // println!("Reviewing internal commands"); - Log::trace("Reviewing internal commands"); + // Log::trace("Reviewing internal commands"); + 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("\n").next().expect("ERROR during BotCommand"); let inpt = msg.message_text.split(" ").next().expect("ERROR during BotCommand"); @@ -481,19 +658,35 @@ impl BotInstance if confirmed_bot_command { // println!("Confirmed bot command"); - Log::debug("Confirmed bot command"); + // Log::debug("Confirmed bot command"); + botlog::debug("Confirmed bot command", + Some("BotInstance > listener_main_prvmsg()".to_string()) , + Some(&msg)); // println!("Going for botlock"); - Log::trace("Going for botlock"); + // Log::trace("Going for botlock"); + 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"); + // Log::trace("Going for identity"); + 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"); + // Log::trace("Unlocking identity"); + 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; // // [-] #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 { @@ -507,33 +700,54 @@ impl BotInstance }; // println!("Checking if permissible"); Log::trace("Checking if permissible"); + botlog::trace("Checking if permissible", + Some("BotInstance > listener_main_prvmsg()".to_string()) , + Some(&msg)); 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)); + + // println!("Read() lock Bot"); - Log::trace("Read() lock Bot"); + // Log::trace("Read() lock Bot"); + 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(); (*botlock).botmgrs.chat.say_in_reply_to(msg, outstr).await; + } } match eval { Permissible::Allow => { // println!("Executed as permissible"); - Log::debug("Executed as permissible"); + // Log::debug("Executed as permissible"); + 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"); + // Log::trace("exit out of execution"); + 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"); + // 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)); }, // _ => (), }; @@ -558,7 +772,10 @@ impl BotInstance // // [ ] 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"); + // 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)); // self // bot diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 7075484..43af6d7 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -17,7 +17,7 @@ use tokio::sync::Mutex; -use crate::core::botinstance::{self, BotInstance}; +use crate::core::botinstance::{self, botlog, BotInstance}; use std::rc::Rc; // use tokio::sync::RwLock; @@ -201,14 +201,20 @@ impl BotActionTrait for Listener async fn add_to_bot(self, bot:BotInstance) { // println!("Adding action to bot"); - Log::trace("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); self.add_to_modmgr(bot.botmodules).await; } 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"); + // Log::trace("Adding action to module manager"); + 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; } @@ -245,7 +251,11 @@ impl ModulesManager // :: [x] initialize core modules - println!("ModulesManager > init() > Adding modules"); + // println!("ModulesManager > init() > Adding modules"); + botlog::debug("ModulesManager > init() > Adding modules", + Some("ModulesManager > init()".to_string()), + None + ); let mgra = Arc::new(mgr); crate::core::identity::init(Arc::clone(&mgra)).await; @@ -254,7 +264,11 @@ impl ModulesManager - println!(">> Modules Manager : End of Init"); + // println!(">> Modules Manager : End of Init"); + botlog::trace(">> Modules Manager : End of Init", + Some("ModulesManager > init()".to_string()), + None + ); mgra } @@ -285,7 +299,14 @@ impl ModulesManager pub async fn add_botaction(&self, in_module:ModType, in_action:BotAction ) { - println!("Add botaction called"); + // println!("Add botaction called"); + + 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 @@ -426,8 +447,16 @@ impl ModulesManager // modactions.push(BotAction::L(newlistener)); modactions.push(in_action); - println!(">> Modules Manager : Called Add bot Action"); - println!("add_botaction - botactions size : {}",modactions.len()); + // println!(">> Modules Manager : Called Add bot Action"); + 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 + ); } diff --git a/src/core/identity.rs b/src/core/identity.rs index c02e269..a628aa6 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -34,7 +34,9 @@ fn adminvector() -> Vec { pub async fn init(mgr:Arc) { - println!("Went into Identiy Module init"); + // println!("Went into Identiy Module init"); + botinstance::botlog::trace("Went into Identiy Module init", + Some("identity.rs > init()".to_string()), None); // let a = actions_util::asyncbox(cmd_promote) ; @@ -57,7 +59,9 @@ pub async fn init(mgr:Arc) async fn cmd_promote(bot:BotAR,msg:PrivmsgMessage) -> () { //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); - println!("Called cmd promote"); + // println!("Called cmd promote"); + 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 @@ -87,7 +91,10 @@ pub async fn init(mgr:Arc) */ - println!("{}",msg.message_text); + // println!("{}",msg.message_text); + botinstance::botlog::trace(&format!("{}",msg.message_text), + Some("identity.rs > cmd_prommote()".to_string()), None); + let mut argv = msg.message_text.split(" "); argv.next(); // Skip the command name @@ -122,7 +129,10 @@ pub async fn init(mgr:Arc) // if let Some(a) = *ta { if a.contains(&UserRole::BotAdmin) { - println!("BotAdmin allowed to promote admin"); + // println!("BotAdmin allowed to promote admin"); + botinstance::botlog::debug("BotAdmin allowed to promote admin", + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + { let botlock = Arc::clone(&bot.read().await.get_identity()); @@ -184,8 +194,10 @@ pub async fn init(mgr:Arc) tempb.add_to_modmgr(Arc::clone(&mgr)).await; // async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { - async fn cmd_demote(mut _chat:BotAR,_msg:PrivmsgMessage) { - println!("Called cmd demote"); + async fn cmd_demote(mut _chat:BotAR,msg:PrivmsgMessage) { + // println!("Called cmd demote"); + botinstance::botlog::debug("Called cmd demote", + Some("identity.rs > cmd_demote()".to_string()), Some(&msg)); } @@ -224,7 +236,9 @@ pub async fn init(mgr:Arc) // async fn getroles(bot:Arc>,msg:PrivmsgMessage) { async fn getroles(bot:BotAR,msg:PrivmsgMessage) { - println!("Called cmd getroles"); + // println!("Called cmd getroles"); + botinstance::botlog::debug("Called cmd getroles", + Some("identity.rs > cmd_getroles()".to_string()), Some(&msg)); /* Usage @@ -297,11 +311,17 @@ pub async fn init(mgr:Arc) // let a = a.lock().await; // let a = bot.get_identity(); let botlock = bot.read().await; - println!("botlock read"); + // println!("botlock read"); + botinstance::botlog::trace("botlock read", + Some("identity.rs > init > getroles()".to_string()), Some(&msg)); let idlock = botlock.get_identity(); - println!("got identity"); + // println!("got identity"); + 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"); + // 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); @@ -334,7 +354,9 @@ pub async fn init(mgr:Arc) }; - println!("Retrieved User Roles >> {:?}",sproles); + // println!("Retrieved User Roles >> {:?}",sproles); + botinstance::botlog::debug(&format!("Retrieved User Roles >> {:?}",sproles), + Some("identity.rs > init > getroles()".to_string()), Some(&msg)); // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot")))); // println!("{:?}",a); @@ -343,7 +365,9 @@ pub async fn init(mgr:Arc) - println!("End of Init MOdule add"); + // println!("End of Init MOdule add"); + botinstance::botlog::trace("End of Init MOdule add", + Some("identity.rs > init ".to_string()), None); } @@ -416,7 +440,9 @@ impl IdentityManager { // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // [ ] Check what Badges in PrivmsgMessage - println!{"Checking within PRVMSG"}; + // println!{"Checking within PRVMSG"}; + botinstance::botlog::debug("Checking within PRVMSG", + Some("identity.rs > can_user_run_PRVMSG()".to_string()), Some(&msg)); let mut sender_badge:Option = None; @@ -486,7 +512,9 @@ impl IdentityManager { // ) -> Result> { ) -> (Permissible,ChangeResult) { - println!{"Checking within can_user_run()"}; + // println!{"Checking within can_user_run()"}; + botinstance::botlog::debug("Checking within can_user_run()", + Some("identity.rs > can_user_run()".to_string()), None); /* canUserRun - @@ -557,7 +585,9 @@ impl IdentityManager { ChatBadge::Mod => { - println!("Mod Chatbadge detected"); + // 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()); @@ -565,9 +595,16 @@ impl IdentityManager { // 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"); + // println!("Creating clone"); + botinstance::botlog::trace("Creating 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 + + // 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); + let mut roleslock = roleslock.write().await; match (*roleslock).get(&usr.to_lowercase()) { Some(usrroles) if @@ -577,12 +614,20 @@ impl IdentityManager { // 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"); + // 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"); + // 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; @@ -607,7 +652,9 @@ impl IdentityManager { // [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); + // 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) { @@ -616,13 +663,20 @@ impl IdentityManager { // } - println!("Mod Role required"); + // 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"); + // 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 "); + // 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) } } @@ -644,12 +698,22 @@ impl IdentityManager { // [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow) - println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin)); + // 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())); + // 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) diff --git a/src/main.rs b/src/main.rs index 07e4a13..316483e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::process::Output; use crate::core::botinstance::ArcBox; -use crate::core::botinstance::BotInstance; +use crate::core::botinstance::{self,BotInstance}; use casual_logger::Extension; use tokio::sync::RwLock; use std::sync::Arc; @@ -23,7 +23,8 @@ pub async fn main() { let bot = BotInstance::init().await; - Log::debug("Checking bot actions"); + // Log::debug("Checking bot actions"); + botinstance::botlog::debug("Checking bot actions", Some("main()".to_string()), None); let a = Arc::clone(&bot.botmodules.botactions); let a = a.read().await; // let a = *a; @@ -33,15 +34,18 @@ pub async fn main() { match act { crate::core::botmodules::BotAction::C(b) => { // println!("bot actiions: {}",b.command) - Log::info(&format!("bot actions: {}",b.command)); + // Log::info(&format!("bot actions: {}",b.command)); + botinstance::botlog::info(&format!("bot actions: {}",b.command), Some("main()".to_string()), None); }, crate::core::botmodules::BotAction::L(l) => { // println!("bot actiions: {}",l.name) - Log::info(&format!("bot actions: {}",l.name)); + // Log::info(&format!("bot actions: {}",l.name)); + botinstance::botlog::info(&format!("bot actions: {}",l.name), Some("main()".to_string()), None); }, _ => { // println!("Not a valid match??") - Log::info("Not a valid match??"); + // Log::info("Not a valid match??"); + botinstance::botlog::info("Not a valid match??", Some("main()".to_string()), None); }, } @@ -49,7 +53,9 @@ pub async fn main() { }; // println!("Starting runner.."); - Log::notice("Starting Bot Runner"); + // Log::notice("Starting Bot Runner"); + botinstance::botlog::notice("Starting Bot Runner", Some("main()".to_string()), None); + println!("Starting Bot Runner"); Log::flush(); @@ -57,6 +63,8 @@ pub async fn main() { // println!("ERROR : EXIT Game loop"); // let msg = Log::fatal("ERROR : EXIT Game loop"); - panic!("{}",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 diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index f63192c..2c4a4e2 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -79,7 +79,13 @@ pub async fn init(mgr:Arc) async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) { - println!("In GoodGirl() Listener"); + // 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)); + + //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); // [ ] Uses gen_ratio() to output bool based on a ratio probability . @@ -91,10 +97,16 @@ async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) { // chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; //if rng.gen_ratio(1,5) { - println!("In GoodGirl() > Pausechamp"); + // 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); if rollwin { - println!("In GoodGirl() > Win"); + // 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; @@ -106,8 +118,11 @@ async fn good_girl(mut bot:BotAR,msg:PrivmsgMessage) } -async fn testy(mut _chat:BotAR,_msg:PrivmsgMessage) +async fn testy(mut _chat:BotAR,msg:PrivmsgMessage) { - println!("testy triggered!") + 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 -- 2.46.1 From dacad7fbe2673499d607a00056f99df8f4fbdad5 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:49:36 -0500 Subject: [PATCH 31/39] (cont) identity > promote() --- src/core/identity.rs | 403 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 357 insertions(+), 46 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index a628aa6..d745684 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -21,6 +21,8 @@ use std::cell::RefCell; use std::sync::{Arc}; use tokio::sync::RwLock; +use casual_logger::{Level,Log}; + use super::botmodules::bot_actions::actions_util::BotAR; @@ -115,35 +117,58 @@ pub async fn init(mgr:Arc) match arg1 { - Some(a1) if a1 == String::from("admin") => { - // - BotAdmins can promote admin to give BotAdmin UserRole + Some(a1) if a1 == String::from("-admin") => { + // - [ ] BotAdmins can promote admin to give BotAdmin UserRole let botlock = bot.read().await; - let ta = botlock.get_identity(); - let ta = ta.read().await; - let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - let ta = ta.unwrap(); - let a = ta.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 a.contains(&UserRole::BotAdmin) { + 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 botlock = Arc::clone(&bot.read().await.get_identity()); - let idlock = botlock.write().await; + 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(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} ;"), - ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), - ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + botinstance::botlog::debug(&format!("BotAdmin Successful Promotion : {a}"), + 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).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + botinstance::botlog::debug(&format!("BotAdmin Failed Promotion : {a}"), + 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).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + botinstance::botlog::debug(&format!("BotAdmin No Change in Promotion : {a}"), + 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).await; + }, } } @@ -151,6 +176,9 @@ pub async fn init(mgr:Arc) } // }, + Some(arg1) => { + + } _ => (), } @@ -334,7 +362,10 @@ pub async fn init(mgr:Arc) // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); // println!("Retrieved User Roles >> {:?}",a); // let a = idlock.read().await; - idlock.getspecialuserroles(String::from(targetuser),None).await + // 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 }, Some(targetchnl) => { // let bot = Rc::clone(&bot); @@ -348,19 +379,129 @@ pub async fn init(mgr:Arc) // println!("Retrieved User Roles >> {:?}",a); // bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None) // let a = a.read().await; - idlock.getspecialuserroles(String::from(targetuser),None).await + + // [ ] If caller is not a BotAdmin, they can only pull those related to the current channel for the target user + // [ ] If caller is a BotAdmin, allow & return for target channel + // let mut sender_badge:Option = None; + + // for b in &msg.badges { + // if b.name == "moderator" { + // sender_badge = Some(ChatBadge::Mod); + // } else if b.name == "broadcaster" { + // sender_badge = Some(ChatBadge::Broadcaster); + // } + // } + + // match sender_badge { + // Some(ChatBadge::Mod) => { + + // } , + // Some(ChatBadge::Broadcaster) => { + + // } + // _ => { + + // } + // } + + // [x]gets special roles for caller + 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 + // 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 + } + + }, }; + // let sproles = idlock.getspecialuserroles(String::from(targetuser),).await; + // println!("Retrieved User Roles >> {:?}",sproles); - botinstance::botlog::debug(&format!("Retrieved User Roles >> {:?}",sproles), + 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)); + + // 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 + format!("FeelsWowMan they're the broadcaster ") + } + 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())) { + + // } else if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { + + // } + + // let outmsg = match sproles + // { + + // // let mut outmsg = String::new(); + // Some(sproles) => { + + // let sproles = sproles.read().await; + + // 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), + // 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())), + // Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + + // if msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase()) { + // format!("FeelsWowMan they're the broadcaster ") + // } else { + // format!("Target chatter has no special roles LULE ") + // } + + // } + + // }; // 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)); + 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 + + } @@ -369,6 +510,8 @@ pub async fn init(mgr:Arc) botinstance::botlog::trace("End of Init MOdule add", Some("identity.rs > init ".to_string()), None); + Log::flush(); + } @@ -458,7 +601,9 @@ impl IdentityManager { // } - if let Some(sender_badge) = sender_badge { + // 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, @@ -489,25 +634,38 @@ impl IdentityManager { // * NOTE : We're preferring to pass the ChangeResult up , where we have access to Chat via BotInstance // that have more strained chatting rules - return self.can_user_run(msg.sender.name.to_owned(), - ChType::Channel(msg.channel_login.to_owned()), - sender_badge, - cmdreqroles - ).await - } + // 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())) + // (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 } pub async fn can_user_run(&mut self, usr:String, channelname:ChType, - chat_badge:ChatBadge, + chat_badge:Option, cmdreqroles:Vec // ) -> Result> { ) -> (Permissible,ChangeResult) { @@ -570,7 +728,7 @@ impl IdentityManager { // [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) // [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) - ChatBadge::Broadcaster => { + Some(ChatBadge::Broadcaster) => { if cmdreqroles.contains(&UserRole::Broadcaster) || cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) || cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { @@ -583,7 +741,7 @@ impl IdentityManager { // [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) // [x] If not, assign them UserRole::Mod(channelname::ChType) - ChatBadge::Mod => { + Some(ChatBadge::Mod) => { // println!("Mod Chatbadge detected"); botinstance::botlog::info("Mod Chatbadge detected", @@ -647,7 +805,7 @@ impl IdentityManager { } }, - // _ => (), + _ => (), // 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) @@ -751,27 +909,51 @@ impl IdentityManager { // _ => &(emptyvec), // }; - let chatterroles = chatterroles.unwrap(); - let chatterroles = chatterroles.read().await; - let rolemap = &(*chatterroles); + // let chatterroles = chatterroles.unwrap(); + // let chatterroles = chatterroles.read().await; + //let rolemap = &(*chatterroles); + let rolemap = chatterroles; match trg_role { Some(UserRole::Mod(a)) => { - if let Some(trg_chnl) = channel { + if let Some(trg_chnl) = channel.clone() { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rolemap = chatterroles; // let rolemap = rolemap.unwrap(); if rolemap.contains(&UserRole::Mod(trg_chnl.clone())) { return ChangeResult::NoChange(String::from("Target User already has Target Role")); } // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); - self.special_roles_users - .write().await - .get_mut(&trgchatter) - .expect("Error getting roles") - .write().await - .push(UserRole::Mod(trg_chnl)); + // let a = self.special_roles_users; + // let b = a.write().await; + // // let c = b.get_mut(&trgchatter); + // let c = (*b).; + + // [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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } return ChangeResult::Success(String::from("Promotion Successful")); } @@ -779,7 +961,61 @@ impl IdentityManager { }, Some(UserRole::SupMod(a)) => (), - Some(UserRole::BotAdmin) => (), + Some(UserRole::BotAdmin) => { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rolemap = chatterroles; + + 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] 1. Check target chatter's roles first if they already have 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), + Some("identity.rs > promote()".to_string()), None); + + // [ ] (!) This seems to be an issue - rolemap by this point is blank + if rolemap.contains(&UserRole::BotAdmin) { + return ChangeResult::NoChange(String::from("Target User already has Target Role")); + } + // # 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + { + + let mut srulock = self.special_roles_users.write().await; + + srulock + .get_mut(&trgchatter) + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .expect("Error getting roles") + .write().await + .push(UserRole::BotAdmin); + 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"), + Some("identity.rs > promote()".to_string()), None); + + return ChangeResult::Success(String::from("Promotion Successful")); + }, Some(_) => (), None => (), } @@ -856,27 +1092,102 @@ impl IdentityManager { ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { + // pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { + pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Vec { /* 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); + + // resulting vector + let mut evalsproles = vec![]; let chattername = chattername.to_lowercase(); + // Checks if broadcaster + let channel_out = match channel { + Some(channel_tmp) => { + match channel_tmp { + ChType::Channel(channel_tmp) => { + // In this block, Some input channel is given + // We're comparing the channel name with chattername to determine if they're a broadcaster + if chattername == channel_tmp.to_lowercase() { + evalsproles.push(UserRole::Broadcaster); + } + + Some(ChType::Channel(channel_tmp)) + }, + // _ => () + } + } + None => None, + }; + + let rolesa = Arc::clone(&self.special_roles_users); let a = rolesa.read().await; // let a = Arc::clone(a) let a = a; - let outr = &(*a); - let outr = outr.get(&chattername); - match outr { - Some(a) => Some(Arc::clone(a)), - None => None, + let vecroles = &(*a); + let vecroles = vecroles.get(&chattername); + match vecroles { + Some(a) => { + // [ ] This needs to take the user roles for the user, then yield only the one for the channel if channel is explicitely provided + // Some(Arc::clone(a)) + match channel_out { + 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); + + // 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); + + 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) { + 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 + }, } + botinstance::botlog::debug(&format!("OUT > evalsproles {:?}", &evalsproles), + Some("IdentityManager > getspecialuserroles()".to_string()), None); + + return evalsproles; + } -- 2.46.1 From ce27674a5f78f82521dbcbbd969416c1b4dd5d63 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 14 Feb 2024 01:09:55 -0500 Subject: [PATCH 32/39] (cont) identity > promote 2 --- src/core/identity.rs | 349 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 312 insertions(+), 37 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index d745684..1ae9e60 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -6,7 +6,7 @@ use std::error::Error; use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; use crate::core::botmodules::bot_actions::actions_util; -use crate::core::botinstance::{self,BotInstance}; +use crate::core::botinstance::{self, botlog, BotInstance}; use futures::lock::Mutex; use twitch_irc::message::{Badge, PrivmsgMessage}; @@ -77,25 +77,25 @@ pub async fn init(mgr:Arc) - [ ] 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 - - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` + - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` or `promote` the other way */ /* Usage : - promote + promote - demote + demote - promote admin + promote -admin */ // println!("{}",msg.message_text); - botinstance::botlog::trace(&format!("{}",msg.message_text), - Some("identity.rs > cmd_prommote()".to_string()), None); + botinstance::botlog::trace(&format!("Twich Message > {}",msg.message_text), + Some("identity.rs > cmd_promote()".to_string()), None); let mut argv = msg.message_text.split(" "); @@ -118,14 +118,16 @@ pub async fn init(mgr:Arc) match arg1 { Some(a1) if a1 == String::from("-admin") => { - // - [ ] BotAdmins can promote admin to give BotAdmin UserRole + // - [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 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; @@ -150,33 +152,210 @@ pub async fn init(mgr:Arc) match ta { ChangeResult::Success(a) => { // println!("Succesfully promoted : {a} ;"); - botinstance::botlog::debug(&format!("BotAdmin Successful Promotion : {a}"), - 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).await; + 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} ; "); - botinstance::botlog::debug(&format!("BotAdmin Failed Promotion : {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).await; + // 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} ; "); - botinstance::botlog::debug(&format!("BotAdmin No Change in Promotion : {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).await; + // 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 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::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 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 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(); } _ => (), @@ -189,6 +368,11 @@ pub async fn init(mgr:Arc) let targetchnl = arg2; + + botinstance::botlog::trace(&format!("End of cmd_promote()"), + Some("identity.rs > cmd_prommote()".to_string()), None); + + } // BotCommand { @@ -226,23 +410,35 @@ pub async fn init(mgr:Arc) // println!("Called cmd demote"); 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 + - [ ] run `promote` on a regular `Chatter` to make them a `Mod` + - [ ] run `demote` on a `Mod` to make them a `Chatter` + - [ ] 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 + - `[ ] Broadcaster` & `BotAdmin` can `demote` a `SupMod` to make them a `Mod` or `promote` the other way + */ + /* + Usage : + + promote + + demote + + promote -admin + + */ - // 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, - // ], - // }.add_to_modmgr(Arc::clone(&mgr)); let tempcomm = BotCommand { module : BotModule(String::from("identity")), @@ -442,9 +638,16 @@ pub async fn init(mgr:Arc) 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 - format!("FeelsWowMan they're the broadcaster ") + // 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 } + 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) { @@ -885,6 +1088,10 @@ impl IdentityManager { // pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { pub async fn promote(&self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { + botinstance::botlog::trace(&format!("IN VARS for promote() : Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", + trgchatter,channel,trg_role), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); // Note : If channel is none, getspecialuserroles() returns all roles for the user // let chatterroles = self.getspecialuserroles(trgchatter, channel); @@ -917,7 +1124,7 @@ impl IdentityManager { match trg_role { - Some(UserRole::Mod(a)) => { + Some(UserRole::Mod(_)) => { if let Some(trg_chnl) = channel.clone() { let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; @@ -925,7 +1132,10 @@ impl IdentityManager { // let rolemap = rolemap.unwrap(); if rolemap.contains(&UserRole::Mod(trg_chnl.clone())) { return ChangeResult::NoChange(String::from("Target User already has Target Role")); + } else if rolemap.contains(&UserRole::Broadcaster) { + return ChangeResult::NoChange(String::from("No need to do that for broadcaster")); } + // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); // let a = self.special_roles_users; @@ -960,7 +1170,72 @@ impl IdentityManager { }, - Some(UserRole::SupMod(a)) => (), + Some(UserRole::SupMod(_)) => + { + if let Some(trg_chnl) = channel.clone() { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rolemap = chatterroles; + // let rolemap = rolemap.unwrap(); + if rolemap.contains(&UserRole::SupMod(trg_chnl.clone())) { + return ChangeResult::NoChange(String::from("Target User already has Target Role")); + } else if rolemap.contains(&UserRole::Broadcaster) { + return ChangeResult::NoChange(String::from("No need to do that for broadcaster")); + } + // # otherwise, trg_role for the given chnl is not assigned to the trgchatter + // chatterroles.push(UserRole::Mod(trg_chnl.clone())); + // let a = self.special_roles_users; + // let b = a.write().await; + // // let c = b.get_mut(&trgchatter); + // let c = (*b).; + + // [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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { + let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + // .write().await + // .(UserRole::Mod(trg_chnl)); + // let indx = srulock.iter().position() + let mut uroleslock = srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .write().await; + if let Some(indx) = uroleslock.iter().position(|value| *value == UserRole::Mod(trg_chnl.clone())){ + uroleslock.swap_remove(indx); + } + + botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",uroleslock), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + return ChangeResult::Success(String::from("Promotion Successful")); + } + } , Some(UserRole::BotAdmin) => { let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; -- 2.46.1 From a825544590f7369ad377d5b5e1882b14e4ccd2e8 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 14 Feb 2024 09:21:50 -0500 Subject: [PATCH 33/39] (init) id > demote --- src/core/identity.rs | 88 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 1ae9e60..3401bc1 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -411,7 +411,7 @@ pub async fn init(mgr:Arc) 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 @@ -440,6 +440,8 @@ pub async fn init(mgr:Arc) */ + } + let tempcomm = BotCommand { module : BotModule(String::from("identity")), command : String::from("getroles"), // command call name @@ -1086,7 +1088,12 @@ impl IdentityManager { } // pub async fn promote(&mut self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { - pub async fn promote(&self,trgchatter:String,channel:Option,trg_role:Option) -> ChangeResult { + pub async fn promote(&self, + trgchatter:String, + channel:Option, + trg_role:Option) -> ChangeResult + { + botinstance::botlog::trace(&format!("IN VARS for promote() : Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", trgchatter,channel,trg_role), @@ -1291,8 +1298,14 @@ impl IdentityManager { return ChangeResult::Success(String::from("Promotion Successful")); }, - Some(_) => (), - None => (), + Some(_) => { + botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), + Some("identity.rs > promote()".to_string()), None); + }, + None => { + botinstance::botlog::warn(&format!("Runtime reached undeveloped code"), + Some("identity.rs > promote()".to_string()), None); + }, } @@ -1362,9 +1375,72 @@ impl IdentityManager { ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub fn demote(self,trgchatter:String,channel:Option,trgRole:Option) -> ChangeResult { - ChangeResult::Success(String::from("TEST > Promotion Successful")) + pub async fn demote(&self, + authorizer:String, + trgchatter:String, + channel:Option, + trg_role:Option) -> ChangeResult + { + botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", + authorizer,trgchatter,channel,trg_role), + Some("identity.rs > demote()".to_string()), None); + Log::flush(); + + /* + Check authorizer roles (if any) for the target channel + Check Targer User 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 + */ + + if let Some(channel) = channel { + let authusrroles = self.getspecialuserroles( + authorizer.to_lowercase().clone(), + Some(channel.clone())) + .await; + // let authusrroles = authusrroles; + + let trgusrroles = self.getspecialuserroles( + trgchatter.to_lowercase().clone(), + Some(channel.clone())) + .await; + + if ( authusrroles.contains(&UserRole::BotAdmin) || + authusrroles.contains(&UserRole::Broadcaster) || + authusrroles.contains(&UserRole::SupMod(channel.clone())) ) && + trgusrroles.contains(&UserRole::Mod(channel.clone())) + { + 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()) + } + } + else if ( authusrroles.contains(&UserRole::BotAdmin) || + authusrroles.contains(&UserRole::Broadcaster) ) && + trgusrroles.contains(&UserRole::SupMod(channel.clone())) + { + 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::SupMod(channel.clone())); + if let Some(indx) = usrrolelock.iter().position(|value| *value == UserRole::SupMod(channel.clone())){ + usrrolelock.swap_remove(indx); + return ChangeResult::Success("Demoted successfully".to_string()) + } + } + } + + + ChangeResult::Failed(String::from("Did not meet criteria to demote succesfully")) } // pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { -- 2.46.1 From 2d5fa269de08ac5077d46520a616c8c80f31702c Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 18 Feb 2024 15:23:58 -0500 Subject: [PATCH 34/39] functional identity demote,promote,canuserrun --- .gitignore | 5 +- src/core/botinstance.rs | 31 +- src/core/botmodules.rs | 23 +- src/core/identity.rs | 819 +++++++++++++++++++++++++++++++++++-- src/modules/experiments.rs | 4 +- 5 files changed, 827 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index c8270c9..5c5e6b4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,7 @@ target/ # log -*.log \ No newline at end of file +*.log + +# debug +.vscode/ \ No newline at end of file diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 7823673..1bc9d21 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -66,6 +66,16 @@ pub mod botlog { // trace, debug, info, notice, warn, error, fatal + /* + + in main : Log::debug("Checking bot actions", Some("main()".to_string()), None); + + in log : + [blalba@timestmp] + debug = "Checking bot actions", + + */ + pub fn trace(in_msg:&str,in_module:Option,in_prvmsg:Option<&PrivmsgMessage>) -> () { @@ -86,6 +96,8 @@ pub mod botlog { .str("Chatter",&format!("{:?}",chatter)) .str("Code_Module",&format!("{:?}",in_module)) ); + + } @@ -385,6 +397,8 @@ pub struct BotInstance pub twitch_oauth : String, pub bot_channels : Vec, pub botmgrs : BotManagers, + //modesmgr : ModesManager, // Silent/Quiet , uwu , frisky/horny + } @@ -435,7 +449,17 @@ impl BotInstance - let b = BotInstance { + // 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, + // botmgrs : BotManagers::init(ratelimiters,client), + // }; + + BotInstance { prefix : prefix, bot_channel : Channel(login_name) , incoming_messages : Arc::new(RwLock::new(incoming_messages)), @@ -443,10 +467,9 @@ impl BotInstance twitch_oauth : oauth_token, bot_channels : botchannels, botmgrs : BotManagers::init(ratelimiters,client), - }; + } - - b + // b } pub async fn runner(self) -> () { diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 43af6d7..86c6314 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -55,11 +55,12 @@ pub enum ModType { pub use ModType::BotModule; -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub enum ChType { - Channel(String), -} +// #[derive(Debug, PartialEq, Eq, Hash, Clone)] +// pub enum ChType { +// Channel(String), +// } +use botinstance::ChType; pub use ChType::Channel; use twitch_irc::message::PrivmsgMessage; @@ -234,6 +235,20 @@ pub struct ModulesManager pub botactions: Arc>>>, } +/* + +statusdb + <-- shows Enabled/Disabled per Status level + +botactions + HashMap< + ModType, <-- e.g., BotModule(String::from("experiments001")) + Vec> BotCommand, Listener + +*/ + impl ModulesManager { diff --git a/src/core/identity.rs b/src/core/identity.rs index 3401bc1..7251646 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -6,11 +6,11 @@ use std::error::Error; use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; use crate::core::botmodules::bot_actions::actions_util; -use crate::core::botinstance::{self, botlog, BotInstance}; +use crate::core::botinstance::{self, botlog, BotInstance,ChType}; use futures::lock::Mutex; use twitch_irc::message::{Badge, PrivmsgMessage}; -use crate::core::botmodules::ChType; +// use crate::core::botmodules::ChType; use crate::core::botinstance::ArcBox; @@ -29,6 +29,7 @@ use super::botmodules::bot_actions::actions_util::BotAR; fn adminvector() -> Vec { vec![String::from("ModulatingForce")] + //vec![] } @@ -97,6 +98,8 @@ pub async fn init(mgr:Arc) 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 @@ -115,7 +118,92 @@ pub async fn init(mgr:Arc) } } + 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}; + + + // [x] 2. promote trguser + + // [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 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}; + + 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); + Log::flush(); + + ChangeResult::NoChange("No Targer User".to_string()) + + } + + }; + + + + // [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)); + // 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; + }, + } + + + /* match arg1 { Some(a1) if a1 == String::from("-admin") => { // - [x] BotAdmins can promote admin to give BotAdmin UserRole @@ -252,7 +340,7 @@ pub async fn init(mgr:Arc) }, ChangeResult::NoChange(a) => { // println!("No Changes Made : {a} ; "); - let outmsg = &format!("uuh No Change in Promotion : {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(); @@ -270,10 +358,10 @@ pub async fn init(mgr:Arc) Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); Log::flush(); - // broadcaster & botadmins can make mods into superadmins + // 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::Mod(ChType::Channel(msg.channel_login.to_lowercase())))).await; + Some(UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase())))).await; match ta { ChangeResult::Success(a) => { @@ -367,6 +455,7 @@ pub async fn init(mgr:Arc) let targetchnl = arg2; + */ botinstance::botlog::trace(&format!("End of cmd_promote()"), @@ -406,7 +495,7 @@ pub async fn init(mgr:Arc) tempb.add_to_modmgr(Arc::clone(&mgr)).await; // async fn cmd_demote(mut _chat:Arc>,_msg:PrivmsgMessage) { - async fn cmd_demote(mut _chat: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)); @@ -439,6 +528,227 @@ pub async fn init(mgr:Arc) */ + // [ ] #TODO : Need to define the body that calls demote() + + // [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 mut argv = msg.message_text.split(" "); + + argv.next(); // Skip the command name + + let arg1 = argv.next(); + + let arg2 = argv.next(); + + (arg1,arg2) + + }; + + /* + let mut sender_badge:Option = None; + + for b in &msg.badges { + if b.name == "moderator" { + sender_badge = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + sender_badge = Some(ChatBadge::Broadcaster); + } + } + */ + + // --- + + /* + => 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 + + - [ ] 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; + + for b in &msg.badges { + if b.name == "moderator" { + sender_badge_mut = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + sender_badge_mut = Some(ChatBadge::Broadcaster); + } + } + + let sender_badge = sender_badge_mut; + + let targetusr = arg1; + + 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; + + + + let rslt = match targetusr { + Some(targetusr) => { + + 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 + } + + 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 + + */ + + + // let senderUserRole = { + + // // 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(), + // Some(ChType::Channel(targetchnl.clone()))).await; + + // rslroles.push(UserRole::Mod(ChType::Channel(targetchnl))); + + // rslroles + // }, + // _ => { + // idlock.getspecialuserroles( + // 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 + // // 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)); + // 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 demote : {a}"); + 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; + }, + 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)); + // let outmsg = "uuh No Promotion Change : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg.to_string()).await; + }, + + + } + + // println!("tester"); + // println!("tester2"); } @@ -750,7 +1060,23 @@ pub struct IdentityManager { // parent_mgr : Box, //parent_mgr : Option>, } +/* + HashMap< + String, <-- Chatter / Username + Vec -- <-- Vectors are basically arrays + > + -- [ ] + let a = vec![] + + modulatingforce : vec![UserRole::BotAdmin, + UserRole::Mod(ChType::Channel("modulatingforcebot"))] + modulatingforce : vec![UserRole::BotAdmin, + UserRole::Mod(ChType::Channel("modulatingforcebot"))] + +*/ + +#[derive(Debug)] pub enum ChatBadge { Broadcaster, Mod, @@ -876,7 +1202,9 @@ impl IdentityManager { ) -> (Permissible,ChangeResult) { // println!{"Checking within can_user_run()"}; - botinstance::botlog::debug("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 - @@ -918,6 +1246,8 @@ impl IdentityManager { // let idar = Arc::new(RwLock::new(self)); + 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())) @@ -959,7 +1289,7 @@ impl IdentityManager { // 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 clone", + botinstance::botlog::trace("Creating arc clone", Some("identity.rs > can_user_run()".to_string()), None); let roleslock = Arc::clone(&(*self).special_roles_users); @@ -968,6 +1298,16 @@ impl IdentityManager { 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(); + } + let mut roleslock = roleslock.write().await; match (*roleslock).get(&usr.to_lowercase()) { Some(usrroles) if @@ -1089,51 +1429,370 @@ impl IdentityManager { // 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 + trg_role:Option + ) -> ChangeResult { - botinstance::botlog::trace(&format!("IN VARS for promote() : Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", - trgchatter,channel,trg_role), + 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); Log::flush(); - // Note : If channel is none, getspecialuserroles() returns all roles for the user - - // let chatterroles = self.getspecialuserroles(trgchatter, channel); - // let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()); - // let chatterroles = *self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; - // let chatterroles = chatterroles.lock().await; - // // let chatterroles = *chatterroles; - // let chatterroles = chatterroles.unwrap(); + + /* + [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 + [x] 3. If the authorizer & Target Chatters are the same, and the Authorizer is not a Admin, return no change + [x] 4a. If Authorizer is BotAdmin & trg_role is Some(BotAdmin) , set Target as BotAdmin and return + [x] 4b. If target is Broadcaster, return NoChange + [ ] 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 + + + */ + + // [x] 1. Check if Authorizer Mod Badge then Auto Promote to Mod if not Mod + + let (authusrroles,trgusrroles) = if let Some(channel) = channel.clone() { + let mut authusrroles = self.getspecialuserroles( + authorizer.to_lowercase().clone(), + Some(channel.clone())) + .await; + + + { // 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()))) => { + // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); + authusrroles.push(UserRole::Mod(channel.clone())); + + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .write().await + .push(UserRole::Mod(channel.clone())); + + } + _ => (), + } + } // 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + { + + let mut srulock = self.special_roles_users.write().await; + + srulock + .get_mut(&trgchatter) + .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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + return ChangeResult::Success("Promotion Successful".to_string()); + + } + } + + // [x] 4b. If target is Broadcaster, return NoChange + + if trgusrroles.contains(&UserRole::Broadcaster) { + 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 + */ + + + // let authhasnsreqroles = match channel.clone() { + + // 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())) { + // target user is neither Mod nor SupMod && not broadcaster + // target's Next Role would be Mod + // Authorizer must be SupMod,Broadcaster,BotAdmin + // > Promote target to Mod + 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { + // 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + return ChangeResult::Success(String::from("Promotion Successful")); + + } + // 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())) // + { + // 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 + + 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { // Adds the requested role for the user + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] 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())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { // Removes the lower role (mod) from the user + let mut srulock = self.special_roles_users.write().await; + let mut uroleslock = srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + .write().await; + if let Some(indx) = uroleslock.iter().position(|value| *value == UserRole::Mod(trg_chnl.clone())){ + uroleslock.swap_remove(indx); + } + + botinstance::botlog::trace(&format!("Removing lower role > {:?}",uroleslock), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + 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())) { + // target user is a SuMod && not broadcaster + // No Change + return ChangeResult::Failed(String::from("Already highest available role")); + + + } else { + // since handling for channel is already done, will be handling other trguserroles situations here + // other situations includes : + /* + [-] 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")); + + + } + + + + // 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + // { + // // promote target after + // let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] 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())), + // 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + // { + // // promote target after + // let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + + // return ChangeResult::Success(String::from("Promotion Successful")); + + // } + + // authusrroles.contains(&UserRole::Mod(())) + + + + + + + + + /* let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; - // let chatterroles = chatterroles.lock().await; - // let chatterroles = *chatterroles; - // let chatterroles = chatterroles.unwrap(); - - // let emptyvec = vec![]; - - // let chatterroles = match chatterroles { - // Some(a) => a, - // _ => &(emptyvec), - // }; - - // let chatterroles = chatterroles.unwrap(); - // let chatterroles = chatterroles.read().await; - //let rolemap = &(*chatterroles); + 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 + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; let rolemap = chatterroles; // let rolemap = rolemap.unwrap(); @@ -1150,9 +1809,13 @@ impl IdentityManager { // // let c = b.get_mut(&trgchatter); // let c = (*b).; + // [ ] 2. Ensure an entry in Special_Roles_user for trgchatter, and push Mod(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 { + + // 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())), @@ -1160,6 +1823,7 @@ impl IdentityManager { Log::flush(); } { + // promote target after let mut srulock = self.special_roles_users.write().await; srulock .get_mut(&trgchatter) @@ -1181,6 +1845,8 @@ impl IdentityManager { { if let Some(trg_chnl) = channel.clone() { + // [ ] 1. If trg_role & trgchatter is a Mod or SupMod of the target channel, return NoChange + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; let rolemap = chatterroles; // let rolemap = rolemap.unwrap(); @@ -1196,6 +1862,9 @@ 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 { @@ -1245,6 +1914,8 @@ impl IdentityManager { } , Some(UserRole::BotAdmin) => { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; let rolemap = chatterroles; @@ -1308,6 +1979,7 @@ impl IdentityManager { }, } + */ // match chatterroles { // Some(chatterroles) => { @@ -1371,42 +2043,81 @@ impl IdentityManager { // }, // _ => (), // } - - ChangeResult::Success(String::from("TEST > Promotion Successful")) + 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, - trg_role:Option) -> ChangeResult + // trg_role:Option + ) -> ChangeResult { - botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}", - authorizer,trgchatter,channel,trg_role), + // botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} ; Targer 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); Log::flush(); /* Check authorizer roles (if any) for the target channel - Check Targer User 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 */ + // [x] 1. If Authorizer's Badge is Mod, ensuring Sender is in DB as Mod(Channel) if let Some(channel) = channel { - let authusrroles = self.getspecialuserroles( + 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())) + ) => { + // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); + authusrroles.push(UserRole::Mod(channel.clone())); + + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .write().await + .push(UserRole::Mod(channel.clone())); + + } + _ => (), + } + } + + // [x] 2. Targer User's Vec 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()) + } + + // [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())) ) && @@ -1422,6 +2133,8 @@ impl IdentityManager { 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())) @@ -1431,20 +2144,38 @@ impl IdentityManager { .get_mut(&trgchatter) .expect("Error getting roles") .write().await; - usrrolelock.push(UserRole::SupMod(channel.clone())); + 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()) } } + + // [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()) + } + // [x] 4d. WHhen 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()) + } } + 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 { + pub async fn getspecialuserroles( + &self,chattername:String, + channel:Option) -> Vec { /* Note : Ideally this be called for a given chatter name ? */ diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs index 2c4a4e2..c75574f 100644 --- a/src/modules/experiments.rs +++ b/src/modules/experiments.rs @@ -14,10 +14,10 @@ use std::future::Future; -use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType}; +use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand}; use crate::core::botmodules::bot_actions::actions_util::{self, BotAR}; -use crate::core::botinstance::{self,BotInstance}; +use crate::core::botinstance::{self,BotInstance,ChType}; use futures::lock::Mutex; use twitch_irc::message::PrivmsgMessage; -- 2.46.1 From cbaad6055738ca3e13b5b8d39182928dfcb01e54 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 18 Feb 2024 16:01:28 -0500 Subject: [PATCH 35/39] fix identity so case insensitive --- src/core/identity.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 7251646..081be65 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1461,6 +1461,9 @@ impl IdentityManager { // [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(), @@ -2073,6 +2076,9 @@ impl IdentityManager { */ // [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(), @@ -2156,7 +2162,7 @@ impl IdentityManager { !trgusrroles.contains(&UserRole::SupMod(channel.clone())) { return ChangeResult::Failed("Target chatter does not have a role that can be demoted".to_string()) } - // [x] 4d. WHhen they're only a Mod + // [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()) } -- 2.46.1 From b41c34c3922498ec67afbf218f42ae660efbb1f4 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 18 Feb 2024 19:23:50 -0500 Subject: [PATCH 36/39] idmgr helper fns --- src/core/identity.rs | 293 ++++++++++++++++++++++++++----------------- 1 file changed, 181 insertions(+), 112 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 081be65..8b8589a 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -1104,6 +1104,43 @@ impl IdentityManager { } } + + 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); + + } + + 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){ + usrrolelock.swap_remove(indx); + //return ChangeResult::Success("Demoted successfully".to_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); + 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> @@ -1298,15 +1335,16 @@ impl IdentityManager { 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(); - } + // // 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()) { @@ -1482,15 +1520,18 @@ impl IdentityManager { // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); authusrroles.push(UserRole::Mod(channel.clone())); - let mut srulock = self.special_roles_users.write().await; - srulock - .get_mut(&trgchatter) - .expect("Error getting roles") - // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at - .write().await - .push(UserRole::Mod(channel.clone())); + // let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + // .write().await + // .push(UserRole::Mod(channel.clone())); + + self.add_role(trgchatter.clone(), UserRole::Mod(channel.clone())).await; } + _ => (), } } // mut block @@ -1531,28 +1572,31 @@ impl IdentityManager { return ChangeResult::NoChange("Already has the role".to_string()); } else { - { - let mut srulock = self.special_roles_users.write().await; + // { + // 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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } + // srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); + // botinstance::botlog::trace(&format!("Ensuring Target Chatter in Roles > {:?}",srulock.entry(trgchatter.clone())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.affirm_chatter_in_db(trgchatter.clone()).await; - { + // { - let mut srulock = self.special_roles_users.write().await; + // let mut srulock = self.special_roles_users.write().await; - srulock - .get_mut(&trgchatter) - .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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } + // srulock + // .get_mut(&trgchatter) + // .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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.add_role(trgchatter.clone(), UserRole::BotAdmin).await; + return ChangeResult::Success("Promotion Successful".to_string()); @@ -1598,27 +1642,30 @@ impl IdentityManager { || 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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } - { - // 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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } + // // 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.affirm_chatter_in_db(trgchatter.clone()).await; + + // { + // // 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.add_role(trgchatter.clone(), UserRole::Mod(trg_chnl.clone())).await; return ChangeResult::Success(String::from("Promotion Successful")); @@ -1645,39 +1692,47 @@ impl IdentityManager { || 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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } - { // Adds the requested role for the user - let mut srulock = self.special_roles_users.write().await; - srulock - .get_mut(&trgchatter) - .expect("Error getting roles") - // !! [ ] 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())), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } - { // Removes the lower role (mod) from the user - let mut srulock = self.special_roles_users.write().await; - let mut uroleslock = srulock - .get_mut(&trgchatter) - .expect("Error getting roles") - .write().await; - if let Some(indx) = uroleslock.iter().position(|value| *value == UserRole::Mod(trg_chnl.clone())){ - uroleslock.swap_remove(indx); - } + // { // 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + self.affirm_chatter_in_db(trgchatter.clone()).await; - botinstance::botlog::trace(&format!("Removing lower role > {:?}",uroleslock), - Some("identity.rs > promote()".to_string()), None); - Log::flush(); - } + // { // Adds the requested role for the user + // let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] 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())), + // Some("identity.rs > promote()".to_string()), None); + // Log::flush(); + // } + + 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; + // let mut uroleslock = srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // .write().await; + // if let Some(indx) = uroleslock.iter().position(|value| *value == UserRole::Mod(trg_chnl.clone())){ + // uroleslock.swap_remove(indx); + // } + + // 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; return ChangeResult::Success(String::from("Promotion Successful")); @@ -2097,13 +2152,16 @@ impl IdentityManager { // (*authusrroles_mut).push(UserRole::Mod(channel.clone())); authusrroles.push(UserRole::Mod(channel.clone())); - let mut srulock = self.special_roles_users.write().await; - srulock - .get_mut(&trgchatter) - .expect("Error getting roles") - // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at - .write().await - .push(UserRole::Mod(channel.clone())); + // [ ] below pushes mod to authorizer + // let mut srulock = self.special_roles_users.write().await; + // srulock + // .get_mut(&trgchatter) + // .expect("Error getting roles") + // // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + // .write().await + // .push(UserRole::Mod(channel.clone())); + + self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())).await; } _ => (), @@ -2129,34 +2187,45 @@ impl IdentityManager { authusrroles.contains(&UserRole::SupMod(channel.clone())) ) && trgusrroles.contains(&UserRole::Mod(channel.clone())) { - 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()) - } + // // [ ] 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())) - { - 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()) - } + + + { + // [ ] 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())) { -- 2.46.1 From 2adceffd59fc083228d2f7b907678b74bddf7d15 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Mon, 19 Feb 2024 21:04:01 -0500 Subject: [PATCH 37/39] identity test fns --- src/core/identity.rs | 271 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 268 insertions(+), 3 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index 8b8589a..1b7e908 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -18,7 +18,7 @@ use crate::core::botinstance::ArcBox; use std::rc::Rc; use std::cell::RefCell; -use std::sync::{Arc}; +use std::sync::Arc; use tokio::sync::RwLock; use casual_logger::{Level,Log}; @@ -1082,7 +1082,7 @@ pub enum ChatBadge { Mod, } - +#[derive(Debug,PartialEq, Eq)] pub enum ChangeResult { Success(String), Failed(String), @@ -1528,7 +1528,8 @@ impl IdentityManager { // .write().await // .push(UserRole::Mod(channel.clone())); - self.add_role(trgchatter.clone(), UserRole::Mod(channel.clone())).await; + self.affirm_chatter_in_db(authorizer.clone()).await; + self.add_role(authorizer.clone(), UserRole::Mod(channel.clone())).await; } @@ -2349,3 +2350,267 @@ impl IdentityManager { } + + +#[cfg(test)] +mod core_identity { + + + use casual_logger::Extension; + + use super::*; + + #[test] + fn user_role_identity() { + Log::set_file_ext(Extension::Log); + // 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()))); + } + + #[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 + let channel = Some(ChType::Channel("twitchchanneltest".to_string())); + let trgchatter = "regularChatter".to_string(); + 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; + + 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 + let channel = Some(ChType::Channel("broadcasterer".to_string())); + let trgchatter = "regularChatter".to_string(); + 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; + + assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + + 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; + + assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + + 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"))); + + + } + + + + #[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.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(); + let authorizer = supchatter; + let authorizer_badge = &Some(ChatBadge::Broadcaster); + let channel = Some(ChType::Channel(broadcaster.clone())); + 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; + + assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + + 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; + + // assert_eq!(rslt, ChangeResult::Success("Promotion Successful".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 + + // [x] Create BotAdmin first + + let botadmin = "botadministrator".to_string(); + 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; + + assert!(rslt.contains(&UserRole::BotAdmin)); + + + // [x] SupMod Attempts to Promote Chatter to SupMod + + // let broadcaster = "broadcasterer".to_string(); + let authorizer = botadmin; + let authorizer_badge = botadmin_badge; + let channel = Some(ChType::Channel("somechannel".to_string())); + 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; + + assert_eq!(rslt, ChangeResult::Success("Promotion Successful".to_string())); + + 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; + + // 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; + + 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"))); + + + } + + + #[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(); + // let supmod_badge = &None; + 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; + + let rslt = test_id_mgr.getspecialuserroles(supmod.clone(), channel.clone()).await; + + assert!(rslt.contains(&UserRole::SupMod(channel.clone().unwrap()))); + + // [x] Create regular mod + + let regmod = "moder".to_string(); + // let supmod_badge = &None; + // 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; + + let rslt = test_id_mgr.getspecialuserroles(regmod.clone(), channel.clone()).await; + + assert!(rslt.contains(&UserRole::Mod(channel.clone().unwrap()))); + + // [x] Regular mod attempts to demote a supmod + + let authorizer = regmod.clone(); + let authorizer_badge = &None; + let trgchatter = supmod.clone(); + + + 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())); + + // [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())); + + + + } + + +} -- 2.46.1 From 66e82de28ff7397cbcfdac7a52a9f75c8859a7ee Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sat, 24 Feb 2024 22:31:12 -0500 Subject: [PATCH 38/39] lib.rs --- Cargo.toml | 7 ++++++- src/lib.rs | 3 +++ src/main.rs | 17 +++++++++++------ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 3b8edd4..70c9e9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,9 @@ twitch-irc = "5.0.1" rand = { version = "0.8.5", features = [] } futures = "0.3" async-trait = "0.1.77" -casual_logger = "0.6.5" \ No newline at end of file +casual_logger = "0.6.5" + + +[lib] +name = "botLib" +path = "src/lib.rs" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..15558d2 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ + +pub mod core; +pub mod modules; diff --git a/src/main.rs b/src/main.rs index 316483e..afd1526 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,17 @@ -pub mod core; -pub mod modules; +// pub mod core; +// pub mod modules; +//use myLib; +//pub mod lib; use std::process::Output; -use crate::core::botinstance::ArcBox; +// use crate::core::botinstance::ArcBox; +use botLib::core::botinstance::ArcBox; + +use botLib::core::botinstance::{self,BotInstance}; +// use core::botinstance::{self,BotInstance}; -use crate::core::botinstance::{self,BotInstance}; use casual_logger::Extension; use tokio::sync::RwLock; use std::sync::Arc; @@ -32,12 +37,12 @@ pub async fn main() { for (_,acts) in &*a { for act in acts { match act { - crate::core::botmodules::BotAction::C(b) => { + 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); }, - crate::core::botmodules::BotAction::L(l) => { + 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); -- 2.46.1 From 0a7a4b539a1af3094ddaa08c60ecbf4acdf2b861 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 25 Feb 2024 10:40:54 -0500 Subject: [PATCH 39/39] rustfmt --- src/core.rs | 2 +- src/core/botinstance.rs | 731 +++++----- src/core/botmodules.rs | 299 ++-- src/core/identity.rs | 2734 ++++++++++++++++++++---------------- src/core/ratelimiter.rs | 38 +- src/lib.rs | 1 - src/main.rs | 45 +- src/modules.rs | 10 +- src/modules/experiments.rs | 107 +- 9 files changed, 2093 insertions(+), 1874 deletions(-) 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), + ); +} -- 2.46.1