guest_badge module
This commit is contained in:
parent
2a884f9571
commit
a9da9f4192
9 changed files with 413 additions and 46 deletions
src
|
@ -1,7 +1,9 @@
|
|||
//! WIP Fun forcebot with catered customizations #todo
|
||||
//!
|
||||
//! Custom modules that can be managed in chat through `disable` and `enable` commands
|
||||
//! - funbot
|
||||
//! - funbot
|
||||
//! - guests
|
||||
//!
|
||||
//!
|
||||
//! Be sure the followig is defined in `.env`
|
||||
//! - login_name
|
||||
|
@ -14,7 +16,7 @@
|
|||
//! - Get a Bot Chat Token here - <https://twitchtokengenerator.com>
|
||||
//! - More Info - <https://dev.twitch.tv/docs/authentication>
|
||||
|
||||
use forcebot_rs_v2::Bot;
|
||||
use forcebot_rs_v2::{custom_mods::guest_badge, Bot};
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
@ -24,8 +26,11 @@ pub async fn main() {
|
|||
|
||||
/* 1. Load the module into the bot */
|
||||
bot.load_module(funbot_objs::create_module());
|
||||
|
||||
/* 2. Load Custom Modules */
|
||||
bot.load_module(guest_badge::create_module());
|
||||
|
||||
/* 2. Run the bot */
|
||||
/* 3. Run the bot */
|
||||
bot.run().await;
|
||||
|
||||
}
|
||||
|
@ -39,7 +44,9 @@ pub mod funbot_objs {
|
|||
|
||||
/// Create a Module with a loaded Command object
|
||||
pub fn create_module() -> Module {
|
||||
let mut custom_mod = Module::new("funbot".to_string(), "".to_string());
|
||||
let mut custom_mod = Module::new(
|
||||
vec!["funbot".to_string()],
|
||||
"".to_string());
|
||||
|
||||
custom_mod.load_command(create_cmd_test());
|
||||
|
||||
|
|
|
@ -44,7 +44,9 @@ pub mod custom_mod {
|
|||
/// Module with a loaded command
|
||||
pub fn new() -> Module {
|
||||
/* 1. Create a new module */
|
||||
let mut custom_mod = Module::new("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());
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
use tokio::sync::{mpsc::UnboundedReceiver, Mutex};
|
||||
use twitch_irc::{login::StaticLoginCredentials, message::ServerMessage, SecureTCPTransport, TwitchIRCClient};
|
||||
use dotenv::dotenv;
|
||||
use std::{env, sync::Arc};
|
||||
use std::{env, sync::Arc, time::{Duration, Instant}};
|
||||
|
||||
use crate::{Command, Listener, Module};
|
||||
use crate::{Badge, Command, Listener, Module};
|
||||
|
||||
use super::bot_objects::built_in_objects;
|
||||
use super::{bot_objects::built_in_objects, modules::{self, Status}};
|
||||
|
||||
|
||||
/// Twitch chat bot
|
||||
|
@ -30,7 +30,9 @@ pub struct Bot
|
|||
/// modules
|
||||
modules: Vec<Module>,
|
||||
/// channel module status
|
||||
channel_module_status: Mutex<Vec<(String,String,String)>>
|
||||
channel_module_status: Mutex<Vec<(String,String,modules::Status)>>,
|
||||
/// chatter guest badges - chatter,channel,Badge,start_time,duration
|
||||
chatter_guest_badges: Mutex<Vec<(String,String,Badge,Instant,Duration)>>
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,6 +48,8 @@ impl Bot
|
|||
/// - bot_admins
|
||||
pub fn new() -> Bot {
|
||||
|
||||
|
||||
|
||||
dotenv().ok();
|
||||
let bot_login_name = env::var("login_name").unwrap().to_owned();
|
||||
let oauth_token = env::var("access_token").unwrap().to_owned();
|
||||
|
@ -107,6 +111,7 @@ impl Bot
|
|||
admins,
|
||||
modules: vec![],
|
||||
channel_module_status: Mutex::new(vec![]),
|
||||
chatter_guest_badges: Mutex::new(vec![]),
|
||||
};
|
||||
|
||||
for cmd in built_in_objects::create_commands() {
|
||||
|
@ -145,18 +150,28 @@ impl Bot
|
|||
for cmd in &(*bot).commands {
|
||||
|
||||
let a = cmd.clone();
|
||||
if a.command_triggered(bot.clone(),msg.clone()) {
|
||||
if a.command_triggered(bot.clone(),msg.clone()).await {
|
||||
|
||||
let _ = cmd.execute_fn(bot.clone(),message.clone()).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for module in &(*bot).modules {
|
||||
'module_loop: for module in &(*bot).modules {
|
||||
|
||||
// skip modules that are disable
|
||||
let cms_lock = bot.channel_module_status.lock().await;
|
||||
if cms_lock.contains(&(msg.channel_login.clone(),module.get_name(),"disabled".to_string()))
|
||||
{ continue; }
|
||||
|
||||
for channel_flags in cms_lock.iter() {
|
||||
if channel_flags.0 == msg.channel_login.clone() {
|
||||
|
||||
if module.get_names().contains(&channel_flags.1) && channel_flags.2 == Status::Disabled {
|
||||
continue 'module_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for listener in module.get_listeners() {
|
||||
|
||||
|
@ -169,7 +184,7 @@ impl Bot
|
|||
for cmd in module.get_commands() {
|
||||
|
||||
let a = cmd.clone();
|
||||
if a.command_triggered(bot.clone(),msg.clone()) {
|
||||
if a.command_triggered(bot.clone(),msg.clone()).await {
|
||||
|
||||
let _ = cmd.execute_fn(bot.clone(),message.clone()).await;
|
||||
}
|
||||
|
@ -196,6 +211,16 @@ impl Bot
|
|||
pub fn load_command(&mut self,c : Command) {
|
||||
self.commands.push(c);
|
||||
}
|
||||
|
||||
|
||||
pub fn get_module(&self,module:String) -> Option<Module> {
|
||||
for modl in self.modules.clone() {
|
||||
if modl.get_names().contains(&module) {
|
||||
return Some(modl);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -212,26 +237,93 @@ impl Bot
|
|||
self.modules.push(m)
|
||||
}
|
||||
|
||||
pub async fn get_channel_module_status(&self,channel:String,module:String) -> Status {
|
||||
let found_disabled:bool = {
|
||||
let cms_lock = self.channel_module_status.lock().await;
|
||||
|
||||
let mut found = false;
|
||||
|
||||
for channel_flags in cms_lock.iter() {
|
||||
if channel_flags.0 == channel {
|
||||
if channel_flags.1 == module && channel_flags.2 == Status::Disabled {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
found
|
||||
};
|
||||
if found_disabled { return Status::Disabled;}
|
||||
else { return Status::Enabled; };
|
||||
|
||||
}
|
||||
|
||||
pub async fn disable_module(&self,channel:String,module:String){
|
||||
let mut lock = self.channel_module_status.lock().await;
|
||||
if !lock.contains(&(channel.clone(),module.clone(),"disabled".to_string())) {
|
||||
lock.push((channel,module,"disabled".to_string()));
|
||||
}
|
||||
|
||||
let found_disabled:bool = {
|
||||
let cms_lock = self.channel_module_status.lock().await;
|
||||
|
||||
let mut found = false;
|
||||
|
||||
for channel_flags in cms_lock.iter() {
|
||||
if channel_flags.0 == channel {
|
||||
if channel_flags.1 == module && channel_flags.2 == Status::Disabled {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
found
|
||||
};
|
||||
|
||||
if !found_disabled {
|
||||
|
||||
let mut cms_lock = self.channel_module_status.lock().await;
|
||||
cms_lock.push((channel,module,Status::Disabled));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub async fn enable_module(&self,channel:String,module:String){
|
||||
let mut lock = self.channel_module_status.lock().await;
|
||||
if lock.contains(&(channel.clone(),module.clone(),"disabled".to_string())) {
|
||||
if lock.contains(&(channel.clone(),module.clone(),Status::Disabled)) {
|
||||
|
||||
let index = lock
|
||||
.iter()
|
||||
.position(|x| *x ==
|
||||
(channel.clone(),module.clone(),"disabled".to_string()))
|
||||
(channel.clone(),module.clone(),Status::Disabled))
|
||||
.unwrap();
|
||||
lock.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
badges.push((temp_badge.2.clone(),temp_badge.3,temp_badge.4));
|
||||
}
|
||||
}
|
||||
|
||||
badges
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use super::bot::Bot;
|
|||
|
||||
|
||||
/// chat badge
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone,PartialEq, Eq,Debug)]
|
||||
pub enum Badge {
|
||||
Moderator,
|
||||
Broadcaster,
|
||||
|
@ -36,13 +36,13 @@ where
|
|||
|
||||
/// collection of functions to create built in objects
|
||||
pub mod built_in_objects {
|
||||
|
||||
const TEMP_BADGE_DUR_MIN:u64 = 30;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{sync::Arc, time::{Duration, Instant}};
|
||||
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
use crate::{asyncfn_box, Badge, Bot, Command};
|
||||
use crate::{asyncfn_box, modules::Status, Badge, Bot, Command};
|
||||
|
||||
|
||||
/// create a vector of command build in objects
|
||||
|
@ -52,6 +52,7 @@ pub mod built_in_objects {
|
|||
|
||||
cmds.push(create_disable_cmd());
|
||||
cmds.push(create_enable_cmd());
|
||||
cmds.push(create_iam_role_cmd());
|
||||
|
||||
cmds
|
||||
|
||||
|
@ -64,12 +65,19 @@ 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 {
|
||||
for (i,arg) in msg.message_text.split(" ").enumerate() {
|
||||
let mut action_taken = false;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
let _ = bot.client.say_in_reply_to(&msg, String::from("Disabled!")).await ;
|
||||
if action_taken {
|
||||
let _ = bot.client.say_in_reply_to(&msg, String::from("Disabled!")).await ;
|
||||
}
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
@ -93,13 +101,38 @@ 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 {
|
||||
for (i,arg) in msg.message_text.split(" ").enumerate() {
|
||||
|
||||
let mut bot_message="".to_string();
|
||||
let mut re_enabled = false;
|
||||
|
||||
for (i,arg) in msg.message_text.replace("\u{e0000}","").trim().split(" ").enumerate() {
|
||||
if i > 1 {
|
||||
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()) {
|
||||
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.client.say_in_reply_to(&msg,
|
||||
format!("Enabled! {}", bot_message)
|
||||
).await ;
|
||||
|
||||
}
|
||||
|
||||
let _ = bot.client.say_in_reply_to(&msg, String::from("Enabled!")).await ;
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
@ -113,7 +146,7 @@ pub mod built_in_objects {
|
|||
/* 5. optionally, set min badge*/
|
||||
cmd.set_min_badge(Badge::Moderator);
|
||||
cmd
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// adminonly command that grants a temporary role
|
||||
|
@ -121,31 +154,88 @@ pub mod built_in_objects {
|
|||
/* 1. Create a new blank cmd */
|
||||
let mut cmd = Command::new(vec![
|
||||
"I am ".to_string(),
|
||||
"I'm ".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.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
|
||||
// if not dont have the badge or have a lower priviledge badge
|
||||
// and they dont have an active guest badge, ths admin can be
|
||||
// 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 mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Moderator {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if found {
|
||||
/* do nothing */
|
||||
} else {
|
||||
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;
|
||||
|
||||
let _ = bot.client.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 mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Vip {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if found {
|
||||
/* do nothing */
|
||||
} else {
|
||||
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;
|
||||
|
||||
let _ = bot.client.say_in_reply_to(&msg,
|
||||
format!("Temp {:?} issued for {:?} minutes",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 mut found = false;
|
||||
for temp_badge in curr_temp_badges {
|
||||
if temp_badge.0 == Badge::Broadcaster {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if found {
|
||||
/* do nothing */
|
||||
} else {
|
||||
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;
|
||||
|
||||
let _ = bot.client.say_in_reply_to(&msg,
|
||||
format!("Temp {:?} issued for {:?} minutes",Badge::Broadcaster,TEMP_BADGE_DUR_MIN)
|
||||
).await ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = bot.client.say_in_reply_to(&msg, String::from("Disabled!")).await ;
|
||||
// let _ = bot.client.say_in_reply_to(&msg, String::from("Disabled!")).await ;
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ pub struct Command
|
|||
exec_fn : Arc<ExecBody>,
|
||||
min_badge : Badge,
|
||||
admin_only : bool,
|
||||
/// admin role overrides channel badgen- default : false
|
||||
admin_override : bool,
|
||||
prefix : String,
|
||||
custom_cond_fn : fn(Arc<Bot>,PrivmsgMessage) -> bool,
|
||||
}
|
||||
|
@ -49,6 +51,7 @@ impl Command
|
|||
exec_fn : Arc::new(asyncfn_box(execbody)),
|
||||
min_badge : Badge::Vip,
|
||||
admin_only : true,
|
||||
admin_override : false ,
|
||||
custom_cond_fn : |_:Arc<Bot>,_:PrivmsgMessage| true,
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +73,7 @@ impl Command
|
|||
/// checks if the trigger condition is met
|
||||
/// specifically if the message is a valid command and min badge roles provided
|
||||
///
|
||||
pub fn command_triggered(&self,bot:Arc<Bot>,msg:PrivmsgMessage) -> bool {
|
||||
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();
|
||||
|
@ -89,18 +92,21 @@ impl Command
|
|||
}
|
||||
|
||||
|
||||
fn caller_badge_ok(cmd:&Command,bot:Arc<Bot>,message:PrivmsgMessage) -> bool {
|
||||
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;
|
||||
} ;
|
||||
|
||||
// adminonly commands will can only be ran by admins
|
||||
// adminOnly commands will can only be ran by admins
|
||||
if cmd.admin_only && bot.get_admins().contains(&message.sender.login) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// admin role overrides badge check if enabled
|
||||
if cmd.admin_override && bot.get_admins().contains( &message.sender.login) { return true; }
|
||||
|
||||
for badge in message.badges {
|
||||
|
||||
match cmd.min_badge {
|
||||
|
@ -123,6 +129,15 @@ impl Command
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -153,7 +168,7 @@ impl Command
|
|||
// custom_cond_ok(self, bot.clone(), msg.clone()));
|
||||
|
||||
cmd_called(self, bot.clone(), msg.clone()) &&
|
||||
caller_badge_ok(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, msg)
|
||||
|
||||
|
@ -175,4 +190,10 @@ impl Command
|
|||
pub fn set_admin_only(&mut self,admin_only:bool) {
|
||||
self.admin_only = admin_only
|
||||
}
|
||||
|
||||
/// sets admin_override . This lets admins bypass
|
||||
/// badge restrictions
|
||||
pub fn set_admin_override(&mut self,admin_override:bool) {
|
||||
self.admin_override = admin_override
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,21 @@
|
|||
|
||||
use crate::{Command, Listener};
|
||||
|
||||
#[derive(PartialEq, Eq,Debug)]
|
||||
pub enum Status {
|
||||
Disabled,
|
||||
Enabled
|
||||
}
|
||||
|
||||
/// Bot `Module` that groups a set of `bot_objects`
|
||||
///
|
||||
/// Elevated chatters can disable modules by their name or chat alias
|
||||
#[derive(Clone)]
|
||||
pub struct Module
|
||||
{
|
||||
name: String,
|
||||
_alias: String,
|
||||
name: Vec<String>,
|
||||
// _alias: String,
|
||||
bot_read_description : String,
|
||||
listeners: Vec<Listener>,
|
||||
commands: Vec<Command>,
|
||||
}
|
||||
|
@ -17,10 +24,11 @@ pub struct Module
|
|||
impl Module
|
||||
{
|
||||
/// create a new module
|
||||
pub fn new(name:String,alias:String) -> Module {
|
||||
pub fn new(name:Vec<String>,bot_read_description:String) -> Module {
|
||||
Module {
|
||||
name,
|
||||
_alias: alias,
|
||||
// _alias: alias,
|
||||
bot_read_description,
|
||||
listeners: vec![],
|
||||
commands: vec![]
|
||||
}
|
||||
|
@ -44,8 +52,13 @@ impl Module
|
|||
self.commands.clone()
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> String {
|
||||
pub fn get_names(&self) -> Vec<String> {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
pub fn get_bot_read_description(&self) -> String {
|
||||
self.bot_read_description.clone()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod guest_badge;
|
140
src/custom_mods/guest_badge.rs
Normal file
140
src/custom_mods/guest_badge.rs
Normal file
|
@ -0,0 +1,140 @@
|
|||
use std::{sync::Arc, time::{Duration, Instant}};
|
||||
|
||||
use twitch_irc::message::ServerMessage;
|
||||
|
||||
use crate::{asyncfn_box, Badge, Bot, Command, Module};
|
||||
|
||||
/// guest_badge / guest module
|
||||
///
|
||||
/// Temporary badges can be issued to chatters. The bot then opens functionality
|
||||
/// to that chatter baded on the recognized role
|
||||
///
|
||||
/// Chatters with real badge roles will be able to share guest
|
||||
/// badges based on their role
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
|
||||
const VIP_GIVEN_DUR_MIN:u64 = 15;
|
||||
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());
|
||||
|
||||
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 ; }
|
||||
}
|
||||
result
|
||||
};
|
||||
|
||||
|
||||
let mut badges_issued =false;
|
||||
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 }
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if badges_issued {
|
||||
|
||||
|
||||
let _= bot.client.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())
|
||||
}
|
||||
|
||||
cmd.set_exec_fn(asyncfn_box(execbody));
|
||||
|
||||
cmd.set_admin_only(false);
|
||||
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() {
|
||||
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 }
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if badges_issued {
|
||||
let _= bot.client.say_in_reply_to(
|
||||
&msg, format!("Guest badges issued for {} min",MOD_GIVEN_DUR_MIN)).await;
|
||||
return Result::Ok("Success".to_string());
|
||||
}
|
||||
}
|
||||
Result::Err("Not Valid message type".to_string())
|
||||
}
|
||||
|
||||
cmd.set_exec_fn(asyncfn_box(execbody));
|
||||
|
||||
cmd.set_admin_only(false);
|
||||
cmd.set_admin_override(true);
|
||||
cmd.set_min_badge(Badge::Moderator);
|
||||
cmd
|
||||
|
||||
|
||||
}
|
|
@ -137,7 +137,7 @@
|
|||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! ## Modertor Reactor
|
||||
//! ## Moderator Reactor
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
|
@ -197,10 +197,11 @@
|
|||
|
||||
|
||||
pub mod botcore;
|
||||
pub mod custom_mods;
|
||||
pub use crate::botcore::bot::Bot;
|
||||
pub use crate::botcore::bot_objects::asyncfn_box;
|
||||
pub use crate::botcore::bot_objects::listener::Listener;
|
||||
pub use crate::botcore::bot_objects::command::Command;
|
||||
pub use crate::botcore::modules::Module;
|
||||
pub use crate::botcore::bot_objects::Badge;
|
||||
|
||||
pub use crate::botcore::modules;
|
||||
|
|
Loading…
Add table
Reference in a new issue