This commit is contained in:
ModulatingForce 2024-02-25 10:40:54 -05:00
parent 66e82de28f
commit 0a7a4b539a
9 changed files with 2093 additions and 1874 deletions

View file

@ -1,7 +1,7 @@
pub mod botinstance; pub mod botinstance;
pub mod ratelimiter;
pub mod botmodules; pub mod botmodules;
pub mod identity; pub mod identity;
pub mod ratelimiter;
// pub fn init() -> () // pub fn init() -> ()
// { // {

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
use core::{panic}; use core::panic;
use std::error::Error; use std::error::Error;
use std::collections::HashMap; 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 // Important to use tokios Mutex here since std Mutex doesn't work with async functions
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::core::botinstance::{self, botlog, BotInstance}; use crate::core::botinstance::{self, botlog, BotInstance};
use std::rc::Rc; use std::rc::Rc;
// use tokio::sync::RwLock; // use tokio::sync::RwLock;
use async_trait::async_trait; 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 { pub struct ModulesManager {
statusdb: HashMap<ModType,Vec<ModStatusType>>, statusdb: HashMap<ModType,Vec<ModStatusType>>,
botactions: HashMap<ModType,Vec<BotAction>>, botactions: HashMap<ModType,Vec<BotAction>>,
} }
- statusdb: HashMap<ModType,Vec<ModStatusType>> - Defines Modules and their ModStatusType (e.g., Enabled at an Instance level, Disabled at a Channel Level) - statusdb: HashMap<ModType,Vec<ModStatusType>> - Defines Modules and their ModStatusType (e.g., Enabled at an Instance level, Disabled at a Channel Level)
- botactions: HashMap<ModType,Vec<BotAction>> - Defines Modules and their BotActions (e.g., BotCommand , Listener, Routine) - botactions: HashMap<ModType,Vec<BotAction>> - Defines Modules and their BotActions (e.g., BotCommand , Listener, Routine)
Example Example
{ {
ModulesManager { ModulesManager {
statusdb: {BotModule("experiments 004"): [Enabled(Instance)]}, statusdb: {BotModule("experiments 004"): [Enabled(Instance)]},
botactions: {BotModule("experiments 004"): [C(BotCommand { module: BotModule("experiments 004"), command: "DUPCMD4", alias: ["DUPALIAS4A", "DUPALIAS4B"], help: "DUPCMD4 tester" })]} } 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 { pub enum ModType {
BotModule(String), BotModule(String),
} }
pub use ModType::BotModule; pub use ModType::BotModule;
// #[derive(Debug, PartialEq, Eq, Hash, Clone)] // #[derive(Debug, PartialEq, Eq, Hash, Clone)]
@ -62,13 +58,12 @@ pub use ModType::BotModule;
use botinstance::ChType; use botinstance::ChType;
pub use ChType::Channel;
use twitch_irc::message::PrivmsgMessage; use twitch_irc::message::PrivmsgMessage;
pub use ChType::Channel;
use self::bot_actions::actions_util; use self::bot_actions::actions_util;
use self::bot_actions::actions_util::BotAR; use self::bot_actions::actions_util::BotAR;
#[derive(Debug)] #[derive(Debug)]
enum StatusLvl { enum StatusLvl {
Instance, Instance,
@ -82,246 +77,223 @@ pub enum ModStatusType {
} }
// #[derive(Clone)] // #[derive(Clone)]
pub enum BotAction pub enum BotAction {
{ C(BotCommand),
C(BotCommand),
L(Listener), L(Listener),
R(Routine), R(Routine),
} }
impl BotAction { impl BotAction {
pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () {
pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> ()
{
match self { match self {
BotAction::L(a) => a.execute(m,n).await, BotAction::L(a) => a.execute(m, n).await,
BotAction::C(a) => a.execute(m,n).await, BotAction::C(a) => a.execute(m, n).await,
_ => (), _ => (),
} }
} }
} }
#[async_trait] #[async_trait]
pub trait BotActionTrait pub trait BotActionTrait {
{ async fn add_to_bot(self, bot: BotInstance);
async fn add_to_bot(self, bot:BotInstance); async fn add_to_modmgr(self, modmgr: Arc<ModulesManager>);
async fn add_to_modmgr(self,modmgr:Arc<ModulesManager>);
} }
// #[derive(Clone)] // #[derive(Clone)]
pub struct BotCommand { pub struct BotCommand {
pub module : ModType, pub module: ModType,
pub command : String, // command call name pub command: String, // command call name
pub alias : Vec<String>, // String of alternative names pub alias: Vec<String>, // String of alternative names
// bot_prefix : char, // although should be global? // bot_prefix : char, // although should be global?
pub exec_body : bot_actions::actions_util::ExecBody, pub exec_body: bot_actions::actions_util::ExecBody,
pub help : String, pub help: String,
pub required_roles : Vec<identity::UserRole>, pub required_roles: Vec<identity::UserRole>,
} }
impl BotCommand impl BotCommand {
{ pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () {
pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () { ((*self).exec_body)(m, n).await;
((*self).exec_body)(m,n).await;
} }
} }
#[async_trait] #[async_trait]
impl BotActionTrait for BotCommand impl BotActionTrait for BotCommand {
{ async fn add_to_bot(self, bot: BotInstance) {
async fn add_to_bot(self, bot:BotInstance) {
self.add_to_modmgr(bot.botmodules).await; self.add_to_modmgr(bot.botmodules).await;
} }
// async fn add_to_modmgr(self, modmgr:Arc<Mutex<ModulesManager>>) { // async fn add_to_modmgr(self, modmgr:Arc<Mutex<ModulesManager>>) {
async fn add_to_modmgr(self, modmgr:Arc<ModulesManager>) { async fn add_to_modmgr(self, modmgr: Arc<ModulesManager>) {
modmgr.add_botaction(self.module.clone(), BotAction::C(self)).await modmgr
.add_botaction(self.module.clone(), BotAction::C(self))
.await
} }
} }
pub mod bot_actions { pub mod bot_actions {
pub mod actions_util { pub mod actions_util {
use std::future::Future;
use std::boxed::Box; use std::boxed::Box;
use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use crate::core::botinstance::{BotInstance, BotManagers, Chat}; use crate::core::botinstance::{BotInstance, BotManagers, Chat};
use twitch_irc::message::PrivmsgMessage;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::{Arc}; use std::sync::Arc;
use twitch_irc::message::PrivmsgMessage;
// use futures::lock::Mutex; // use futures::lock::Mutex;
// Important to use tokios Mutex here since std Mutex doesn't work with async functions // 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<Mutex<BotInstance>>; pub type BotAM = Arc<Mutex<BotInstance>>;
pub type BotAR = Arc<RwLock<BotInstance>>; pub type BotAR = Arc<RwLock<BotInstance>>;
pub type ExecBody = Box<dyn Fn(BotAR,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>; pub type ExecBody = Box<
dyn Fn(BotAR, PrivmsgMessage) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync,
>;
pub fn asyncbox<T>(f: fn(BotAR,PrivmsgMessage) -> T) -> ExecBody pub fn asyncbox<T>(f: fn(BotAR, PrivmsgMessage) -> T) -> ExecBody
where where
T: Future<Output=()> + Send + 'static T: Future<Output = ()> + 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 struct Listener pub name: String,
{ pub exec_body: bot_actions::actions_util::ExecBody,
pub module : ModType, pub help: String,
pub name : String,
pub exec_body : bot_actions::actions_util::ExecBody,
pub help : String
} }
impl Listener impl Listener {
{ pub async fn execute(&self, m: BotAR, n: PrivmsgMessage) -> () {
((*self).exec_body)(m, n).await;
pub async fn execute(&self,m:BotAR,n:PrivmsgMessage) -> () {
((*self).exec_body)(m,n).await;
} }
} }
#[async_trait] #[async_trait]
impl BotActionTrait for Listener impl BotActionTrait for Listener {
{ async fn add_to_bot(self, bot: BotInstance) {
async fn add_to_bot(self, bot:BotInstance) {
// println!("Adding action to bot"); // println!("Adding action to bot");
// Log::trace("Adding action to bot"); // Log::trace("Adding action to bot");
botinstance::botlog::trace("Adding action to bot", botinstance::botlog::trace(
Some("BotModules > BotActionTrait > add_to_bot()".to_string()) , "Adding action to bot",
None); Some("BotModules > BotActionTrait > add_to_bot()".to_string()),
None,
);
self.add_to_modmgr(bot.botmodules).await; self.add_to_modmgr(bot.botmodules).await;
} }
async fn add_to_modmgr(self, modmgr:Arc<ModulesManager>) { async fn add_to_modmgr(self, modmgr: Arc<ModulesManager>) {
// let modmgr = *modmgr.lock().await; // let modmgr = *modmgr.lock().await;
// println!("Adding action to module manager"); // 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", botinstance::botlog::trace(
Some("BotModules > BotActionTrait > add_to_bot()".to_string()) , "Adding action to module manager",
None); 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)] #[derive(Debug)]
struct Routine {} struct Routine {}
// #[derive(Clone)] // #[derive(Clone)]
pub struct ModulesManager pub struct ModulesManager {
{ statusdb: Arc<RwLock<HashMap<ModType, Vec<ModStatusType>>>>,
statusdb: Arc<RwLock<HashMap<ModType,Vec<ModStatusType>>>>, pub botactions: Arc<RwLock<HashMap<ModType, Vec<BotAction>>>>,
pub botactions: Arc<RwLock<HashMap<ModType,Vec<BotAction>>>>,
} }
/* /*
statusdb statusdb
<HashMap <HashMap
<ModType, <-- e.g., BotModule(String::from("experiments001")) <ModType, <-- e.g., BotModule(String::from("experiments001"))
Vec<ModStatusType> <-- shows Enabled/Disabled per Status level Vec<ModStatusType> <-- shows Enabled/Disabled per Status level
botactions botactions
HashMap< HashMap<
ModType, <-- e.g., BotModule(String::from("experiments001")) ModType, <-- e.g., BotModule(String::from("experiments001"))
Vec<BotAction>> BotCommand, Listener Vec<BotAction>> BotCommand, Listener
*/ */
impl ModulesManager impl ModulesManager {
{ pub async fn init() -> Arc<ModulesManager> {
pub async fn init() -> Arc<ModulesManager>
{
let m = HashMap::new(); let m = HashMap::new();
let act = HashMap::new(); let act = HashMap::new();
let mut mgr = ModulesManager { let mut mgr = ModulesManager {
statusdb : Arc::new(RwLock::new(m)), statusdb: Arc::new(RwLock::new(m)),
botactions : Arc::new(RwLock::new(act)), botactions: Arc::new(RwLock::new(act)),
}; };
// :: [x] initialize core modules // :: [x] initialize core modules
// println!("ModulesManager > init() > Adding modules"); // println!("ModulesManager > init() > Adding modules");
botlog::debug("ModulesManager > init() > Adding modules", botlog::debug(
"ModulesManager > init() > Adding modules",
Some("ModulesManager > init()".to_string()), Some("ModulesManager > init()".to_string()),
None None,
); );
let mgra = Arc::new(mgr); let mgra = Arc::new(mgr);
crate::core::identity::init(Arc::clone(&mgra)).await; crate::core::identity::init(Arc::clone(&mgra)).await;
crate::modules::init(Arc::clone(&mgra)).await; crate::modules::init(Arc::clone(&mgra)).await;
// println!(">> Modules Manager : End of Init"); // 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()), Some("ModulesManager > init()".to_string()),
None None,
); );
mgra mgra
} }
pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { pub fn modstatus(&self, _: ModType, _: ChType) -> ModStatusType {
// Example usage : botmanager.modstatus( // Example usage : botmanager.modstatus(
// BotModule("GambaCore"), // BotModule("GambaCore"),
// Channel("modulatingforce") // 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 // but also validates based on wheher the module is disabled at a bot instance
// level as well // level as well
ModStatusType::Enabled(StatusLvl::Instance) 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 // enables or disables based on current status
ModStatusType::Enabled(StatusLvl::Instance) ModStatusType::Enabled(StatusLvl::Instance)
} }
pub fn setstatus(&self, _: ModType, _: ModStatusType) -> Result<&str, Box<dyn Error>> {
pub fn setstatus(&self, _:ModType, _:ModStatusType) -> Result<&str,Box<dyn Error>> {
// sets the status based given ModSatusType // sets the status based given ModSatusType
// e.g., b.setstatus(BodModule("GambaCore"), Enabled(Channel("modulatingforce"))).expect("ERROR") // e.g., b.setstatus(BodModule("GambaCore"), Enabled(Channel("modulatingforce"))).expect("ERROR")
Ok("") 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"); // println!("Add botaction called");
botlog::trace("Add botaction called", botlog::trace(
Some("ModulesManager > init()".to_string()), "Add botaction called",
None Some("ModulesManager > init()".to_string()),
None,
); );
/* /*
adds a BotAction to the Modules Manager - This will require a BotModule passed as well adds a BotAction to the Modules Manager - This will require a BotModule passed as well
This will including the logic of a valid add 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 -- 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 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" , 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 { // let newlistener = Listener {
@ -341,20 +313,15 @@ impl ModulesManager
// help : String::from("This will listen and react to sock randomly"), // 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 // As a Demonstration, the listener's Module is added and Enabled at Instance level
// [x] Before Adding, validate the following :
// [x] Before Adding, validate the following : // - If BotAction to Add is a BotCommand , In Module Manager DB (botactions),
// - 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 // Check All Other BotAction Command Names & Aliases to ensure they don't conflict
async fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option<ModType> async fn find_conflict_module(mgr: &ModulesManager, act: &BotAction) -> Option<ModType> {
{
// Some(BotModule(String::from("GambaCore"))) // Some(BotModule(String::from("GambaCore")))
// match act { // match act {
// BotAction::C(c) => { // BotAction::C(c) => {
// Some(BotModule(String::from("GambaCore"))) // Some(BotModule(String::from("GambaCore")))
@ -364,15 +331,12 @@ impl ModulesManager
// } // }
if let BotAction::C(incmd) = act { if let BotAction::C(incmd) = act {
// let n = & mgr.botactions; // let n = & mgr.botactions;
let d = mgr.botactions.read().await; let d = mgr.botactions.read().await;
let d = &(*d); let d = &(*d);
for (module,moduleactions) in d { for (module, moduleactions) in d {
for modact in moduleactions.iter() { for modact in moduleactions.iter() {
if let BotAction::C(dbcmd) = &modact { if let BotAction::C(dbcmd) = &modact {
// At this point, there is an command incmd and looked up dbcmd // 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(incmd); // for some reason I keep getting issues
//return Some(BotModule(String::from("GambaCore"))); // works //return Some(BotModule(String::from("GambaCore"))); // works
return Some(module.clone()); // works return Some(module.clone()); // works
// return Some(dbcmd.clone()); // return Some(dbcmd.clone());
} }
for a in &dbcmd.alias { for a in &dbcmd.alias {
if incmd.command.to_lowercase() == a.to_lowercase() { if incmd.command.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works 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() { if inalias.to_lowercase() == dbcmd.command.to_lowercase() {
// Returning State - with the identified module // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works return Some(module.clone()); // works
}
}
for a in &dbcmd.alias { for a in &dbcmd.alias {
if inalias.to_lowercase() == a.to_lowercase() { if inalias.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works 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 // for all other scenarios (e.g., Listener, Routine), find no conflicts
None None
} }
// if let probmod = find_conflict_module(&self, &in_action) { // if let probmod = find_conflict_module(&self, &in_action) {
@ -441,7 +394,10 @@ impl ModulesManager
// } // }
match find_conflict_module(&self, &in_action).await { 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 {:?} ; 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 => (), None => (),
} }
@ -456,30 +412,28 @@ impl ModulesManager
let mut a = self.botactions.write().await; let mut a = self.botactions.write().await;
let modactions = a let modactions = a
//.entry( BotModule(String::from("experiments"))) //.entry( BotModule(String::from("experiments")))
.entry( in_module.clone()) .entry(in_module.clone())
.or_insert(Vec::new()); .or_insert(Vec::new());
// modactions.push(BotAction::L(newlistener)); // modactions.push(BotAction::L(newlistener));
modactions.push(in_action); modactions.push(in_action);
// println!(">> Modules Manager : Called Add bot Action"); // println!(">> Modules Manager : Called Add bot Action");
botlog::trace(">> Modules Manager : Called Add bot Action", botlog::trace(
Some("ModulesManager > init()".to_string()), ">> Modules Manager : Called Add bot Action",
None Some("ModulesManager > init()".to_string()),
None,
); );
// println!("add_botaction - botactions size : {}",modactions.len()); // println!("add_botaction - botactions size : {}",modactions.len());
botlog::trace(&format!("add_botaction - botactions size : {}",modactions.len()), botlog::trace(
Some("ModulesManager > init()".to_string()), &format!("add_botaction - botactions size : {}", modactions.len()),
None Some("ModulesManager > init()".to_string()),
None,
); );
} }
fn statuscleanup(&self, _: Option<ChType>) -> () {
// internal cleans up statusdb . For example :
fn statuscleanup(&self,_:Option<ChType>) -> () {
// internal cleans up statusdb . For example :
// - remove redudancies . If we see several Enabled("m"), only keep 1x // - 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") // - 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 // 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 // Passing None to chnl may be a heavy operation, as this will review and look at the whole table
() ()
} }
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,8 @@
use std::time::Instant; use std::time::Instant;
const TIME_THRESHOLD_S: u64 = 30; const TIME_THRESHOLD_S: u64 = 30;
const MSG_THRESHOLD: u32 = 20; const MSG_THRESHOLD: u32 = 20;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RateLimiter { pub struct RateLimiter {
timer: Instant, timer: Instant,
@ -13,10 +11,9 @@ pub struct RateLimiter {
pub enum LimiterResp { pub enum LimiterResp {
Allow, // when it's evaluated to be within limits Allow, // when it's evaluated to be within limits
Skip, // as outside of rate limits Skip, // as outside of rate limits
} }
impl RateLimiter { impl RateLimiter {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -25,24 +22,23 @@ impl RateLimiter {
} }
} }
pub fn check_limiter(&mut self) -> LimiterResp { pub fn check_limiter(&mut self) -> LimiterResp {
if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S {
if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S { // # [x] elapsed >= TIME_THRESHOLD_S
// # [x] elapsed >= TIME_THRESHOLD_S self.timer = Instant::now();
self.timer = Instant::now(); self.msgcounter = 0;
self.msgcounter = 0; LimiterResp::Allow
LimiterResp::Allow } else if self.msgcounter < MSG_THRESHOLD {
} else if self.msgcounter < MSG_THRESHOLD { // # [x] elapsed < TIME_THRESHOLD_S && msgcounter < MSG_THRESHOLD
// # [x] elapsed < TIME_THRESHOLD_S && msgcounter < MSG_THRESHOLD LimiterResp::Allow
LimiterResp::Allow // } else if self.msgcounter >= MSG_THRESHOLD {
// } else if self.msgcounter >= MSG_THRESHOLD { } else {
} else { // # [x] elapsed < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD
// # [x] elapsed < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD LimiterResp::Skip
LimiterResp::Skip }
} }
}
pub fn increment_counter(&mut self) -> () { pub fn increment_counter(&mut self) -> () {
self.msgcounter += 1; self.msgcounter += 1;
} }
} }

View file

@ -1,3 +1,2 @@
pub mod core; pub mod core;
pub mod modules; pub mod modules;

View file

@ -1,5 +1,3 @@
// pub mod core; // pub mod core;
// pub mod modules; // pub mod modules;
//use myLib; //use myLib;
@ -9,22 +7,21 @@ use std::process::Output;
// use crate::core::botinstance::ArcBox; // use crate::core::botinstance::ArcBox;
use botLib::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 core::botinstance::{self,BotInstance};
use casual_logger::Extension; use casual_logger::Extension;
use tokio::sync::RwLock;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock;
pub type BotAR = Arc<RwLock<BotInstance>>; pub type BotAR = Arc<RwLock<BotInstance>>;
use casual_logger::{Level,Log}; use casual_logger::{Level, Log};
#[tokio::main] #[tokio::main]
pub async fn main() { pub async fn main() {
Log::set_file_ext(Extension::Log); Log::set_file_ext(Extension::Log);
Log::set_level(Level::Trace); Log::set_level(Level::Trace);
// Log::set_level(Level::Notice); // Log::set_level(Level::Notice);
let bot = BotInstance::init().await; let bot = BotInstance::init().await;
@ -34,28 +31,39 @@ pub async fn main() {
let a = a.read().await; let a = a.read().await;
// let a = *a; // let a = *a;
for (_,acts) in &*a { for (_, acts) in &*a {
for act in acts { for act in acts {
match act { match act {
botLib::core::botmodules::BotAction::C(b) => { botLib::core::botmodules::BotAction::C(b) => {
// println!("bot actiions: {}",b.command) // 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); botinstance::botlog::info(
}, &format!("bot actions: {}", b.command),
Some("main()".to_string()),
None,
);
}
botLib::core::botmodules::BotAction::L(l) => { botLib::core::botmodules::BotAction::L(l) => {
// println!("bot actiions: {}",l.name) // 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); botinstance::botlog::info(
}, &format!("bot actions: {}", l.name),
Some("main()".to_string()),
None,
);
}
_ => { _ => {
// println!("Not a valid match??") // 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); botinstance::botlog::info(
}, "Not a valid match??",
Some("main()".to_string()),
None,
);
}
} }
} }
}; }
// println!("Starting runner.."); // println!("Starting runner..");
// Log::notice("Starting Bot Runner"); // Log::notice("Starting Bot Runner");
@ -70,6 +78,5 @@ pub async fn main() {
// let msg = Log::fatal("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); let a = botinstance::botlog::fatal("ERROR : EXIT Game loop", Some("main()".to_string()), None);
panic!("{}",a); panic!("{}", a);
}
}

View file

@ -10,22 +10,20 @@ pub use crate::core::botmodules::ModulesManager;
// use crate::core::botinstance; // use crate::core::botinstance;
pub use crate::core::botinstance::BotInstance; pub use crate::core::botinstance::BotInstance;
use std::sync::Arc;
use futures::lock::Mutex; use futures::lock::Mutex;
use std::sync::Arc;
// [ ] Load submodules // [ ] Load submodules
mod experiments; mod experiments;
// [ ] init() function that accepts bot instance - this is passed to init() on submodules // [ ] init() function that accepts bot instance - this is passed to init() on submodules
pub async fn init(mgr:Arc<ModulesManager>) pub async fn init(mgr: Arc<ModulesManager>) {
{
// Modules initializer loads modules into the bot // Modules initializer loads modules into the bot
// this is achieved by calling submodules that also have fn init() defined // this is achieved by calling submodules that also have fn init() defined
experiments::init(mgr).await experiments::init(mgr).await
//(); //();
} }

View file

@ -1,9 +1,8 @@
/* /*
Submodules - Submodules -
- should have definitions of BotAction that will be added to a bit - 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 : - will define one init(&BotInstance) take within the module that will contain :
- BotAction definitions that each call &BotInstance module manager to add itself - BotAction definitions that each call &BotInstance module manager to add itself
@ -14,28 +13,23 @@
use std::future::Future; 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::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 futures::lock::Mutex;
use twitch_irc::message::PrivmsgMessage; use twitch_irc::message::PrivmsgMessage;
use crate::core::identity; use crate::core::identity;
use rand::Rng; use rand::Rng;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
// pub fn init(mgr:&mut ModulesManager) // pub fn init(mgr:&mut ModulesManager)
pub async fn init(mgr:Arc<ModulesManager>) pub async fn init(mgr: Arc<ModulesManager>) {
{
// BotCommand { // BotCommand {
// module : BotModule(String::from("experiments 004")), // module : BotModule(String::from("experiments 004")),
// command : String::from("test1"), // command call name // command : String::from("test1"), // command call name
@ -48,81 +42,78 @@ pub async fn init(mgr:Arc<ModulesManager>)
// ], // ],
// }.add_to_modmgr(mgr); // }.add_to_modmgr(mgr);
let botc1 = BotCommand { let botc1 = BotCommand {
module : BotModule(String::from("experiments001")), module: BotModule(String::from("experiments001")),
command : String::from("test1"), // command call name command: String::from("test1"), // command call name
alias : vec![String::from("tester1"),String::from("testy1")], // String of alternative names alias: vec![String::from("tester1"), String::from("testy1")], // String of alternative names
exec_body : actions_util::asyncbox(testy) , exec_body: actions_util::asyncbox(testy),
help : String::from("Test Command tester"), help: String::from("Test Command tester"),
required_roles : vec![ required_roles: vec![identity::UserRole::BotAdmin],
identity::UserRole::BotAdmin
],
}; };
botc1.add_to_modmgr(Arc::clone(&mgr)).await; botc1.add_to_modmgr(Arc::clone(&mgr)).await;
let list1 = Listener { let list1 = Listener {
module : BotModule(String::from("experiments001")), module: BotModule(String::from("experiments001")),
name : String::from("GoodGirl Listener"), name: String::from("GoodGirl Listener"),
exec_body : actions_util::asyncbox(good_girl) , exec_body: actions_util::asyncbox(good_girl),
help : String::from("") help: String::from(""),
}; };
list1.add_to_modmgr(Arc::clone(&mgr)).await; 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"); // println!("In GoodGirl() Listener");
// Change below from debug to trace if required later // Change below from debug to trace if required later
botinstance::botlog::debug("In GoodGirl() Listener", botinstance::botlog::debug(
Some("experiments > goodgirl()".to_string()) , "In GoodGirl() Listener",
Some(&msg)); Some("experiments > goodgirl()".to_string()),
Some(&msg),
);
//println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); //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) // - 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 // - More Info : https://rust-random.github.io/rand/rand/trait.Rng.html#method.gen_ratio
if msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase()
if msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase() || msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase() // && msg.message_text.contains("GoodGirl") || msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase()
// && msg.message_text.contains("GoodGirl")
{ {
// chat.say_in_reply_to(&msg,String::from("GoodGirl")).await; // chat.say_in_reply_to(&msg,String::from("GoodGirl")).await;
//if rng.gen_ratio(1,5) { //if rng.gen_ratio(1,5) {
// println!("In GoodGirl() > Pausechamp"); // println!("In GoodGirl() > Pausechamp");
botinstance::botlog::debug("In GoodGirl() > Pausechamp", botinstance::botlog::debug(
Some("experiments > goodgirl()".to_string()) , "In GoodGirl() > Pausechamp",
Some(&msg)); Some("experiments > goodgirl()".to_string()),
let rollwin = rand::thread_rng().gen_ratio(1,8); Some(&msg),
);
let rollwin = rand::thread_rng().gen_ratio(1, 8);
if rollwin { if rollwin {
// println!("In GoodGirl() > Win"); // println!("In GoodGirl() > Win");
botinstance::botlog::debug("In GoodGirl() > Win", botinstance::botlog::debug(
Some("experiments > goodgirl()".to_string()) , "In GoodGirl() > Win",
Some(&msg)); Some("experiments > goodgirl()".to_string()),
let a = Arc::clone(&bot); Some(&msg),
let botlock = a.read().await; );
botlock.botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await; 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 println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call
botinstance::botlog::debug("testy triggered!", botinstance::botlog::debug(
Some("experiments > testy()".to_string()) , "testy triggered!",
Some(&msg)); Some("experiments > testy()".to_string()),
Some(&msg),
} );
}