cargo-fmt
This commit is contained in:
parent
8eaa56dd0c
commit
cd69a35ec1
22 changed files with 1140 additions and 1075 deletions
forcebot_core/src
bin
botcore.rsbotcore
custom_mods.rscustom_mods
lib.rsmoderator_reactor/src
new_empty_bot/src
simple_command_bot/src
simple_debug_listener/src
simple_module_example/src
|
@ -18,13 +18,13 @@
|
|||
//! - Get a Bot Chat Token here - <https://twitchtokengenerator.com>
|
||||
//! - More Info - <https://dev.twitch.tv/docs/authentication>
|
||||
|
||||
use forcebot_core::{custom_mods::{debug, guest_badge, pyramid}, Bot};
|
||||
|
||||
|
||||
use forcebot_core::{
|
||||
custom_mods::{debug, guest_badge, pyramid},
|
||||
Bot,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -34,13 +34,10 @@ pub async fn main() {
|
|||
bot.load_module(pyramid::create_module()).await;
|
||||
bot.load_module(debug::create_module()).await;
|
||||
|
||||
|
||||
/* 3. Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub mod funbot_objs {
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -51,7 +48,8 @@ pub mod funbot_objs {
|
|||
pub fn create_module() -> Module {
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["besty".to_string()],
|
||||
"Now Aware of besty xdd666 ".to_string());
|
||||
"Now Aware of besty xdd666 ".to_string(),
|
||||
);
|
||||
|
||||
custom_mod.load_command(create_cmd_test());
|
||||
// custom_mod.set_status_by_default(Status::Disabled);
|
||||
|
@ -61,13 +59,19 @@ pub mod funbot_objs {
|
|||
|
||||
/// Create a Command Object
|
||||
fn create_cmd_test() -> Command {
|
||||
|
||||
let mut cmd = Command::new(vec!["remind besty".to_string()],"annytfYandere ".to_string());
|
||||
let mut cmd = Command::new(
|
||||
vec!["remind besty".to_string()],
|
||||
"annytfYandere ".to_string(),
|
||||
);
|
||||
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _= bot.chat.lock().await.say_in_reply_to(
|
||||
&msg, "annytfYandere he's mine".to_string()).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, "annytfYandere he's mine".to_string())
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -79,6 +83,5 @@ pub mod funbot_objs {
|
|||
cmd.set_min_badge(Badge::Vip);
|
||||
|
||||
cmd
|
||||
|
||||
}
|
||||
}
|
|
@ -14,11 +14,9 @@ use forcebot_core::Bot;
|
|||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* 1. Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
/* 2. Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ use forcebot_core::Bot;
|
|||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -30,29 +29,23 @@ pub async fn main() {
|
|||
|
||||
/* Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub mod custom_mod {
|
||||
use std::sync::Arc;
|
||||
|
||||
use forcebot_core::{execution_async, Badge, Bot, Command, Module};
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
|
||||
/// Module definition with a loaded command
|
||||
pub fn new() -> Module {
|
||||
/* 1. Create a new module */
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["test".to_string()],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec!["test".to_string()], "".to_string());
|
||||
|
||||
/* 2. Load the cmd into a new module */
|
||||
custom_mod.load_command(cmd_test());
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// Command definition
|
||||
|
@ -63,8 +56,12 @@ pub mod custom_mod {
|
|||
/* 2. Define exec callback */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _= bot.chat.lock().await.say_in_reply_to(
|
||||
&msg, "test return".to_string()).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, "test return".to_string())
|
||||
.await;
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub mod bot;
|
||||
pub mod bot_objects;
|
||||
pub mod modules;
|
||||
pub mod built_in_mods;
|
||||
pub mod chat;
|
||||
pub mod modules;
|
||||
|
|
|
@ -1,25 +1,32 @@
|
|||
|
||||
|
||||
// use async_recursion::async_recursion;
|
||||
use tokio::sync::{mpsc::UnboundedReceiver, Mutex};
|
||||
use twitch_irc::{login::StaticLoginCredentials, message::{PrivmsgMessage, ServerMessage}, SecureTCPTransport, TwitchIRCClient};
|
||||
use dotenv::dotenv;
|
||||
use std::{env, sync::{Arc, RwLock}, time::{Duration, Instant}};
|
||||
use std::{
|
||||
env,
|
||||
sync::{Arc, RwLock},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::sync::{mpsc::UnboundedReceiver, Mutex};
|
||||
use twitch_irc::{
|
||||
login::StaticLoginCredentials,
|
||||
message::{PrivmsgMessage, ServerMessage},
|
||||
SecureTCPTransport, TwitchIRCClient,
|
||||
};
|
||||
|
||||
// use crate::{Badge, Command, Listener, Module};
|
||||
use super::{bot_objects::command::Command, built_in_mods, chat::Chat};
|
||||
|
||||
use crate::botcore::{bot_objects::Badge, chat};
|
||||
use crate::botcore::bot_objects::listener::Listener;
|
||||
use super::super::botcore::modules::Module;
|
||||
use crate::botcore::bot_objects::listener::Listener;
|
||||
use crate::botcore::{bot_objects::Badge, chat};
|
||||
// use super::
|
||||
|
||||
use super:: {bot_objects::built_in_objects, modules::{self, Status}};
|
||||
|
||||
use super::{
|
||||
bot_objects::built_in_objects,
|
||||
modules::{self, Status},
|
||||
};
|
||||
|
||||
/// Twitch chat bot
|
||||
pub struct Bot
|
||||
{
|
||||
pub struct Bot {
|
||||
/// Prefix for commands
|
||||
prefix: String,
|
||||
/// inbound chat msg stream
|
||||
|
@ -46,12 +53,9 @@ pub struct Bot
|
|||
message_cache: Mutex<Vec<PrivmsgMessage>>,
|
||||
// /// channel_quiet
|
||||
// channel_quiet_yn: RwLock<Vec<(String,RwLock<bool>)>>,
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl Bot
|
||||
{
|
||||
impl Bot {
|
||||
/// Creates a new `Bot` using env variables
|
||||
///
|
||||
/// Be sure the following is defined in an `.env` file
|
||||
|
@ -62,15 +66,10 @@ impl Bot
|
|||
/// - bot_admins
|
||||
// #[async_recursion]
|
||||
pub async fn new() -> Arc<Bot> {
|
||||
|
||||
|
||||
|
||||
dotenv().ok();
|
||||
let bot_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();
|
||||
let prefix = env::var("prefix").unwrap().to_owned();
|
||||
|
||||
let mut botchannels = Vec::new();
|
||||
|
||||
|
@ -79,18 +78,17 @@ impl Bot
|
|||
}
|
||||
|
||||
Bot::new_from(bot_login_name, oauth_token, prefix, botchannels).await
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Creates a new `Bot` using bot information
|
||||
///
|
||||
/// Bot will join `botchannels` argument
|
||||
pub async fn new_from(bot_login_name:String,
|
||||
pub async fn new_from(
|
||||
bot_login_name: String,
|
||||
oauth_token: String,
|
||||
prefix: String,
|
||||
botchannels:Vec<String>) -> Arc<Bot> {
|
||||
|
||||
botchannels: Vec<String>,
|
||||
) -> Arc<Bot> {
|
||||
dotenv().ok();
|
||||
let bot_login_name = bot_login_name;
|
||||
|
||||
|
@ -105,7 +103,6 @@ impl Bot
|
|||
let mut botchannels_all = Vec::new();
|
||||
botchannels_all.extend(botchannels);
|
||||
|
||||
|
||||
let mut admins = Vec::new();
|
||||
|
||||
if let Ok(value) = env::var("bot_admins") {
|
||||
|
@ -114,7 +111,6 @@ impl Bot
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
let bot = Bot {
|
||||
prefix,
|
||||
incoming_msgs: Mutex::new(incoming_messages),
|
||||
|
@ -142,12 +138,10 @@ impl Bot
|
|||
built_in_mods::load_built_in_mods(&bot).await;
|
||||
|
||||
bot
|
||||
|
||||
}
|
||||
|
||||
let bot = load_modules(bot).await;
|
||||
|
||||
|
||||
let bot = Arc::new(bot);
|
||||
|
||||
// let lock = bot.chat.lock().await;
|
||||
|
@ -162,13 +156,11 @@ impl Bot
|
|||
|
||||
println!("Joined - {:?}", bot.botchannels);
|
||||
|
||||
|
||||
bot.clone()
|
||||
}
|
||||
|
||||
/// Runs the bot
|
||||
pub async fn run(self: Arc<Self>) {
|
||||
|
||||
for chnl in &self.botchannels {
|
||||
self.client.join(chnl.to_owned()).unwrap();
|
||||
}
|
||||
|
@ -177,7 +169,6 @@ impl Bot
|
|||
let bot = self;
|
||||
|
||||
let join_handle = tokio::spawn(async move {
|
||||
|
||||
let a = bot.clone();
|
||||
let mut in_msgs_lock = a.incoming_msgs.lock().await;
|
||||
|
||||
|
@ -186,7 +177,6 @@ impl Bot
|
|||
|
||||
let bot_listener_lock = bot.listeners.lock().await;
|
||||
for listener in bot_listener_lock.iter() {
|
||||
|
||||
let a = listener.clone();
|
||||
if a.cond_triggered(bot.clone(), message.clone()).await {
|
||||
let _ = listener.execute_fn(bot.clone(), message.clone()).await;
|
||||
|
@ -194,7 +184,6 @@ impl Bot
|
|||
}
|
||||
|
||||
if let ServerMessage::Privmsg(msg) = message.clone() {
|
||||
|
||||
// let mut cache_lock = bot.message_cache.lock().await;
|
||||
let mut cache_lock = bot.message_cache.lock().await;
|
||||
cache_lock.push(msg.clone());
|
||||
|
@ -203,17 +192,13 @@ impl Bot
|
|||
|
||||
let cmd_lock = bot.commands.lock().await;
|
||||
for cmd in cmd_lock.iter() {
|
||||
|
||||
let a = cmd.clone();
|
||||
if a.command_triggered(bot.clone(), msg.clone()).await {
|
||||
|
||||
let _ = cmd.execute_fn(bot.clone(), message.clone()).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_enabled_channel_modules(bot: Arc<Bot>, channel: String) -> Vec<Module> {
|
||||
|
||||
let botmodules_lock = bot.modules.read().unwrap();
|
||||
let botmodules_cpy = botmodules_lock.clone();
|
||||
drop(botmodules_lock);
|
||||
|
@ -221,16 +206,15 @@ impl Bot
|
|||
let mut enabled_mods = Vec::new();
|
||||
|
||||
'module_loop: for module in &*botmodules_cpy {
|
||||
|
||||
// dbg!("try cms read");
|
||||
let cms_lock = bot.channel_module_status.read().unwrap();
|
||||
|
||||
for channel_flags in cms_lock.iter() {
|
||||
if channel_flags.0 == channel {
|
||||
|
||||
if module.get_names().contains(&channel_flags.1) && channel_flags.2 == Status::Disabled {
|
||||
if module.get_names().contains(&channel_flags.1)
|
||||
&& channel_flags.2 == Status::Disabled
|
||||
{
|
||||
continue 'module_loop;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,33 +222,26 @@ impl Bot
|
|||
}
|
||||
|
||||
enabled_mods
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
for module in get_enabled_channel_modules(bot.clone(), msg.clone().channel_login) {
|
||||
|
||||
for module in
|
||||
get_enabled_channel_modules(bot.clone(), msg.clone().channel_login)
|
||||
{
|
||||
for listener in module.get_listeners() {
|
||||
|
||||
let a = listener.clone();
|
||||
if a.cond_triggered(bot.clone(), message.clone()).await {
|
||||
|
||||
let _ = listener.execute_fn(bot.clone(), message.clone()).await;
|
||||
}
|
||||
}
|
||||
for cmd in module.get_commands() {
|
||||
|
||||
let a = cmd.clone();
|
||||
if a.command_triggered(bot.clone(), msg.clone()).await {
|
||||
|
||||
let _ = cmd.execute_fn(bot.clone(), message.clone()).await;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {} ;
|
||||
|
||||
} else {
|
||||
};
|
||||
}
|
||||
drop(in_msgs_lock);
|
||||
});
|
||||
|
@ -286,7 +263,6 @@ impl Bot
|
|||
cmdlock.push(c);
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_module(&self, module: String) -> Option<Module> {
|
||||
let modlock = self.modules.read().unwrap();
|
||||
for modl in modlock.iter() {
|
||||
|
@ -297,8 +273,6 @@ impl Bot
|
|||
None
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn get_prefix(&self) -> String {
|
||||
self.prefix.clone()
|
||||
}
|
||||
|
@ -318,8 +292,8 @@ impl Bot
|
|||
// dbg!("inner if");
|
||||
for (_index, chnl) in bot.botchannels.iter().enumerate() {
|
||||
// dbg!("iter - ",index);
|
||||
bot.disable_module(chnl.clone(),
|
||||
m.get_names().first().unwrap().clone()).await
|
||||
bot.disable_module(chnl.clone(), m.get_names().first().unwrap().clone())
|
||||
.await
|
||||
}
|
||||
}
|
||||
// dbg!("aftee disable check");
|
||||
|
@ -350,7 +324,6 @@ impl Bot
|
|||
};
|
||||
|
||||
let module_loaded: bool = {
|
||||
|
||||
let mut loaded_yn = false;
|
||||
|
||||
for loaded_m in self.modules.read().unwrap().iter() {
|
||||
|
@ -360,14 +333,15 @@ impl Bot
|
|||
}
|
||||
|
||||
loaded_yn
|
||||
|
||||
};
|
||||
|
||||
if found_disabled { return Status::Disabled;}
|
||||
|
||||
else if !module_loaded { return Status::NotLoaded ;}
|
||||
else { return Status::Enabled; };
|
||||
|
||||
if found_disabled {
|
||||
return Status::Disabled;
|
||||
} else if !module_loaded {
|
||||
return Status::NotLoaded;
|
||||
} else {
|
||||
return Status::Enabled;
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn disable_module(&self, channel: String, module: String) {
|
||||
|
@ -394,18 +368,12 @@ impl Bot
|
|||
};
|
||||
|
||||
if !found_disabled {
|
||||
|
||||
|
||||
let mut cms_lock = self.channel_module_status.write().unwrap();
|
||||
|
||||
cms_lock.push((channel, module.clone(), Status::Disabled));
|
||||
|
||||
drop(cms_lock);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub async fn enable_module(&self, channel: String, module: String) {
|
||||
|
@ -415,26 +383,28 @@ impl Bot
|
|||
// dbg!("cms write lock");
|
||||
// dbg!(module.clone());
|
||||
while lock.contains(&(channel.clone(), module.clone(), Status::Disabled)) {
|
||||
|
||||
let index = lock
|
||||
.iter()
|
||||
.position(|x| *x ==
|
||||
(channel.clone(),module.clone(),Status::Disabled))
|
||||
.position(|x| *x == (channel.clone(), module.clone(), Status::Disabled))
|
||||
.unwrap();
|
||||
lock.remove(index);
|
||||
}
|
||||
drop(lock);
|
||||
}
|
||||
|
||||
pub async fn get_channel_guest_badges(&self,chatter:String,channel:String) -> Vec<(Badge,Instant,Duration)> {
|
||||
|
||||
pub async fn get_channel_guest_badges(
|
||||
&self,
|
||||
chatter: String,
|
||||
channel: String,
|
||||
) -> Vec<(Badge, Instant, Duration)> {
|
||||
let bot = Arc::new(self);
|
||||
let guest_badges_lock = bot.chatter_guest_badges.lock().await;
|
||||
|
||||
let mut badges = vec![];
|
||||
for temp_badge in guest_badges_lock.iter() {
|
||||
if temp_badge.0 == chatter && temp_badge.1 == channel &&
|
||||
temp_badge.3 + temp_badge.4 > Instant::now()
|
||||
if temp_badge.0 == chatter
|
||||
&& temp_badge.1 == channel
|
||||
&& temp_badge.3 + temp_badge.4 > Instant::now()
|
||||
{
|
||||
badges.push((temp_badge.2.clone(), temp_badge.3, temp_badge.4));
|
||||
}
|
||||
|
@ -443,13 +413,18 @@ impl Bot
|
|||
badges
|
||||
}
|
||||
|
||||
|
||||
pub async fn issue_new_guest_badge(&self,chatter:String,channel:String,badge:Badge,start:Instant,dur:Duration) {
|
||||
pub async fn issue_new_guest_badge(
|
||||
&self,
|
||||
chatter: String,
|
||||
channel: String,
|
||||
badge: Badge,
|
||||
start: Instant,
|
||||
dur: Duration,
|
||||
) {
|
||||
let bot = Arc::new(self);
|
||||
let mut guest_badges_lock = bot.chatter_guest_badges.lock().await;
|
||||
|
||||
guest_badges_lock.push((chatter, channel, badge, start, dur));
|
||||
|
||||
}
|
||||
|
||||
pub fn get_message_cache(&self) -> &Mutex<Vec<PrivmsgMessage>> {
|
||||
|
@ -460,9 +435,13 @@ impl Bot
|
|||
pub async fn get_message_cache_per_channel(&self, channel: String) -> Vec<PrivmsgMessage> {
|
||||
let cache = self.message_cache.lock().await;
|
||||
let mut rslt = vec![];
|
||||
for a in cache.iter().rev().filter(|x| { x.channel_login==channel }).into_iter() {
|
||||
for a in cache
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|x| x.channel_login == channel)
|
||||
.into_iter()
|
||||
{
|
||||
rslt.push(a.clone());
|
||||
|
||||
}
|
||||
rslt
|
||||
}
|
||||
|
@ -500,7 +479,4 @@ impl Bot
|
|||
// }
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
pub mod listener;
|
||||
pub mod command;
|
||||
|
||||
pub mod listener;
|
||||
|
||||
use std::boxed::Box;
|
||||
use std::future::Future;
|
||||
|
@ -11,19 +10,18 @@ use twitch_irc::message::{PrivmsgMessage, ServerMessage};
|
|||
|
||||
use super::bot::Bot;
|
||||
|
||||
|
||||
/// chat badge
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Badge {
|
||||
Moderator,
|
||||
Broadcaster,
|
||||
Vip
|
||||
Vip,
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub type ExecBody = Box<
|
||||
dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = Result<String,String>> + Send>> + Send + Sync,
|
||||
dyn Fn(Arc<Bot>, ServerMessage) -> Pin<Box<dyn Future<Output = Result<String, String>> + Send>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>;
|
||||
|
||||
/// used to store async execution functions. Primarily used for `Command`
|
||||
|
@ -72,7 +70,6 @@ where
|
|||
Box::new(move |a, b| Box::pin(f(a, b)))
|
||||
}
|
||||
|
||||
|
||||
pub type ListenerTrigger = Box<
|
||||
dyn Fn(Arc<Bot>, ServerMessage) -> Pin<Box<dyn Future<Output = bool> + Send>> + Send + Sync,
|
||||
>;
|
||||
|
@ -97,22 +94,21 @@ where
|
|||
Box::new(move |a, b| Box::pin(f(a, b)))
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// collection of functions to create built in objects
|
||||
pub mod built_in_objects {
|
||||
const TEMP_BADGE_DUR_MIN: u64 = 30;
|
||||
|
||||
use std::{sync::Arc, time::{Duration, Instant}};
|
||||
use std::{
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
use super::{execution_async,command::Command,Bot,Badge,super::modules::Status};
|
||||
|
||||
use super::{super::modules::Status, command::Command, execution_async, Badge, Bot};
|
||||
|
||||
/// create a vector of command build in objects
|
||||
pub fn create_commands() -> Vec<Command>
|
||||
{
|
||||
pub fn create_commands() -> Vec<Command> {
|
||||
let mut cmds = vec![];
|
||||
|
||||
cmds.push(create_disable_cmd());
|
||||
|
@ -120,7 +116,6 @@ pub mod built_in_objects {
|
|||
cmds.push(create_iam_role_cmd());
|
||||
|
||||
cmds
|
||||
|
||||
}
|
||||
|
||||
fn create_disable_cmd() -> Command {
|
||||
|
@ -131,17 +126,32 @@ pub mod built_in_objects {
|
|||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let mut action_taken = false;
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
for (i, arg) in msg
|
||||
.message_text
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.split(" ")
|
||||
.enumerate()
|
||||
{
|
||||
if i > 1 {
|
||||
if bot.get_channel_module_status(msg.channel_login.clone(), arg.to_string()).await == Status::Enabled {
|
||||
if bot
|
||||
.get_channel_module_status(msg.channel_login.clone(), arg.to_string())
|
||||
.await
|
||||
== Status::Enabled
|
||||
{
|
||||
action_taken = true;
|
||||
bot.disable_module(msg.channel_login.clone(), arg.to_string()).await;
|
||||
bot.disable_module(msg.channel_login.clone(), arg.to_string())
|
||||
.await;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if action_taken {
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg, String::from("Disabled!")).await ;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, String::from("Disabled!"))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -156,7 +166,6 @@ pub mod built_in_objects {
|
|||
/* 5. optionally, set min badge*/
|
||||
cmd.set_min_badge(Badge::Moderator /* ::Moderator */);
|
||||
cmd
|
||||
|
||||
}
|
||||
|
||||
fn create_enable_cmd() -> Command {
|
||||
|
@ -166,38 +175,50 @@ pub mod built_in_objects {
|
|||
/* 2. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
||||
let mut bot_message = "".to_string();
|
||||
let mut re_enabled = false;
|
||||
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
for (i, arg) in msg
|
||||
.message_text
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.split(" ")
|
||||
.enumerate()
|
||||
{
|
||||
if i > 1 {
|
||||
|
||||
if Status::Disabled == bot.get_channel_module_status(msg.channel_login.clone(), arg.to_string()).await {
|
||||
bot.enable_module(msg.channel_login.clone(), arg.to_string()).await;
|
||||
if Status::Disabled
|
||||
== bot
|
||||
.get_channel_module_status(
|
||||
msg.channel_login.clone(),
|
||||
arg.to_string(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
bot.enable_module(msg.channel_login.clone(), arg.to_string())
|
||||
.await;
|
||||
|
||||
//bot.get_modules()
|
||||
if let Some(found_mod) = bot.get_module(arg.to_string()).await {
|
||||
bot_message = bot_message.to_string() + found_mod.get_bot_read_description().as_str();
|
||||
bot_message = bot_message.to_string()
|
||||
+ found_mod.get_bot_read_description().as_str();
|
||||
}
|
||||
re_enabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if re_enabled {
|
||||
|
||||
if bot_message.len() > 250 {
|
||||
bot_message = bot_message[..250].to_string();
|
||||
}
|
||||
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg,
|
||||
format!("Enabled! {}", bot_message)
|
||||
).await ;
|
||||
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, format!("Enabled! {}", bot_message))
|
||||
.await;
|
||||
}
|
||||
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
@ -213,20 +234,24 @@ pub mod built_in_objects {
|
|||
cmd
|
||||
}
|
||||
|
||||
|
||||
/// adminonly command that grants a temporary role
|
||||
fn create_iam_role_cmd() -> Command {
|
||||
/* 1. Create a new blank cmd */
|
||||
let mut cmd = Command::new(vec![
|
||||
"I am ".to_string(),
|
||||
"I'm ".to_string(),
|
||||
"Im a ".to_string(),
|
||||
],"".to_string());
|
||||
let mut cmd = Command::new(
|
||||
vec!["I am ".to_string(), "I'm ".to_string(), "Im a ".to_string()],
|
||||
"".to_string(),
|
||||
);
|
||||
|
||||
/* 2. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
for (i, arg) in msg
|
||||
.message_text
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.split(" ")
|
||||
.enumerate()
|
||||
{
|
||||
if i > 1 {
|
||||
// bot.disable_module(msg.channel_login.clone(), arg.to_string()).await;
|
||||
// #todo
|
||||
|
@ -235,7 +260,12 @@ pub mod built_in_objects {
|
|||
// recognzed wth that badge
|
||||
|
||||
if arg == "mod" || arg == "moderator" {
|
||||
let curr_temp_badges = bot.get_channel_guest_badges(msg.sender.login.clone(), msg.channel_login.clone()).await;
|
||||
let curr_temp_badges = bot
|
||||
.get_channel_guest_badges(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
)
|
||||
.await;
|
||||
let mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Moderator {
|
||||
|
@ -248,16 +278,34 @@ pub mod built_in_objects {
|
|||
bot.issue_new_guest_badge(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
Badge::Moderator, Instant::now(), Duration::from_secs(60*TEMP_BADGE_DUR_MIN)).await;
|
||||
Badge::Moderator,
|
||||
Instant::now(),
|
||||
Duration::from_secs(60 * TEMP_BADGE_DUR_MIN),
|
||||
)
|
||||
.await;
|
||||
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg,
|
||||
format!("Temp {:?} issued for {:?} minutes",Badge::Moderator,TEMP_BADGE_DUR_MIN)
|
||||
).await ;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(
|
||||
&msg,
|
||||
format!(
|
||||
"Temp {:?} issued for {:?} minutes",
|
||||
Badge::Moderator,
|
||||
TEMP_BADGE_DUR_MIN
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
}
|
||||
if arg == "vip" {
|
||||
let curr_temp_badges = bot.get_channel_guest_badges(msg.sender.login.clone(), msg.channel_login.clone()).await;
|
||||
let curr_temp_badges = bot
|
||||
.get_channel_guest_badges(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
)
|
||||
.await;
|
||||
let mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Vip {
|
||||
|
@ -270,15 +318,34 @@ pub mod built_in_objects {
|
|||
bot.issue_new_guest_badge(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
Badge::Vip, Instant::now(), Duration::from_secs(60*TEMP_BADGE_DUR_MIN)).await;
|
||||
Badge::Vip,
|
||||
Instant::now(),
|
||||
Duration::from_secs(60 * TEMP_BADGE_DUR_MIN),
|
||||
)
|
||||
.await;
|
||||
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg,
|
||||
format!("Temp {:?} issued for {:?} minutes for the bot admin",Badge::Vip,TEMP_BADGE_DUR_MIN)
|
||||
).await ;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(
|
||||
&msg,
|
||||
format!(
|
||||
"Temp {:?} issued for {:?} minutes for the bot admin",
|
||||
Badge::Vip,
|
||||
TEMP_BADGE_DUR_MIN
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
if arg == "broadcaster" || arg == "strimmer" || arg == "streamer" {
|
||||
let curr_temp_badges = bot.get_channel_guest_badges(msg.sender.login.clone(), msg.channel_login.clone()).await;
|
||||
let curr_temp_badges = bot
|
||||
.get_channel_guest_badges(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
)
|
||||
.await;
|
||||
let mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Broadcaster {
|
||||
|
@ -291,11 +358,25 @@ pub mod built_in_objects {
|
|||
bot.issue_new_guest_badge(
|
||||
msg.sender.login.clone(),
|
||||
msg.channel_login.clone(),
|
||||
Badge::Broadcaster, Instant::now(), Duration::from_secs(60*TEMP_BADGE_DUR_MIN)).await;
|
||||
Badge::Broadcaster,
|
||||
Instant::now(),
|
||||
Duration::from_secs(60 * TEMP_BADGE_DUR_MIN),
|
||||
)
|
||||
.await;
|
||||
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg,
|
||||
format!("Temp {:?} issued for {:?} minutes for the bot admin",Badge::Broadcaster,TEMP_BADGE_DUR_MIN)
|
||||
).await ;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(
|
||||
&msg,
|
||||
format!(
|
||||
"Temp {:?} issued for {:?} minutes for the bot admin",
|
||||
Badge::Broadcaster,
|
||||
TEMP_BADGE_DUR_MIN
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,8 +395,5 @@ pub mod built_in_objects {
|
|||
// /* 5. optionally, set min badge*/
|
||||
// cmd.set_min_badge(Badge::Moderator);
|
||||
cmd
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,9 +2,7 @@ use std::sync::Arc;
|
|||
|
||||
use twitch_irc::message::{PrivmsgMessage, ServerMessage};
|
||||
|
||||
|
||||
use super::{execution_async,Bot,Badge,command_condition_async};
|
||||
|
||||
use super::{command_condition_async, execution_async, Badge, Bot};
|
||||
|
||||
use super::{CommandTrigger, ExecBody};
|
||||
|
||||
|
@ -20,8 +18,7 @@ use super::{CommandTrigger, ExecBody};
|
|||
///
|
||||
/// Use `execution_async()` on custom async execution bodies
|
||||
#[derive(Clone)]
|
||||
pub struct Command
|
||||
{
|
||||
pub struct Command {
|
||||
commands: Vec<String>,
|
||||
exec_fn: Arc<ExecBody>,
|
||||
min_badge: Badge,
|
||||
|
@ -34,9 +31,7 @@ pub struct Command
|
|||
custom_cond_async: Arc<CommandTrigger>,
|
||||
}
|
||||
|
||||
impl Command
|
||||
{
|
||||
|
||||
impl Command {
|
||||
/// Creates a new empty `Command` using command `String` and prefix `String`
|
||||
/// Pass an empty string prefix if the bot should use the bot default
|
||||
///
|
||||
|
@ -45,10 +40,12 @@ impl Command
|
|||
///
|
||||
/// By default, the new command is admin_only
|
||||
pub fn new(commands: Vec<String>, prefix: String) -> Command {
|
||||
|
||||
async fn execbody(_:Arc<Bot>,_:ServerMessage) -> Result<String,String>
|
||||
{ Result::Ok("success".to_string()) }
|
||||
async fn condition01(_:Arc<Bot>,_:PrivmsgMessage) -> bool { true }
|
||||
async fn execbody(_: Arc<Bot>, _: ServerMessage) -> Result<String, String> {
|
||||
Result::Ok("success".to_string())
|
||||
}
|
||||
async fn condition01(_: Arc<Bot>, _: PrivmsgMessage) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
Command {
|
||||
commands,
|
||||
|
@ -67,7 +64,6 @@ impl Command
|
|||
self.custom_cond_fn = cond_fn;
|
||||
}
|
||||
|
||||
|
||||
/// sets the async trigger condition for listener
|
||||
///
|
||||
/// Same as `set_custom_cond_fn()` , but async define
|
||||
|
@ -103,7 +99,6 @@ impl Command
|
|||
/// specifically if the message is a valid command and min badge roles provided
|
||||
///
|
||||
pub async fn command_triggered(&self, bot: Arc<Bot>, msg: PrivmsgMessage) -> bool {
|
||||
|
||||
fn cmd_called(cmd: &Command, bot: Arc<Bot>, message: PrivmsgMessage) -> bool {
|
||||
let mut prefixed_cmd = "".to_string();
|
||||
if cmd.prefix == "" {
|
||||
|
@ -116,13 +111,11 @@ impl Command
|
|||
if message.message_text.starts_with(prefixed_cmd.as_str()) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
async fn caller_badge_ok(cmd: &Command, bot: Arc<Bot>, message: PrivmsgMessage) -> bool {
|
||||
|
||||
// senders that are admins skip badge check if the command is adminonly
|
||||
if cmd.admin_only && bot.get_admins().contains(&message.sender.login) {
|
||||
return true;
|
||||
|
@ -134,35 +127,41 @@ impl Command
|
|||
}
|
||||
|
||||
// admin role overrides badge check if enabled
|
||||
if cmd.admin_override && bot.get_admins().contains( &message.sender.login) { return true; }
|
||||
if cmd.admin_override && bot.get_admins().contains(&message.sender.login) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for badge in message.badges {
|
||||
|
||||
match cmd.min_badge {
|
||||
Badge::Broadcaster => {
|
||||
if badge.name == "broadcaster" { return true }
|
||||
else { return false }
|
||||
},
|
||||
Badge::Moderator => {
|
||||
match badge.name.as_str() {
|
||||
if badge.name == "broadcaster" {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Badge::Moderator => match badge.name.as_str() {
|
||||
"moderator" | "broadcaster" => return true,
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
Badge::Vip => {
|
||||
match badge.name.as_str() {
|
||||
Badge::Vip => match badge.name.as_str() {
|
||||
"vip" | "moderator" | "broadcaster" => return true,
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for temp_badge in bot.get_channel_guest_badges(message.sender.login, message.channel_login).await {
|
||||
for temp_badge in bot
|
||||
.get_channel_guest_badges(message.sender.login, message.channel_login)
|
||||
.await
|
||||
{
|
||||
match (cmd.min_badge.clone(), temp_badge.0) {
|
||||
(Badge::Broadcaster, Badge::Broadcaster) => return true,
|
||||
(Badge::Moderator,Badge::Moderator) | (Badge::Moderator,Badge::Broadcaster) => return true,
|
||||
(Badge::Vip,Badge::Vip)|(Badge::Vip,Badge::Moderator)|(Badge::Vip,Badge::Broadcaster) => return true,
|
||||
(Badge::Moderator, Badge::Moderator)
|
||||
| (Badge::Moderator, Badge::Broadcaster) => return true,
|
||||
(Badge::Vip, Badge::Vip)
|
||||
| (Badge::Vip, Badge::Moderator)
|
||||
| (Badge::Vip, Badge::Broadcaster) => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -170,14 +169,15 @@ impl Command
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// determines if the command caller can run the command
|
||||
/// based on admin_only flag
|
||||
///
|
||||
/// callers who are admins can run admin_only commands
|
||||
/// callers can run non-admin_only commands
|
||||
fn admin_only_ok(cmd: &Command, bot: Arc<Bot>, message: PrivmsgMessage) -> bool {
|
||||
if (cmd.admin_only && bot.get_admins().contains(&message.sender.login)) || !cmd.admin_only {
|
||||
if (cmd.admin_only && bot.get_admins().contains(&message.sender.login))
|
||||
|| !cmd.admin_only
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -185,7 +185,8 @@ impl Command
|
|||
}
|
||||
|
||||
async fn custom_cond_ok(cmd: &Command, bot: Arc<Bot>, message: PrivmsgMessage) -> bool {
|
||||
(cmd.custom_cond_fn)(bot.clone(),message.clone()) && (cmd.custom_cond_async)(bot,message).await
|
||||
(cmd.custom_cond_fn)(bot.clone(), message.clone())
|
||||
&& (cmd.custom_cond_async)(bot, message).await
|
||||
}
|
||||
|
||||
// async fn quiet_off_ok(cmd:&Command,bot:Arc<Bot>,message:PrivmsgMessage) -> bool {
|
||||
|
@ -193,14 +194,12 @@ impl Command
|
|||
// || bot.chat.lock().await.get_channel_quiet(message.channel_login.clone()) && cmd.commands.contains(&("quiet off".to_string()))
|
||||
// }
|
||||
|
||||
|
||||
cmd_called(self, bot.clone(), msg.clone()) &&
|
||||
caller_badge_ok(self, bot.clone(), msg.clone()).await &&
|
||||
admin_only_ok(self, bot.clone(), msg.clone()) &&
|
||||
custom_cond_ok(self, bot.clone(), msg.clone()).await
|
||||
cmd_called(self, bot.clone(), msg.clone())
|
||||
&& caller_badge_ok(self, bot.clone(), msg.clone()).await
|
||||
&& admin_only_ok(self, bot.clone(), msg.clone())
|
||||
&& custom_cond_ok(self, bot.clone(), msg.clone()).await
|
||||
// &&
|
||||
// quiet_off_ok(self, bot, msg).await
|
||||
|
||||
}
|
||||
|
||||
/// executes the listeners executon body
|
||||
|
@ -208,7 +207,6 @@ impl Command
|
|||
(self.exec_fn)(bot, msg).await
|
||||
}
|
||||
|
||||
|
||||
/// sets min_badge to run the cmd
|
||||
// pub fn set_min_badge(&mut self,min_badge:String) {
|
||||
pub fn set_min_badge(&mut self, min_badge: Badge) {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
use crate::Module;
|
||||
|
||||
use super::{execution_async,Bot,listener_condition_async};
|
||||
use super::{execution_async, listener_condition_async, Bot};
|
||||
|
||||
use super::{ExecBody, ListenerTrigger};
|
||||
|
||||
|
@ -22,8 +21,7 @@ use super::{ExecBody, ListenerTrigger};
|
|||
///
|
||||
/// - `set_exec_fn()` - to define the Execution Callback
|
||||
#[derive(Clone)]
|
||||
pub struct Listener
|
||||
{
|
||||
pub struct Listener {
|
||||
/// trigger condition
|
||||
trigger_cond_fn: fn(Arc<Bot>, ServerMessage) -> bool,
|
||||
/// trigger condition for async
|
||||
|
@ -33,9 +31,7 @@ pub struct Listener
|
|||
parent_module: Arc<Option<Module>>,
|
||||
}
|
||||
|
||||
impl Listener
|
||||
{
|
||||
|
||||
impl Listener {
|
||||
/// Creates a new empty `Listener`
|
||||
///
|
||||
/// Use `Listener` functions to define the Trigger Condition & Execution callbacks.
|
||||
|
@ -47,9 +43,12 @@ impl Listener
|
|||
///
|
||||
/// - `set_exec_fn()` - to define the Execution Callback
|
||||
pub fn new() -> Listener {
|
||||
|
||||
async fn execbody(_:Arc<Bot>,_:ServerMessage) -> Result<String,String> {Result::Ok("success".to_string()) }
|
||||
async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true }
|
||||
async fn execbody(_: Arc<Bot>, _: ServerMessage) -> Result<String, String> {
|
||||
Result::Ok("success".to_string())
|
||||
}
|
||||
async fn condition01(_: Arc<Bot>, _: ServerMessage) -> bool {
|
||||
true
|
||||
}
|
||||
Listener {
|
||||
trigger_cond_fn: |_: Arc<Bot>, _: ServerMessage| true,
|
||||
trigger_cond_async: Arc::new(listener_condition_async(condition01)),
|
||||
|
@ -85,7 +84,6 @@ impl Listener
|
|||
self.trigger_cond_async = Arc::new(condition);
|
||||
}
|
||||
|
||||
|
||||
/// sets the execution body of the listener for when it triggers
|
||||
///
|
||||
/// Use`execution_async()` on the async fn when storing
|
||||
|
@ -108,12 +106,16 @@ impl Listener
|
|||
|
||||
/// checks if the trigger condition is met
|
||||
pub async fn cond_triggered(&self, bot: Arc<Bot>, msg: ServerMessage) -> bool {
|
||||
|
||||
let list = Arc::new(self.clone());
|
||||
|
||||
async fn defined_conditions_ok(list:Arc<Listener>,bot:Arc<Bot>,msg:ServerMessage) -> bool {
|
||||
async fn defined_conditions_ok(
|
||||
list: Arc<Listener>,
|
||||
bot: Arc<Bot>,
|
||||
msg: ServerMessage,
|
||||
) -> bool {
|
||||
// let list = Arc::new(self);
|
||||
(list.trigger_cond_fn)(bot.clone(),msg.clone()) && (list.trigger_cond_async)(bot,msg).await
|
||||
(list.trigger_cond_fn)(bot.clone(), msg.clone())
|
||||
&& (list.trigger_cond_async)(bot, msg).await
|
||||
}
|
||||
|
||||
// async fn quiet_off_ok(list:Arc<Listener>,bot:Arc<Bot>,message:ServerMessage) -> bool {
|
||||
|
@ -135,7 +137,6 @@ impl Listener
|
|||
|
||||
/// executes the listeners executon body
|
||||
pub async fn execute_fn(&self, bot: Arc<Bot>, msg: ServerMessage) -> Result<String, String> {
|
||||
|
||||
(self.exec_fn)(bot, msg).await
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,4 @@ impl Listener
|
|||
pub fn set_parent_module(&mut self, module: Module) {
|
||||
self.parent_module = Arc::new(Some(module));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,7 @@ use crate::Bot;
|
|||
|
||||
pub mod quiet;
|
||||
|
||||
|
||||
/// used to internally load internal modules
|
||||
pub async fn load_built_in_mods(bot: &Bot) {
|
||||
|
||||
bot.load_module(quiet::create_module()).await;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ use twitch_irc::message::ServerMessage;
|
|||
|
||||
use crate::{execution_async, Badge, Bot, Command, Module};
|
||||
|
||||
|
||||
/// quiet the bot in a channel
|
||||
///
|
||||
/// use
|
||||
|
@ -23,15 +22,12 @@ use crate::{execution_async, Badge, Bot, Command, Module};
|
|||
///
|
||||
pub fn create_module() -> Module {
|
||||
/* 1. Create a new module */
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["quiet".to_string()],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec!["quiet".to_string()], "".to_string());
|
||||
|
||||
/* 2. Load the cmd into a new module */
|
||||
custom_mod.load_command(cmd_quiet_on());
|
||||
custom_mod.load_command(cmd_quiet_off());
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// Command definition for quiet command
|
||||
|
@ -42,7 +38,6 @@ fn cmd_quiet_on() -> Command {
|
|||
/* 2. Define exec callback */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
||||
// dbg!("quiet on called");
|
||||
|
||||
let chatlock = bot.chat.lock().await;
|
||||
|
@ -51,7 +46,6 @@ fn cmd_quiet_on() -> Command {
|
|||
chatlock.set_channel_quiet(msg.channel_login.clone(), true);
|
||||
println!("channel {} set quiet true", msg.channel_login);
|
||||
|
||||
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -74,12 +68,12 @@ fn cmd_quiet_off() -> Command {
|
|||
/* 2. Define exec callback */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
||||
let chatlock = bot.chat.lock().await;
|
||||
|
||||
chatlock.set_channel_quiet(msg.channel_login.clone(), false);
|
||||
let _=chatlock.say_in_reply_to(&msg, "GoodGirl I'll be good for u chat rar ".to_string()).await;
|
||||
|
||||
let _ = chatlock
|
||||
.say_in_reply_to(&msg, "GoodGirl I'll be good for u chat rar ".to_string())
|
||||
.await;
|
||||
|
||||
println!("channel {} set quiet false", msg.channel_login);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
use std::{fmt::Error, ops::Mul, rc::Rc, sync::{Arc, Mutex, RwLock}};
|
||||
use std::{
|
||||
fmt::Error,
|
||||
ops::Mul,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
};
|
||||
|
||||
use twitch_irc::{login::StaticLoginCredentials, message::ReplyToMessage, SecureTCPTransport, TwitchIRCClient};
|
||||
use twitch_irc::{
|
||||
login::StaticLoginCredentials, message::ReplyToMessage, SecureTCPTransport, TwitchIRCClient,
|
||||
};
|
||||
|
||||
use crate::Bot;
|
||||
|
||||
|
@ -10,20 +17,15 @@ use crate::Bot;
|
|||
///
|
||||
///
|
||||
|
||||
pub struct Chat
|
||||
{
|
||||
pub struct Chat {
|
||||
/// outbound chat client msg stream
|
||||
pub client: TwitchIRCClient<SecureTCPTransport, StaticLoginCredentials>,
|
||||
/// channel_quiet
|
||||
channel_quiet_yn: RwLock<Vec<(String, RwLock<bool>)>>,
|
||||
|
||||
}
|
||||
|
||||
impl Chat {
|
||||
|
||||
|
||||
pub async fn new(client:TwitchIRCClient<SecureTCPTransport,StaticLoginCredentials>)
|
||||
-> Chat {
|
||||
pub async fn new(client: TwitchIRCClient<SecureTCPTransport, StaticLoginCredentials>) -> Chat {
|
||||
Chat {
|
||||
client,
|
||||
// parent_bot : Mutex::new(Bot::new().await) ,
|
||||
|
@ -39,7 +41,6 @@ impl Chat {
|
|||
|
||||
/// helper
|
||||
fn ok_to_send(&self, channel_login: String) -> bool {
|
||||
|
||||
fn not_quiet_ok(chat: &Chat, channel_login: String) -> bool {
|
||||
// let lock = chat.parent_bot.lock().unwrap();
|
||||
// let a = lock.as_ref();
|
||||
|
@ -49,10 +50,8 @@ impl Chat {
|
|||
// true
|
||||
}
|
||||
not_quiet_ok(self, channel_login)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Get the quiet status of a channel
|
||||
pub fn get_channel_quiet(&self, channel: String) -> bool {
|
||||
for a in self.channel_quiet_yn.read().unwrap().iter() {
|
||||
|
@ -84,14 +83,12 @@ impl Chat {
|
|||
chnlquiet.push((channel, RwLock::new(quiet_on)));
|
||||
drop(chnlquiet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub async fn say_in_reply_to(&self,
|
||||
pub async fn say_in_reply_to(
|
||||
&self,
|
||||
reply_to: &impl ReplyToMessage,
|
||||
message: String
|
||||
message: String,
|
||||
) -> Result<(), ()> {
|
||||
// reply_to.channel_login()
|
||||
if self.ok_to_send(reply_to.channel_login().to_string()) {
|
||||
|
@ -102,13 +99,9 @@ impl Chat {
|
|||
} else {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub async fn say(&self,
|
||||
channel_login: String,
|
||||
message: String,
|
||||
) -> Result<(),()> {
|
||||
pub async fn say(&self, channel_login: String, message: String) -> Result<(), ()> {
|
||||
if self.ok_to_send(channel_login.to_string()) {
|
||||
match self.client.say(channel_login, message).await {
|
||||
Ok(_) => return Ok(()),
|
||||
|
@ -119,10 +112,7 @@ match self.client.say(channel_login, message).await {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn me(&self,
|
||||
channel_login: String,
|
||||
message: String,
|
||||
) -> Result<(),()> {
|
||||
pub async fn me(&self, channel_login: String, message: String) -> Result<(), ()> {
|
||||
if self.ok_to_send(channel_login.to_string()) {
|
||||
match self.client.me(channel_login, message).await {
|
||||
Ok(_) => return Ok(()),
|
||||
|
@ -131,12 +121,12 @@ match self.client.me(channel_login, message).await {
|
|||
} else {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub async fn me_in_reply_to(&self,
|
||||
pub async fn me_in_reply_to(
|
||||
&self,
|
||||
reply_to: &impl ReplyToMessage,
|
||||
message: String
|
||||
message: String,
|
||||
) -> Result<(), ()> {
|
||||
if self.ok_to_send(reply_to.channel_login().to_string()) {
|
||||
match self.client.me_in_reply_to(reply_to, message).await {
|
||||
|
@ -146,6 +136,5 @@ match self.client.me(channel_login, message).await {
|
|||
} else {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
// use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::bot_objects::command::Command;
|
||||
use super::bot_objects::listener::Listener;
|
||||
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Status {
|
||||
Disabled,
|
||||
|
@ -16,8 +14,7 @@ pub enum Status {
|
|||
///
|
||||
/// Elevated chatters can disable modules by their name or chat alias
|
||||
#[derive(Clone)]
|
||||
pub struct Module
|
||||
{
|
||||
pub struct Module {
|
||||
name: Vec<String>,
|
||||
// _alias: String,
|
||||
bot_read_description: String,
|
||||
|
@ -27,8 +24,7 @@ pub struct Module
|
|||
default_status_per_channel: Status,
|
||||
}
|
||||
|
||||
impl Module
|
||||
{
|
||||
impl Module {
|
||||
/// create a new module
|
||||
pub fn new(name: Vec<String>, bot_read_description: String) -> Module {
|
||||
Module {
|
||||
|
@ -75,6 +71,4 @@ impl Module
|
|||
pub fn get_status_by_default(&self) -> Status {
|
||||
self.default_status_per_channel.clone()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
pub mod debug;
|
||||
pub mod guest_badge;
|
||||
pub mod pyramid;
|
||||
pub mod debug;
|
||||
// pub mod quiet;
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{execution_async, modules::Status, Bot, Command, Listener, Module};
|
||||
|
@ -15,7 +13,6 @@ use twitch_irc::message::ServerMessage;
|
|||
///
|
||||
///
|
||||
|
||||
|
||||
/// Use this function when loading modules into the bot
|
||||
///
|
||||
/// For example
|
||||
|
@ -25,15 +22,12 @@ use twitch_irc::message::ServerMessage;
|
|||
///
|
||||
pub fn create_module() -> Module {
|
||||
/* 1. Create a new module */
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["debug".to_string()],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec!["debug".to_string()], "".to_string());
|
||||
|
||||
/* 2. Load the cmd into a new module */
|
||||
custom_mod.load_command(cmd_debug_on());
|
||||
custom_mod.load_command(cmd_debug_off());
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// Command definition for debug command
|
||||
|
@ -48,12 +42,19 @@ fn cmd_debug_on() -> Command {
|
|||
|
||||
let modulename = "debug listener".to_string();
|
||||
|
||||
if let Status::NotLoaded = bot.get_channel_module_status(msg.channel_login.clone(), modulename.clone()).await {
|
||||
if let Status::NotLoaded = bot
|
||||
.get_channel_module_status(msg.channel_login.clone(), modulename.clone())
|
||||
.await
|
||||
{
|
||||
let module = create_listener_module(modulename.clone());
|
||||
bot.load_module(module.clone()).await;
|
||||
}
|
||||
let modl = bot.get_module(modulename).await.unwrap();
|
||||
bot.enable_module(msg.channel_login.clone(), modl.get_names().first().unwrap().clone()).await;
|
||||
bot.enable_module(
|
||||
msg.channel_login.clone(),
|
||||
modl.get_names().first().unwrap().clone(),
|
||||
)
|
||||
.await;
|
||||
println!("Debug enabled for channel {}", msg.channel_login);
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -85,7 +86,11 @@ fn cmd_debug_off() -> Command {
|
|||
// bot.load_module(module.clone()).await;
|
||||
// }
|
||||
let modl = bot.get_module(modulename).await.unwrap();
|
||||
bot.disable_module(msg.channel_login.clone(), modl.get_names().first().unwrap().clone()).await;
|
||||
bot.disable_module(
|
||||
msg.channel_login.clone(),
|
||||
modl.get_names().first().unwrap().clone(),
|
||||
)
|
||||
.await;
|
||||
println!("Debug disabled for channel {}", msg.channel_login);
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -101,16 +106,12 @@ fn cmd_debug_off() -> Command {
|
|||
}
|
||||
|
||||
fn create_listener_module(name: String) -> Module {
|
||||
|
||||
let mut custom_mod = Module::new(
|
||||
vec![name],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec![name], "".to_string());
|
||||
// dbg!("debug listener module created");
|
||||
custom_mod.load_listener(cmd_debug_listener());
|
||||
custom_mod.set_status_by_default(Status::Disabled);
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// Listener for debug
|
||||
|
@ -120,9 +121,7 @@ fn cmd_debug_listener() -> Listener {
|
|||
let mut listener = Listener::new();
|
||||
|
||||
/* 2b. Set a trigger condition function for listener */
|
||||
listener.set_trigger_cond_fn(
|
||||
|_:Arc<Bot>,_:ServerMessage| true
|
||||
);
|
||||
listener.set_trigger_cond_fn(|_: Arc<Bot>, _: ServerMessage| true);
|
||||
|
||||
/* 2c. Define an async fn callback execution */
|
||||
async fn execbody(_: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
|
@ -137,4 +136,3 @@ fn cmd_debug_listener() -> Listener {
|
|||
|
||||
listener
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use std::{sync::Arc, time::{Duration, Instant}};
|
||||
use std::{
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
|
@ -18,7 +21,6 @@ use crate::{execution_async, Badge, Bot, Command, Module};
|
|||
const VIP_GIVEN_DUR_MIN: u64 = 15;
|
||||
const MOD_GIVEN_DUR_MIN: u64 = 30;
|
||||
|
||||
|
||||
/// Use this function when loading modules into the bot
|
||||
///
|
||||
/// For example
|
||||
|
@ -27,63 +29,79 @@ const MOD_GIVEN_DUR_MIN:u64 = 30;
|
|||
/// ```
|
||||
///
|
||||
pub fn create_module() -> Module {
|
||||
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["guests".to_string()],
|
||||
"Temp Guest badges can be given by chatters with badges. ".to_string());
|
||||
"Temp Guest badges can be given by chatters with badges. ".to_string(),
|
||||
);
|
||||
|
||||
custom_mod.load_command(create_cmd_mod());
|
||||
custom_mod.load_command(create_cmd_vip());
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
fn create_cmd_vip() -> Command {
|
||||
|
||||
let mut cmd = Command::new(vec!["vip".to_string()], "".to_string());
|
||||
|
||||
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
||||
let guest_dur_min = {
|
||||
let mut result = VIP_GIVEN_DUR_MIN;
|
||||
for badge in msg.clone().badges {
|
||||
if badge.name == "vip" { result = VIP_GIVEN_DUR_MIN ; }
|
||||
if badge.name == "moderator" { result = MOD_GIVEN_DUR_MIN ; }
|
||||
if badge.name == "vip" {
|
||||
result = VIP_GIVEN_DUR_MIN;
|
||||
}
|
||||
if badge.name == "moderator" {
|
||||
result = MOD_GIVEN_DUR_MIN;
|
||||
}
|
||||
}
|
||||
result
|
||||
};
|
||||
|
||||
|
||||
let mut badges_issued = false;
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
for (i, arg) in msg
|
||||
.message_text
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.split(" ")
|
||||
.enumerate()
|
||||
{
|
||||
if i > 1 {
|
||||
let mut already_vip = false;
|
||||
|
||||
|
||||
for guest_badge in bot.get_channel_guest_badges(arg.trim().to_string(), msg.channel_login.clone()).await {
|
||||
if guest_badge.0 == Badge::Vip { already_vip = true }
|
||||
for guest_badge in bot
|
||||
.get_channel_guest_badges(arg.trim().to_string(), msg.channel_login.clone())
|
||||
.await
|
||||
{
|
||||
if guest_badge.0 == Badge::Vip {
|
||||
already_vip = true
|
||||
}
|
||||
}
|
||||
if !already_vip {
|
||||
badges_issued = true;
|
||||
bot.issue_new_guest_badge(
|
||||
arg.trim().to_string(),
|
||||
msg.channel_login.clone(),
|
||||
Badge::Vip, Instant::now(), Duration::from_secs(60*guest_dur_min)).await;
|
||||
|
||||
Badge::Vip,
|
||||
Instant::now(),
|
||||
Duration::from_secs(60 * guest_dur_min),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
if badges_issued {
|
||||
|
||||
|
||||
let _= bot.chat.lock().await.say_in_reply_to(
|
||||
&msg.clone(), format!("Guest badges issued for {} min",guest_dur_min)).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(
|
||||
&msg.clone(),
|
||||
format!("Guest badges issued for {} min", guest_dur_min),
|
||||
)
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
@ -94,37 +112,54 @@ fn create_cmd_vip() -> Command {
|
|||
cmd.set_admin_override(true);
|
||||
cmd.set_min_badge(Badge::Vip);
|
||||
cmd
|
||||
|
||||
}
|
||||
|
||||
fn create_cmd_mod() -> Command {
|
||||
|
||||
let mut cmd = Command::new(vec!["mod".to_string()], "".to_string());
|
||||
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
||||
|
||||
let mut badges_issued = false;
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
for (i, arg) in msg
|
||||
.message_text
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.split(" ")
|
||||
.enumerate()
|
||||
{
|
||||
if i > 1 {
|
||||
|
||||
let mut already_mod = false;
|
||||
for guest_badge in bot.get_channel_guest_badges(arg.trim().to_string(), msg.channel_login.clone()).await {
|
||||
if guest_badge.0 == Badge::Moderator { already_mod = true }
|
||||
for guest_badge in bot
|
||||
.get_channel_guest_badges(arg.trim().to_string(), msg.channel_login.clone())
|
||||
.await
|
||||
{
|
||||
if guest_badge.0 == Badge::Moderator {
|
||||
already_mod = true
|
||||
}
|
||||
}
|
||||
if !already_mod {
|
||||
badges_issued = true;
|
||||
bot.issue_new_guest_badge(
|
||||
arg.trim().to_string(),
|
||||
msg.channel_login.clone(),
|
||||
Badge::Moderator, Instant::now(), Duration::from_secs(60*MOD_GIVEN_DUR_MIN)).await;
|
||||
Badge::Moderator,
|
||||
Instant::now(),
|
||||
Duration::from_secs(60 * MOD_GIVEN_DUR_MIN),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
if badges_issued {
|
||||
let _= bot.chat.lock().await.say_in_reply_to(
|
||||
&msg, format!("Guest badges issued for {} min",MOD_GIVEN_DUR_MIN)).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(
|
||||
&msg,
|
||||
format!("Guest badges issued for {} min", MOD_GIVEN_DUR_MIN),
|
||||
)
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +172,4 @@ fn create_cmd_mod() -> Command {
|
|||
cmd.set_admin_override(true);
|
||||
cmd.set_min_badge(Badge::Moderator);
|
||||
cmd
|
||||
|
||||
|
||||
}
|
|
@ -1,17 +1,15 @@
|
|||
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use twitch_irc::message::{PrivmsgMessage, ServerMessage};
|
||||
|
||||
// use crate::{execution_async, listener_condition_async, Badge, Bot, Command, Listener, Module};
|
||||
use super::super::botcore::bot_objects::execution_async;
|
||||
use super::super::botcore::bot_objects::listener_condition_async;
|
||||
use super::super::botcore::bot_objects::listener::Listener;
|
||||
use super::super::botcore::modules::Module;
|
||||
use super::super::botcore::bot::Bot;
|
||||
use super::super::botcore::bot_objects::command::Command;
|
||||
use super::super::botcore::bot_objects::execution_async;
|
||||
use super::super::botcore::bot_objects::listener::Listener;
|
||||
use super::super::botcore::bot_objects::listener_condition_async;
|
||||
use super::super::botcore::bot_objects::Badge;
|
||||
use super::super::botcore::modules::Module;
|
||||
|
||||
/// pyramid module
|
||||
///
|
||||
|
@ -23,7 +21,6 @@ use super::super::botcore::bot_objects::Badge;
|
|||
///
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
|
||||
/// Use this function when loading modules into the bot
|
||||
///
|
||||
/// For example
|
||||
|
@ -32,26 +29,25 @@ use lazy_static::lazy_static;
|
|||
/// ```
|
||||
///
|
||||
pub fn create_module() -> Module {
|
||||
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["pyramid".to_string(),
|
||||
"pyramids".to_string()],
|
||||
"o7 I can handle pyramids".to_string());
|
||||
vec!["pyramid".to_string(), "pyramids".to_string()],
|
||||
"o7 I can handle pyramids".to_string(),
|
||||
);
|
||||
custom_mod.load_listener(create_pyramid_detector());
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
fn create_pyramid_detector() -> Listener {
|
||||
|
||||
/* 1. Create a new blank Listener */
|
||||
let mut listener = Listener::new();
|
||||
|
||||
/* 2. Define an async trigger condition callback */
|
||||
async fn condition01(bot: Arc<Bot>, message: ServerMessage) -> bool {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
if detect_pyramid_complete_ok(bot.clone(), msg.clone()).await && get_pyramid_size(msg.channel_login) > 3 {
|
||||
if detect_pyramid_complete_ok(bot.clone(), msg.clone()).await
|
||||
&& get_pyramid_size(msg.channel_login) > 3
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +57,6 @@ fn create_pyramid_detector() -> Listener {
|
|||
/* 3. Set a trigger condition function for listener */
|
||||
listener.set_trigger_cond_async(listener_condition_async(condition01));
|
||||
|
||||
|
||||
/* 4. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
|
@ -103,7 +98,6 @@ fn create_pyramid_detector() -> Listener {
|
|||
listener.set_exec_fn(Box::new(move |a, b| Box::pin(execbody(a, b))));
|
||||
|
||||
listener
|
||||
|
||||
}
|
||||
|
||||
/// detect pyramid based on latest message and channel
|
||||
|
@ -112,17 +106,26 @@ fn create_pyramid_detector() -> Listener {
|
|||
async fn detect_pyramid_complete_ok(_bot: Arc<Bot>, msg: PrivmsgMessage) -> bool {
|
||||
dbg!("enter detect_pyramid_complete()");
|
||||
|
||||
let msgtext = msg.message_text.replace("","").replace("\u{e0000}","").trim().to_string();
|
||||
let msgtext = msg
|
||||
.message_text
|
||||
.replace("", "")
|
||||
.replace("\u{e0000}", "")
|
||||
.trim()
|
||||
.to_string();
|
||||
let msgchannel = msg.channel_login;
|
||||
let msgchatter = msg.sender.login;
|
||||
|
||||
// 1. Check if Pyramid started in chat > and recognize pyramid started
|
||||
if !is_pyramid_started(msgchannel.clone()) & check_start_pyramid(msgchannel.clone(),msgtext.clone(),) {
|
||||
if !is_pyramid_started(msgchannel.clone())
|
||||
& check_start_pyramid(msgchannel.clone(), msgtext.clone())
|
||||
{
|
||||
dbg!("> set pyramid started - true");
|
||||
set_pyramid_started(msgchannel.clone(), true);
|
||||
push_to_compare(msgchannel.clone(),msgchatter.clone(),get_start_pattern(msgchannel.clone()));
|
||||
|
||||
|
||||
push_to_compare(
|
||||
msgchannel.clone(),
|
||||
msgchatter.clone(),
|
||||
get_start_pattern(msgchannel.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
if is_pyramid_started(msgchannel.clone()) {
|
||||
|
@ -137,7 +140,9 @@ async fn detect_pyramid_complete_ok(_bot:Arc<Bot>,msg:PrivmsgMessage) -> bool {
|
|||
// 2b. If Pyramid is Started, and the latest message is the pattern, check for
|
||||
// symmetry to determine pyramid
|
||||
|
||||
if is_pyramid_started(msgchannel.clone()) && msgtext.clone() == get_start_pattern(msgchannel.clone()) {
|
||||
if is_pyramid_started(msgchannel.clone())
|
||||
&& msgtext.clone() == get_start_pattern(msgchannel.clone())
|
||||
{
|
||||
if symmetry_ok(msgchannel.clone()) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -149,20 +154,20 @@ async fn detect_pyramid_complete_ok(_bot:Arc<Bot>,msg:PrivmsgMessage) -> bool {
|
|||
}
|
||||
|
||||
// 2c. if Pyramid is strted but latest message does not ontain pattern
|
||||
if is_pyramid_started(msgchannel.clone()) && !msgtext.clone().contains( get_start_pattern(msgchannel.clone()).as_str()) {
|
||||
|
||||
if is_pyramid_started(msgchannel.clone())
|
||||
&& !msgtext
|
||||
.clone()
|
||||
.contains(get_start_pattern(msgchannel.clone()).as_str())
|
||||
{
|
||||
dbg!("> set pyramid started - false");
|
||||
set_pyramid_started(msgchannel, false);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
lazy_static! {
|
||||
/// Message Compare stack per channel (channel:String,msgstack:Vec<(chatter:String,message:String)>)
|
||||
pub static ref COMPARE_MSG_STACK_PER_CHNL: Mutex<Vec<(String,Mutex<Vec<(String,String)>>)>> = Mutex::new(vec![]);
|
||||
|
@ -182,7 +187,6 @@ lazy_static!{
|
|||
}
|
||||
|
||||
fn read_top_of_compare(channel: String) -> Option<(String, String)> {
|
||||
|
||||
let comp_perchnl = COMPARE_MSG_STACK_PER_CHNL.lock().unwrap();
|
||||
|
||||
for rec in comp_perchnl.iter() {
|
||||
|
@ -240,25 +244,21 @@ fn set_start_pattern(channel:String,pattern:String) {
|
|||
|
||||
let mut found = false;
|
||||
for rec in start_patterns.iter() {
|
||||
|
||||
if rec.0 == channel {
|
||||
found = true;
|
||||
let mut patternlock = rec.1.lock().unwrap();
|
||||
*patternlock = pattern.clone();
|
||||
}
|
||||
|
||||
}
|
||||
if !found {
|
||||
start_patterns.push((channel.clone(), Mutex::new(pattern.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_start_pattern(channel: String) -> String {
|
||||
let start_patterns = START_PATTERNS_PER_CHNL.lock().unwrap();
|
||||
|
||||
for rec in start_patterns.iter() {
|
||||
|
||||
if rec.0 == channel {
|
||||
let patternlock = rec.1.lock().unwrap();
|
||||
return patternlock.clone();
|
||||
|
@ -268,7 +268,6 @@ fn get_start_pattern(channel:String) -> String {
|
|||
return "".to_string();
|
||||
}
|
||||
|
||||
|
||||
/// pushes message to compare stack
|
||||
fn push_to_compare(channel: String, chatter: String, message: String) {
|
||||
let mut comp_perchnl = COMPARE_MSG_STACK_PER_CHNL.lock().unwrap();
|
||||
|
@ -285,13 +284,16 @@ fn push_to_compare(channel:String,chatter:String,message:String) {
|
|||
if !found {
|
||||
comp_perchnl.push((channel, Mutex::new(vec![(chatter, message)])));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// checks latest and next latest messages for potential start
|
||||
fn check_start_pyramid(channel: String, msgtext: String) -> bool {
|
||||
msgtext == format!("{} {}",get_start_pattern(channel.clone()),get_start_pattern(channel.clone()))
|
||||
msgtext
|
||||
== format!(
|
||||
"{} {}",
|
||||
get_start_pattern(channel.clone()),
|
||||
get_start_pattern(channel.clone())
|
||||
)
|
||||
// msgtext == format!("{} {} {}",
|
||||
// get_start_pattern(channel.clone()),
|
||||
// get_start_pattern(channel.clone()),
|
||||
|
@ -299,59 +301,79 @@ fn check_start_pyramid(channel:String,msgtext: String) -> bool {
|
|||
// )
|
||||
}
|
||||
|
||||
|
||||
/// pops the compare stack to determine symmetry
|
||||
fn symmetry_ok(channel: String) -> bool {
|
||||
let mut temp_stack = TEMP_MSG_STACK.lock().unwrap();
|
||||
let mut checking_started = false;
|
||||
if !(read_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1 == get_start_pattern(channel.clone())) {
|
||||
if !(read_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1
|
||||
== get_start_pattern(channel.clone()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut pyramid_size = 0;
|
||||
loop {
|
||||
|
||||
if !checking_started && read_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1 == get_start_pattern(channel.clone()) {
|
||||
if !checking_started
|
||||
&& read_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1
|
||||
== get_start_pattern(channel.clone())
|
||||
{
|
||||
checking_started = true;
|
||||
}
|
||||
|
||||
if temp_stack.last().is_none() || read_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1.len() > temp_stack.last().unwrap_or(&"".to_string()).len() {
|
||||
temp_stack.push(pop_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1);
|
||||
if temp_stack.last().is_none()
|
||||
|| read_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1
|
||||
.len()
|
||||
> temp_stack.last().unwrap_or(&"".to_string()).len()
|
||||
{
|
||||
temp_stack.push(
|
||||
pop_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1,
|
||||
);
|
||||
pyramid_size += 1;
|
||||
|
||||
} else if temp_stack.last().is_some() && read_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1.len() < temp_stack.last().unwrap_or(&"".to_string()).len() {
|
||||
|
||||
} else if temp_stack.last().is_some()
|
||||
&& read_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1
|
||||
.len()
|
||||
< temp_stack.last().unwrap_or(&"".to_string()).len()
|
||||
{
|
||||
temp_stack.pop();
|
||||
if temp_stack.last().unwrap_or(&"".to_string()).clone() == read_top_of_compare(channel.clone()).unwrap_or(("".to_string(),"".to_string())).1 {
|
||||
if temp_stack.last().unwrap_or(&"".to_string()).clone()
|
||||
== read_top_of_compare(channel.clone())
|
||||
.unwrap_or(("".to_string(), "".to_string()))
|
||||
.1
|
||||
{
|
||||
temp_stack.pop();
|
||||
|
||||
continue;
|
||||
} else {
|
||||
|
||||
set_pyramid_size(channel.clone(), 0);
|
||||
temp_stack.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
set_pyramid_size(channel.clone(), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if checking_started && read_top_of_compare(channel.clone()).unwrap().1 == get_start_pattern(channel.clone()) {
|
||||
|
||||
if checking_started
|
||||
&& read_top_of_compare(channel.clone()).unwrap().1 == get_start_pattern(channel.clone())
|
||||
{
|
||||
/* leave pyramid size set for exection */
|
||||
set_pyramid_size(channel.clone(), pyramid_size * 2 - 1);
|
||||
temp_stack.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn set_pyramid_size(channel: String, size: i32) {
|
||||
let mut size_perchnl = PYRAMID_SIZE_PER_CHNL.lock().unwrap();
|
||||
let mut found = false;
|
||||
|
@ -392,16 +414,20 @@ fn get_pyramid_size(channel:String) -> i32 {
|
|||
///
|
||||
///
|
||||
fn _create_interruptor_cmd() -> Command {
|
||||
let mut cmd = Command::new(vec![
|
||||
"no pyramid".to_string(),
|
||||
"no pyramids".to_string()
|
||||
],
|
||||
"".to_string());
|
||||
let mut cmd = Command::new(
|
||||
vec!["no pyramid".to_string(), "no pyramids".to_string()],
|
||||
"".to_string(),
|
||||
);
|
||||
|
||||
/* 2. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg, String::from("test success")).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, String::from("test success"))
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -416,7 +442,6 @@ fn _create_interruptor_cmd() -> Command {
|
|||
/* 5. optionally, set min badge*/
|
||||
cmd.set_min_badge(Badge::Moderator);
|
||||
|
||||
|
||||
cmd
|
||||
}
|
||||
|
||||
|
@ -424,15 +449,12 @@ fn _create_interruptor_cmd() -> Command {
|
|||
fn _create_interruptor_module(channel: String) -> Module {
|
||||
/* 1. Create a new module */
|
||||
let modname = format!("interruptor {}", channel);
|
||||
let mut custom_mod = Module::new(
|
||||
vec![modname],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec![modname], "".to_string());
|
||||
|
||||
/* 2. Load the cmd into a new module */
|
||||
custom_mod.load_listener(_create_interruptor_listener());
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// #todo
|
||||
|
@ -441,9 +463,7 @@ fn _create_interruptor_listener() -> Listener {
|
|||
let mut listener = Listener::new();
|
||||
|
||||
/* 2b. Set a trigger condition function for listener */
|
||||
listener.set_trigger_cond_fn(
|
||||
|_:Arc<Bot>,_:ServerMessage| true
|
||||
);
|
||||
listener.set_trigger_cond_fn(|_: Arc<Bot>, _: ServerMessage| true);
|
||||
|
||||
/* 2c. Define an async fn callback execution */
|
||||
async fn execbody(_: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
|
@ -455,7 +475,6 @@ fn _create_interruptor_listener() -> Listener {
|
|||
listener.set_exec_fn(execution_async(execbody));
|
||||
|
||||
listener
|
||||
|
||||
}
|
||||
|
||||
/// #todo
|
||||
|
|
|
@ -220,17 +220,15 @@
|
|||
//!
|
||||
//! }
|
||||
|
||||
|
||||
|
||||
pub mod botcore;
|
||||
pub mod custom_mods;
|
||||
pub use botcore::bot::Bot;
|
||||
pub use botcore::bot_objects::execution_async;
|
||||
pub use botcore::bot_objects::command_condition_async;
|
||||
pub use botcore::bot_objects::listener_condition_async;
|
||||
pub use botcore::bot_objects::execution_async;
|
||||
pub use botcore::bot_objects::listener::Listener;
|
||||
pub use botcore::bot_objects::listener_condition_async;
|
||||
// pub use crate::botcore::bot_objects::command::Command;
|
||||
pub use botcore::bot_objects::command::Command;
|
||||
pub use botcore::modules::Module;
|
||||
pub use botcore::bot_objects::Badge;
|
||||
pub use botcore::modules;
|
||||
pub use botcore::modules::Module;
|
||||
|
|
|
@ -13,15 +13,13 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use forcebot_core::Bot;
|
||||
use forcebot_core::execution_async;
|
||||
use forcebot_core::Bot;
|
||||
use forcebot_core::Listener;
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -30,8 +28,7 @@ pub async fn main() {
|
|||
|
||||
/* 2. Set a trigger condition function for listener */
|
||||
|
||||
listener.set_trigger_cond_fn(
|
||||
|_:Arc<Bot>,message:ServerMessage|
|
||||
listener.set_trigger_cond_fn(|_: Arc<Bot>, message: ServerMessage| {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
for badge in msg.badges {
|
||||
if matches!(badge, x if x.name == "moderator") {
|
||||
|
@ -40,13 +37,20 @@ pub async fn main() {
|
|||
}
|
||||
}
|
||||
false
|
||||
} else { false }
|
||||
);
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
/* 3. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg, "pepeKneel".to_string()).await ;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, "pepeKneel".to_string())
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -60,5 +64,4 @@ pub async fn main() {
|
|||
|
||||
/* Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
|
|
@ -14,11 +14,9 @@ use forcebot_core::Bot;
|
|||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* 1. Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
/* 2. Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
|
|
@ -15,16 +15,14 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use forcebot_core::execution_async;
|
||||
use forcebot_core::Badge;
|
||||
use forcebot_core::Bot;
|
||||
use forcebot_core::execution_async;
|
||||
use forcebot_core::Command;
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -34,7 +32,12 @@ pub async fn main() {
|
|||
/* 2. Define an async fn callback execution */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _ = bot.chat.lock().await.say_in_reply_to(&msg, String::from("test success")).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, String::from("test success"))
|
||||
.await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
|
@ -54,5 +57,4 @@ pub async fn main() {
|
|||
|
||||
/* Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ use twitch_irc::message::ServerMessage;
|
|||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* 1. Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -25,9 +24,7 @@ pub async fn main() {
|
|||
let mut listener = Listener::new();
|
||||
|
||||
/* 2b. Set a trigger condition function for listener */
|
||||
listener.set_trigger_cond_fn(
|
||||
|_:Arc<Bot>,_:ServerMessage| true
|
||||
);
|
||||
listener.set_trigger_cond_fn(|_: Arc<Bot>, _: ServerMessage| true);
|
||||
|
||||
/* 2c. Define an async fn callback execution */
|
||||
async fn execbody(_: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
|
@ -43,5 +40,4 @@ pub async fn main() {
|
|||
|
||||
/* 4. Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ use forcebot_core::Bot;
|
|||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
/* Create the bot using env */
|
||||
let bot = Bot::new().await;
|
||||
|
||||
|
@ -30,29 +29,23 @@ pub async fn main() {
|
|||
|
||||
/* Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub mod custom_mod {
|
||||
use std::sync::Arc;
|
||||
|
||||
use forcebot_core::{execution_async, Badge, Bot, Command, Module};
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
|
||||
/// Module definition with a loaded command
|
||||
pub fn new() -> Module {
|
||||
/* 1. Create a new module */
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["test".to_string()],
|
||||
"".to_string());
|
||||
let mut custom_mod = Module::new(vec!["test".to_string()], "".to_string());
|
||||
|
||||
/* 2. Load the cmd into a new module */
|
||||
custom_mod.load_command(cmd_test());
|
||||
|
||||
custom_mod
|
||||
|
||||
}
|
||||
|
||||
/// Command definition
|
||||
|
@ -63,8 +56,12 @@ pub mod custom_mod {
|
|||
/* 2. Define exec callback */
|
||||
async fn execbody(bot: Arc<Bot>, message: ServerMessage) -> Result<String, String> {
|
||||
if let ServerMessage::Privmsg(msg) = message {
|
||||
let _= bot.chat.lock().await.say_in_reply_to(
|
||||
&msg, "test return".to_string()).await;
|
||||
let _ = bot
|
||||
.chat
|
||||
.lock()
|
||||
.await
|
||||
.say_in_reply_to(&msg, "test return".to_string())
|
||||
.await;
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue