WIP: TextMods-Module #58

Draft
HaruYuumei wants to merge 15 commits from TextMods-Module into master
2 changed files with 414 additions and 3 deletions

View file

@ -13,6 +13,7 @@ pub use crate::core::botmodules::ModulesManager;
// mod experiments;
mod experimental;
mod text_mods;
// [ ] init() function that accepts bot instance - this is passed to init() on submodules
@ -20,6 +21,7 @@ pub async fn init(mgr: Arc<ModulesManager>) {
// Modules initializer loads modules into the bot
// this is achieved by calling submodules that also have fn init() defined
// experiments::init(mgr).await
experimental::init(mgr).await;
}
experimental::init(mgr.clone()).await;
text_mods::init(Arc::clone(&mgr)).await;
}

409
src/custom/text_mods.rs Normal file
View file

@ -0,0 +1,409 @@
//! A module about editing and messing around with user text
//!
use std::collections::HashMap;
use std::sync::Arc;
use rand::{thread_rng, Rng};
use rand::seq::SliceRandom;
use twitch_irc::message::ReplyToMessage;
use crate::core::bot_actions::{actions_util, ExecBodyParams};
use crate::core::botinstance::Channel;
use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
use crate::core::identity::UserRole::*;
const OF_CMD_CHANNEL:Channel = Channel(String::new());
pub async fn init(mgr: Arc<ModulesManager>) {
let replyer = BotCommand {
module: BotModule(String::from("Replyer")),
command: String::from("Reply"),
alias: vec![
String::from("reply")
],
exec_body: actions_util::asyncbox(thereplyer),
help: String::from("txt mods help"),
required_roles: vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
VIP(OF_CMD_CHANNEL),
Chatter
],
};
replyer.add_to_modmgr(Arc::clone(&mgr)).await;
let forsen_listener = Listener{
module:BotModule(String::from("TextMods")),
name:String::from("Forsen Listener"),
exec_body:actions_util::asyncbox(forsenforsen),
help:String::from("Forsen helper"),
};
forsen_listener.add_to_modmgr(Arc::clone(&mgr)).await;
let butt = BotCommand{
module:BotModule(String::from("ButtModule")),
command:String::from("butt"),
alias:vec![],
exec_body:actions_util::asyncbox(butt),
help:String::from("butt helper"),
required_roles:vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
Chatter,
]
};
butt.add_to_modmgr(Arc::clone(&mgr)).await;
let shuffler = BotCommand{
module:BotModule(String::from("Shuffler")),
command:String::from("Shuffle"),
alias: vec![
String::from("shuffle")
],
exec_body: actions_util::asyncbox(shuffle),
help:String::from("Shuffle Help"),
required_roles:vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
VIP(OF_CMD_CHANNEL),
Chatter
]
};
shuffler.add_to_modmgr(Arc::clone(&mgr)).await;
let the8ball: BotCommand = BotCommand {
module:BotModule(String::from("8ball")),
command:String::from("8ball"),
alias: vec![String::from("8b")],
exec_body: actions_util::asyncbox(the8ball),
help:String::from("8ball Help"),
required_roles:vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
VIP(OF_CMD_CHANNEL),
Chatter
]
};
the8ball.add_to_modmgr(Arc::clone(&mgr)).await;
let percent:BotCommand = BotCommand{
module:BotModule(String::from("percent")),
command:String::from("%"),
alias:vec![],
exec_body: actions_util::asyncbox(percentage),
help: String::from("Percent Help"),
required_roles: vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
VIP(OF_CMD_CHANNEL),
Chatter
]
};
percent.add_to_modmgr(Arc::clone(&mgr)).await;
let filler: BotCommand = BotCommand{
module:BotModule(String::from("filler")),
command:String::from("fill"),
alias:vec![String::from("Fill")],
exec_body:actions_util::asyncbox(fill),
help:String::from("fill Help"),
required_roles: vec![
BotAdmin,
Broadcaster,
Mod(OF_CMD_CHANNEL),
VIP(OF_CMD_CHANNEL)
]
};
filler.add_to_modmgr(Arc::clone(&mgr)).await;
}
///Fill command, can be used to make the bot reply with a certain quantity of the same message
///
/// only works with `(prefix)fill` `word` `quantity`
///
///
async fn fill(params : ExecBodyParams)
{
let usermessage = usermsg(&params);
let quantity = usermessage.get(&2).unwrap();
let mut botreply = String::new();
for _i in 0..quantity.parse::<i32>().unwrap(){
botreply.push_str(usermessage.get(&1).unwrap().trim());
botreply.push(' ');
}
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
botreply.clone(),
params.clone()
).await;
}
///Percentage is a function that returns a ramdom %
///
async fn percentage (params : ExecBodyParams)
{
let mut _botreply = String::new();
let rng = thread_rng().gen_range(0..100);
let rng_string = rng.to_string();
_botreply = rng_string + "%";
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
_botreply.clone(),
params.clone()
).await;
}
///The 8 ball function
/// it returns a answear to the user message based on random
///
async fn the8ball(params : ExecBodyParams)
{
let mut vecanswears = Vec::new();
vecanswears.push(String::from("It is certain"));
vecanswears.push(String::from("It is decidedly so"));
vecanswears.push(String::from("Without a doubt"));
vecanswears.push(String::from("Yes definitely"));
vecanswears.push(String::from("You may rely on it"));
vecanswears.push(String::from("As I see it, yes"));
vecanswears.push(String::from("Most likely"));
vecanswears.push(String::from("Outlook good"));
vecanswears.push(String::from("Yes"));
vecanswears.push(String::from("Signs point to yes"));
vecanswears.push(String::from("Reply hazy, try again"));
vecanswears.push(String::from("Ask again later"));
vecanswears.push(String::from("Better not tell you now"));
vecanswears.push(String::from("Cannot predict now"));
vecanswears.push(String::from("Concentrate and ask again"));
vecanswears.push(String::from("Don't count on it"));
vecanswears.push(String::from("My reply is no"));
vecanswears.push(String::from("My sources say no"));
vecanswears.push(String::from("Outlook not so good"));
vecanswears.push(String::from("Very doubtful"));
let randchoice = thread_rng().gen_range(0..vecanswears.len());
let ballmessage = &vecanswears[randchoice];
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
ballmessage.clone(),
params.clone()
).await;
}
/// Shuffle Function
///
/// Grabs The user message and checks how many words it has
///
/// If the user message constains more the one word, it shuffles the words
///
/// If its only One word, it shuffles the letters in the word
async fn shuffle(params : ExecBodyParams)
{
let usermessage = usermsg(&params);
if usermessage.len() > 2
{
let mut indexes: Vec<usize> = (1..usermessage.len()).collect();
indexes.shuffle(&mut thread_rng());
let mut new_reply: HashMap<usize, String> = HashMap::new();
for (index, &new_index) in indexes.iter().enumerate() {
new_reply.insert(index, usermessage[&new_index].clone());
}
let mut botreply = String::new();
for value in new_reply.values(){
botreply.push_str(value);
botreply.push(' ');
}
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
botreply,
params.clone()
).await;
}
else {
//if it only has one word, shuffle its chars
let word = usermessage.get(&1).unwrap();
let shuffle_word: String =
word.chars()
.collect::<Vec<char>>()
.choose_multiple(&mut thread_rng(), word.len())
.collect();
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
shuffle_word,
params.clone()
).await;
}
}
///butt command hehe
///
/// All this function does is grab the user message, and randomly pick one of the words
/// in the phrase to change the random word for `butt`
///
async fn butt(params : ExecBodyParams)
{
//getting User message
let mut userm = usermsg(&params);
//choose a random word from the user phrase
let w = thread_rng().gen_range(1..userm.len());
//change the random word to butt :pepepains
userm.insert(w, String::from("Butt"));
let mut bot_reply = String::new();
for index in 1..userm.len()
{
if let Some(word) = userm.get(&index)
{
bot_reply.push_str(word);
bot_reply.push(' ');
}
}
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
bot_reply,
params.clone()
).await;
}
///Forsen.
async fn forsenforsen(params : ExecBodyParams)
{
if params.msg.message_text == "forsen" || params.msg.message_text == "Forsen"
{
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
String::from("Forsen!"),
params.clone()
).await;
}
}
///Thereplyer Function
///
/// This Function grabs the user message and reply the same message, without the command
/// at the beginning
///
async fn thereplyer(params : ExecBodyParams)
{
let user_message: HashMap<usize,String> = usermsg(&params);
let mut bot_reply = String::new();
for index in 1..user_message.len()
{
if let Some(word) = user_message.get(&index)
{
bot_reply.push_str(word);
bot_reply.push(' ');
}
}
let bot = Arc::clone(&params.bot);
let botlock = bot.read().await;
botlock
.botmgrs
.chat
.say_in_reply(
Channel(params.clone().msg.channel_login().to_string()),
bot_reply.clone(),
params.clone()
).await;
}
///Usermsg Function
///
/// Usage: this function grabs the user message, and indexate with a vector and hashmap
///
/// It returns the User message as a `Hashmap<usize,String>`, with indexs so you can utilize especific words
///
/// Where `Usize` is index and `String` is the word
pub fn usermsg(params : &ExecBodyParams) -> HashMap<usize,String>
{
//getting the user message
let sender_message = &params.msg.message_text;
//vector to store the words
let words: Vec<&str> = sender_message.split_whitespace().collect();
//using Hashmap to store the words
let mut index_words:HashMap<usize,String> = HashMap::new();
//adding to the hashmap each word
for(index,word) in words.iter().enumerate()
{
index_words.insert(index, String::from(*word));
}
index_words
}