From 2315270388077f255fe8533c7610cbce3a6d198d Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 2 Apr 2024 21:19:20 -0300
Subject: [PATCH 01/13] Gulpo adding textmods to branch

oh god pls let everythign works fine
---
 src/custom/text_mods.rs | 159 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)
 create mode 100644 src/custom/text_mods.rs

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
new file mode 100644
index 0000000..50ff131
--- /dev/null
+++ b/src/custom/text_mods.rs
@@ -0,0 +1,159 @@
+use std::collections::HashMap;
+use std::sync::Arc;
+use crate::core::{bot_actions::*, botlog};
+use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
+use crate::core::identity::UserRole::*;
+use rand::{thread_rng, Rng};
+use tokio::time::{sleep, Duration};
+
+
+
+pub async fn init(mgr: &Arc<ModulesManager>) {
+
+    // Example Working BotCommand Add
+    BotCommand {
+        module: BotModule(String::from("TextMods")),
+        command: String::from("Reply"),
+        alias: vec![],
+        exec_body: actions_util::asyncbox(fors),
+        help: String::from("txt mods help"),
+        required_roles: vec![BotAdmin],
+    }
+    .add_to_modmgr(Arc::clone(&mgr))
+    .await;
+
+    Listener {
+        module: BotModule(String::from("TextMods")),
+        name: String::from("This Guy Listener"),
+        exec_body: actions_util::asyncbox(mods),
+        help: String::from(""),
+    }
+    .add_to_modmgr(Arc::clone(&mgr))
+    .await;
+}
+async fn fors(params: ExecBodyParams)
+{
+    println!("Test triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call
+    botlog::debug(
+        "test triggered!",
+        Some("modules > tesst()".to_string()),
+        Some(&params.msg),
+    );
+}
+async fn mods(params: ExecBodyParams)
+{
+    // //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));
+    }
+
+    //if command is rw/Rw
+    if index_words.get(&0).unwrap().to_string() == "+reply" 
+        || index_words.get(&0).unwrap().to_string() == "+Reply"
+    {
+        //do what i want with the message
+
+        //new message
+        let mut message:String = String::new();
+
+        //adding all other words in index words to the reply phrase
+        //for index starting at 1 til max indexed words
+        for index in 1..index_words.len()
+        {   
+            //if the word = the word on the indexed words
+            if let Some(words) = index_words.get(&index) 
+            {
+                //add message
+                message.push_str(words);
+                //add space
+                message.push_str(" ");
+                //do agane
+            }
+        }   
+
+        //bot typing the rest of the message
+        let bot = Arc::clone(&params.bot);
+        let botlock = bot.read().await;
+    
+        // uses chat.say_in_reply_to() for the bot controls for messages
+        botlock
+            .botmgrs
+            .chat
+            .say_in_reply_to(&params.msg,
+                message,
+                params.clone())
+            .await;
+        sleep(Duration::from_secs_f64(0.5)).await;
+    }
+
+    /*
+    
+        TESTING AREA, WAITING FOR THREAD_RNG FIX :D
+    
+     */
+    // if index_words.get(&0).unwrap().to_string() == "+shuffle" 
+    //     || index_words.get(&0).unwrap().to_string() == "+Shuffle"{
+    //     //do what i want with the message
+
+    //     //new message
+    //     let mut message:String = String::new();
+
+    //         let mut rnd = thread_rng();
+    //         let random_number = rnd.gen_range(1..=100);
+    //     //adding all other words in index words to the reply phrase
+    //     //for index starting at 1 til max indexed words
+    //     for index in 1..index_words.len()
+    //     {   
+    //         //if the word = the word on the indexed words
+    //         if let Some(words) = index_words.get(&index) 
+    //         {
+    //             //add message
+    //             message.push_str(words);
+    //             //add space
+    //             message.push_str(" ");
+    //             //do agane
+    //         }
+    //     }   
+
+    //     //bot typing the rest of the message
+    //     let bot = Arc::clone(&params.bot);
+    //     let botlock = bot.read().await;
+
+    //     // uses chat.say_in_reply_to() for the bot controls for messages
+    //     botlock
+    //         .botmgrs
+    //         .chat
+    //         .say_in_reply_to(&params.msg,
+    //             message,
+    //             params.clone())
+    //         .await;
+    //     sleep(Duration::from_secs_f64(0.5)).await;
+    // }
+
+
+    if words.get(0).unwrap().to_string() == "forsen"
+    {
+        //bot typing the rest of the message
+        let bot = Arc::clone(&params.bot);
+        let botlock = bot.read().await;
+    
+        // uses chat.say_in_reply_to() for the bot controls for messages
+        botlock
+            .botmgrs
+            .chat
+            .say_in_reply_to(&params.msg, String::from("Forsen!"), params.clone())
+            .await;
+        sleep(Duration::from_secs_f64(0.5)).await;
+    }
+
+}
\ No newline at end of file
-- 
2.49.0


From b561d24c6533c0d6debc4dec1e1657fe88d7ad96 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 2 Apr 2024 22:05:30 -0300
Subject: [PATCH 02/13] Fixed Custom giving error

---
 src/custom.rs           | 8 +++++---
 src/custom/text_mods.rs | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/custom.rs b/src/custom.rs
index 6107797..01fde56 100644
--- a/src/custom.rs
+++ b/src/custom.rs
@@ -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;
+
+}
\ No newline at end of file
diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 50ff131..97d060c 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -3,12 +3,12 @@ use std::sync::Arc;
 use crate::core::{bot_actions::*, botlog};
 use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
 use crate::core::identity::UserRole::*;
-use rand::{thread_rng, Rng};
+//use rand::{thread_rng, Rng};
 use tokio::time::{sleep, Duration};
 
 
 
-pub async fn init(mgr: &Arc<ModulesManager>) {
+pub async fn init(mgr: Arc<ModulesManager>) {
 
     // Example Working BotCommand Add
     BotCommand {
-- 
2.49.0


From 6fd5f7b7fbf07128024a6facecbff91668222210 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Wed, 3 Apr 2024 09:14:37 -0300
Subject: [PATCH 03/13] text-mods Module: re-writen code

the module now works with the actual command and not with the listener
---
 src/custom/text_mods.rs | 195 ++++++++++++++--------------------------
 1 file changed, 67 insertions(+), 128 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 97d060c..616c254 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,48 +1,39 @@
 use std::collections::HashMap;
 use std::sync::Arc;
-use crate::core::{bot_actions::*, botlog};
-use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
+use crate::core::bot_actions::{actions_util, ExecBodyParams};
+use crate::core::botinstance::Channel;
+use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule,ModulesManager};
 use crate::core::identity::UserRole::*;
+const OF_CMD_CHANNEL:Channel = Channel(String::new());
 //use rand::{thread_rng, Rng};
-use tokio::time::{sleep, Duration};
-
-
 
 pub async fn init(mgr: Arc<ModulesManager>) {
 
-    // Example Working BotCommand Add
-    BotCommand {
+    //DEFINING BOT COMMAND
+    let replyer = BotCommand {
         module: BotModule(String::from("TextMods")),
-        command: String::from("Reply"),
-        alias: vec![],
-        exec_body: actions_util::asyncbox(fors),
+        command: String::from("reply"),
+        alias: vec![
+            String::from("reply1")
+            ],
+        exec_body: actions_util::asyncbox(thereplyer),
         help: String::from("txt mods help"),
-        required_roles: vec![BotAdmin],
-    }
-    .add_to_modmgr(Arc::clone(&mgr))
-    .await;
+        required_roles: vec![
+            BotAdmin,
+            //I had to add Broadcaster, just the BotAdmin didn't work, it
+            //said I had no permission, even if being the broadcaster of the channel
+            Broadcaster,
+            Mod(OF_CMD_CHANNEL),
+            ],
+    };
+    //ADDINNG BOT ACTION TO MODULE MANAGER
+    replyer.add_to_modmgr(Arc::clone(&mgr)).await;
+}
 
-    Listener {
-        module: BotModule(String::from("TextMods")),
-        name: String::from("This Guy Listener"),
-        exec_body: actions_util::asyncbox(mods),
-        help: String::from(""),
-    }
-    .add_to_modmgr(Arc::clone(&mgr))
-    .await;
-}
-async fn fors(params: ExecBodyParams)
+
+ async fn thereplyer(params : ExecBodyParams)
 {
-    println!("Test triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call
-    botlog::debug(
-        "test triggered!",
-        Some("modules > tesst()".to_string()),
-        Some(&params.msg),
-    );
-}
-async fn mods(params: ExecBodyParams)
-{
-    // //getting the user message
+    //getting the user message
     let sender_message = &params.msg.message_text;
 
     //vector to store the words
@@ -57,103 +48,51 @@ async fn mods(params: ExecBodyParams)
         index_words.insert(index, String::from(*word));
     }
 
-    //if command is rw/Rw
-    if index_words.get(&0).unwrap().to_string() == "+reply" 
-        || index_words.get(&0).unwrap().to_string() == "+Reply"
-    {
-        //do what i want with the message
-
-        //new message
-        let mut message:String = String::new();
-
-        //adding all other words in index words to the reply phrase
-        //for index starting at 1 til max indexed words
-        for index in 1..index_words.len()
-        {   
-            //if the word = the word on the indexed words
-            if let Some(words) = index_words.get(&index) 
-            {
-                //add message
-                message.push_str(words);
-                //add space
-                message.push_str(" ");
-                //do agane
-            }
-        }   
-
-        //bot typing the rest of the message
-        let bot = Arc::clone(&params.bot);
-        let botlock = bot.read().await;
+    //reply message
+    let mut bot_reply = String::new();
     
-        // uses chat.say_in_reply_to() for the bot controls for messages
-        botlock
+    for index in 1..index_words.len()
+    {
+        if let Some(word) = index_words.get(&index)
+        {
+            bot_reply.push_str(word);
+            bot_reply.push(' ');
+        }
+    }
+    
+
+    let bot = Arc::clone(&params.bot);
+
+
+            let botlock = bot.read().await;
+
+            // uses chat.say_in_reply_to() for the bot controls for messages
+            botlock
             .botmgrs
             .chat
-            .say_in_reply_to(&params.msg,
-                message,
-                params.clone())
-            .await;
-        sleep(Duration::from_secs_f64(0.5)).await;
-    }
-
-    /*
-    
-        TESTING AREA, WAITING FOR THREAD_RNG FIX :D
-    
-     */
-    // if index_words.get(&0).unwrap().to_string() == "+shuffle" 
-    //     || index_words.get(&0).unwrap().to_string() == "+Shuffle"{
-    //     //do what i want with the message
-
-    //     //new message
-    //     let mut message:String = String::new();
-
-    //         let mut rnd = thread_rng();
-    //         let random_number = rnd.gen_range(1..=100);
-    //     //adding all other words in index words to the reply phrase
-    //     //for index starting at 1 til max indexed words
-    //     for index in 1..index_words.len()
-    //     {   
-    //         //if the word = the word on the indexed words
-    //         if let Some(words) = index_words.get(&index) 
-    //         {
-    //             //add message
-    //             message.push_str(words);
-    //             //add space
-    //             message.push_str(" ");
-    //             //do agane
-    //         }
-    //     }   
-
-    //     //bot typing the rest of the message
-    //     let bot = Arc::clone(&params.bot);
-    //     let botlock = bot.read().await;
-
-    //     // uses chat.say_in_reply_to() for the bot controls for messages
-    //     botlock
-    //         .botmgrs
-    //         .chat
-    //         .say_in_reply_to(&params.msg,
-    //             message,
-    //             params.clone())
-    //         .await;
-    //     sleep(Duration::from_secs_f64(0.5)).await;
-    // }
+            .say_in_reply_to(
+                &params.msg, 
+                bot_reply.clone(),
+                params.clone()
+            ).await;
+}
 
 
-    if words.get(0).unwrap().to_string() == "forsen"
-    {
-        //bot typing the rest of the message
-        let bot = Arc::clone(&params.bot);
-        let botlock = bot.read().await;
-    
-        // uses chat.say_in_reply_to() for the bot controls for messages
-        botlock
-            .botmgrs
-            .chat
-            .say_in_reply_to(&params.msg, String::from("Forsen!"), params.clone())
-            .await;
-        sleep(Duration::from_secs_f64(0.5)).await;
-    }
 
-}
\ No newline at end of file
+
+
+
+//    //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));
+//    }
\ No newline at end of file
-- 
2.49.0


From 07028cb519cc8a8bdd7b7f26e4d3dc4a057be05f Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Wed, 3 Apr 2024 09:21:18 -0300
Subject: [PATCH 04/13] txtMods add alias

---
 src/custom/text_mods.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 616c254..7d08e4f 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -12,9 +12,9 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     //DEFINING BOT COMMAND
     let replyer = BotCommand {
         module: BotModule(String::from("TextMods")),
-        command: String::from("reply"),
+        command: String::from("Reply"),
         alias: vec![
-            String::from("reply1")
+            String::from("reply")
             ],
         exec_body: actions_util::asyncbox(thereplyer),
         help: String::from("txt mods help"),
-- 
2.49.0


From bb2222e42b776d08a1b4a65093727e11f145df28 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Wed, 3 Apr 2024 09:34:41 -0300
Subject: [PATCH 05/13] added Forsen

---
 src/custom/text_mods.rs | 49 +++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 12 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 7d08e4f..9292db7 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
 use std::sync::Arc;
 use crate::core::bot_actions::{actions_util, ExecBodyParams};
 use crate::core::botinstance::Channel;
-use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule,ModulesManager};
+use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
 use crate::core::identity::UserRole::*;
 const OF_CMD_CHANNEL:Channel = Channel(String::new());
 //use rand::{thread_rng, Rng};
@@ -28,8 +28,34 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     };
     //ADDINNG BOT ACTION TO MODULE MANAGER
     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;
 }
 
+    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;
+        
+            // uses chat.say_in_reply_to() for the bot controls for messages
+            botlock
+            .botmgrs
+            .chat
+            .say_in_reply_to(
+                &params.msg, 
+                String::from("Forsen!"),
+                params.clone()
+            ).await;
+        }
+    }
 
  async fn thereplyer(params : ExecBodyParams)
 {
@@ -62,19 +88,18 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     
 
     let bot = Arc::clone(&params.bot);
+    let botlock = bot.read().await;
 
+    // uses chat.say_in_reply_to() for the bot controls for messages
+    botlock
+    .botmgrs
+    .chat
+    .say_in_reply_to(
+        &params.msg, 
+        bot_reply.clone(),
+        params.clone()
+    ).await;
 
-            let botlock = bot.read().await;
-
-            // uses chat.say_in_reply_to() for the bot controls for messages
-            botlock
-            .botmgrs
-            .chat
-            .say_in_reply_to(
-                &params.msg, 
-                bot_reply.clone(),
-                params.clone()
-            ).await;
 }
 
 
-- 
2.49.0


From 6a71e3375beb4177f2090d0bbeaf02d76b21a0cf Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Sat, 6 Apr 2024 19:36:24 -0300
Subject: [PATCH 06/13] Added butt command - still works to do

Working on a "change the text" command/listener
---
 src/custom/text_mods.rs | 98 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 17 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 9292db7..8960476 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,5 +1,7 @@
 use std::collections::HashMap;
 use std::sync::Arc;
+use rand::{thread_rng, Rng};
+
 use crate::core::bot_actions::{actions_util, ExecBodyParams};
 use crate::core::botinstance::Channel;
 use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};
@@ -36,8 +38,66 @@ pub async fn init(mgr: Arc<ModulesManager>) {
         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),
+        ]
+    };
+    butt.add_to_modmgr(Arc::clone(&mgr)).await;
+
 }
 
+    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;
+        
+        // uses chat.say_in_reply_to() for the bot controls for messages
+        botlock
+        .botmgrs
+        .chat
+        .say_in_reply_to(
+            &params.msg, 
+            bot_reply,
+            params.clone()
+        ).await;
+
+    }
+
+
+
+
+
     async fn forsenforsen(params : ExecBodyParams)
     {
         if params.msg.message_text == "forsen" || params.msg.message_text == "Forsen"
@@ -59,27 +119,13 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
  async fn thereplyer(params : ExecBodyParams)
 {
-    //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));
-    }
-
+    let user: HashMap<usize,String> = usermsg(&params);
     //reply message
     let mut bot_reply = String::new();
     
-    for index in 1..index_words.len()
+    for index in 1..user.len()
     {
-        if let Some(word) = index_words.get(&index)
+        if let Some(word) = user.get(&index)
         {
             bot_reply.push_str(word);
             bot_reply.push(' ');
@@ -102,7 +148,25 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
 }
 
+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
+
+}
 
 
 
-- 
2.49.0


From 13663d1ae3c0bd40abb5d5a5844e1d963c2dca52 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Sun, 7 Apr 2024 15:25:07 -0300
Subject: [PATCH 07/13] Shuffle thing!

---
 src/custom/text_mods.rs | 67 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 8960476..5aab4ce 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,6 +1,7 @@
 use std::collections::HashMap;
 use std::sync::Arc;
 use rand::{thread_rng, Rng};
+use rand::seq::SliceRandom;
 
 use crate::core::bot_actions::{actions_util, ExecBodyParams};
 use crate::core::botinstance::Channel;
@@ -26,6 +27,8 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             //said I had no permission, even if being the broadcaster of the channel
             Broadcaster,
             Mod(OF_CMD_CHANNEL),
+            VIP(OF_CMD_CHANNEL),
+            Chatter
             ],
     };
     //ADDINNG BOT ACTION TO MODULE MANAGER
@@ -50,12 +53,72 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             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![],
+        exec_body: actions_util::asyncbox(shuff),
+        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;
+
 }
 
+    async fn shuff(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());
+                //println!("{:?}", new_reply[&index]);
+            }
+            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;
+            
+            // uses chat.say_in_reply_to() for the bot controls for messages
+            botlock
+            .botmgrs
+            .chat
+            .say_in_reply_to(
+                &params.msg, 
+                botreply,
+                params.clone()
+            ).await;
+
+        }
+        else {
+            //if it only has one word, shuffle its chars (exclude the n word monkaLaugh)
+        }
+        
+    }
+
+
     async fn butt(params : ExecBodyParams)
     {   
         //getting User message
@@ -94,10 +157,6 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
     }
 
-
-
-
-
     async fn forsenforsen(params : ExecBodyParams)
     {
         if params.msg.message_text == "forsen" || params.msg.message_text == "Forsen"
-- 
2.49.0


From 12da47253d2c886fc407e75e03a7d9e05e86cb9d Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 9 Apr 2024 11:32:04 -0300
Subject: [PATCH 08/13] comments and small edits

---
 src/custom/text_mods.rs | 82 ++++++++++++++++++++---------------------
 1 file changed, 39 insertions(+), 43 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 5aab4ce..62c41ee 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,3 +1,5 @@
+//! A module about editing and messing around with user text
+//! 
 use std::collections::HashMap;
 use std::sync::Arc;
 use rand::{thread_rng, Rng};
@@ -8,13 +10,11 @@ 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());
-//use rand::{thread_rng, Rng};
 
 pub async fn init(mgr: Arc<ModulesManager>) {
 
-    //DEFINING BOT COMMAND
     let replyer = BotCommand {
-        module: BotModule(String::from("TextMods")),
+        module: BotModule(String::from("Replyer")),
         command: String::from("Reply"),
         alias: vec![
             String::from("reply")
@@ -23,17 +23,16 @@ pub async fn init(mgr: Arc<ModulesManager>) {
         help: String::from("txt mods help"),
         required_roles: vec![
             BotAdmin,
-            //I had to add Broadcaster, just the BotAdmin didn't work, it
-            //said I had no permission, even if being the broadcaster of the channel
             Broadcaster,
             Mod(OF_CMD_CHANNEL),
             VIP(OF_CMD_CHANNEL),
             Chatter
             ],
     };
-    //ADDINNG BOT ACTION TO MODULE MANAGER
+
     replyer.add_to_modmgr(Arc::clone(&mgr)).await;
 
+
     let forsen_listener = Listener{
         module:BotModule(String::from("TextMods")),
         name:String::from("Forsen Listener"),
@@ -61,8 +60,10 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     let shuffler = BotCommand{
         module:BotModule(String::from("Shuffler")),
         command:String::from("Shuffle"),
-        alias: vec![],
-        exec_body: actions_util::asyncbox(shuff),
+        alias: vec![
+            String::from("shuffle")
+        ],
+        exec_body: actions_util::asyncbox(shuffle),
         help:String::from("Shuffle Help"),
         required_roles:vec![
             BotAdmin,
@@ -75,8 +76,14 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     shuffler.add_to_modmgr(Arc::clone(&mgr)).await;
 
 }
-
-    async fn shuff(params : ExecBodyParams)
+    /// 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);
         
@@ -89,7 +96,6 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             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());
-                //println!("{:?}", new_reply[&index]);
             }
             let mut botreply = String::new();
             for value in new_reply.values(){
@@ -100,8 +106,6 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
             let bot = Arc::clone(&params.bot);
             let botlock = bot.read().await;
-            
-            // uses chat.say_in_reply_to() for the bot controls for messages
             botlock
             .botmgrs
             .chat
@@ -118,7 +122,11 @@ pub async fn init(mgr: Arc<ModulesManager>) {
         
     }
 
-
+    ///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
@@ -144,8 +152,6 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
         let bot = Arc::clone(&params.bot);
         let botlock = bot.read().await;
-        
-        // uses chat.say_in_reply_to() for the bot controls for messages
         botlock
         .botmgrs
         .chat
@@ -157,14 +163,13 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
     }
 
+    ///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;
-        
-            // uses chat.say_in_reply_to() for the bot controls for messages
             botlock
             .botmgrs
             .chat
@@ -176,15 +181,19 @@ pub async fn init(mgr: Arc<ModulesManager>) {
         }
     }
 
+    ///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: HashMap<usize,String> = usermsg(&params);
-    //reply message
+    let user_message: HashMap<usize,String> = usermsg(&params);
     let mut bot_reply = String::new();
     
-    for index in 1..user.len()
+    for index in 1..user_message.len()
     {
-        if let Some(word) = user.get(&index)
+        if let Some(word) = user_message.get(&index)
         {
             bot_reply.push_str(word);
             bot_reply.push(' ');
@@ -194,8 +203,6 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
     let bot = Arc::clone(&params.bot);
     let botlock = bot.read().await;
-
-    // uses chat.say_in_reply_to() for the bot controls for messages
     botlock
     .botmgrs
     .chat
@@ -207,6 +214,13 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
 }
 
+///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
@@ -225,22 +239,4 @@ pub fn usermsg(params : &ExecBodyParams) -> HashMap<usize,String>
     }
     index_words
 
-}
-
-
-
-
-//    //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));
-//    }
\ No newline at end of file
+}
\ No newline at end of file
-- 
2.49.0


From 4c6bc2e84e73fdf3900f83b2988b4a73a534a1b8 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 9 Apr 2024 13:36:21 -0300
Subject: [PATCH 09/13] Shuffler now Shuffles single Words :D

---
 src/custom/text_mods.rs | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 62c41ee..d0ec2a4 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,6 +1,8 @@
 //! A module about editing and messing around with user text
 //! 
 use std::collections::HashMap;
+use std::os::windows::thread;
+use std::string;
 use std::sync::Arc;
 use rand::{thread_rng, Rng};
 use rand::seq::SliceRandom;
@@ -117,7 +119,25 @@ pub async fn init(mgr: Arc<ModulesManager>) {
 
         }
         else {
-            //if it only has one word, shuffle its chars (exclude the n word monkaLaugh)
+            //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_to(
+                &params.msg, 
+                shuffle_word,
+                params.clone()
+            ).await;
         }
         
     }
-- 
2.49.0


From 94ea1455351fbf3b213fef5222e06ea4b3106287 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 9 Apr 2024 16:32:10 -0300
Subject: [PATCH 10/13] changes to textmods to merge

---
 src/custom/text_mods.rs | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index d0ec2a4..06b8721 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -1,8 +1,6 @@
 //! A module about editing and messing around with user text
 //! 
 use std::collections::HashMap;
-use std::os::windows::thread;
-use std::string;
 use std::sync::Arc;
 use rand::{thread_rng, Rng};
 use rand::seq::SliceRandom;
@@ -111,11 +109,11 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             botlock
             .botmgrs
             .chat
-            .say_in_reply_to(
-                &params.msg, 
-                botreply,
-                params.clone()
-            ).await;
+            .say_in_reply(
+                    Channel(params.clone().msg.channel_login().to_string()),
+                    botreply,
+                  params.clone()
+                ).await;
 
         }
         else {
@@ -133,10 +131,10 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             botlock
             .botmgrs
             .chat
-            .say_in_reply_to(
-                &params.msg, 
+            .say_in_reply(
+                Channel(params.clone().msg.channel_login().to_string()),
                 shuffle_word,
-                params.clone()
+              params.clone()
             ).await;
         }
         
@@ -175,10 +173,10 @@ pub async fn init(mgr: Arc<ModulesManager>) {
         botlock
         .botmgrs
         .chat
-        .say_in_reply_to(
-            &params.msg, 
+        .say_in_reply(
+            Channel(params.clone().msg.channel_login().to_string()),
             bot_reply,
-            params.clone()
+          params.clone()
         ).await;
 
     }
@@ -193,8 +191,8 @@ pub async fn init(mgr: Arc<ModulesManager>) {
             botlock
             .botmgrs
             .chat
-            .say_in_reply_to(
-                &params.msg, 
+            .say_in_reply(
+                Channel(params.clone().msg.channel_login().to_string()),
                 String::from("Forsen!"),
                 params.clone()
             ).await;
@@ -226,8 +224,8 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     botlock
     .botmgrs
     .chat
-    .say_in_reply_to(
-        &params.msg, 
+    .say_in_reply(
+        Channel(params.clone().msg.channel_login().to_string()),
         bot_reply.clone(),
         params.clone()
     ).await;
-- 
2.49.0


From 313b6ecfa9047775f0475eb121772ef493132be9 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Tue, 9 Apr 2024 16:50:07 -0300
Subject: [PATCH 11/13] Updating textmods to say_in_reply

---
 src/custom/text_mods.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 06b8721..5124084 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -4,6 +4,7 @@ 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;
-- 
2.49.0


From 027c03ab1ee7cb7b13c4c22f59d1254a1854db23 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Sun, 14 Apr 2024 17:09:43 -0300
Subject: [PATCH 12/13] magic 8ball implementation

---
 src/custom/text_mods.rs | 70 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 5124084..015c4e9 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -76,7 +76,77 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     };
     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;
+
+
 }
+
+
+///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
-- 
2.49.0


From 2fb6c8f3b9db00299780e0b081b9c3a8419ccd67 Mon Sep 17 00:00:00 2001
From: haruyuumei <luzivotto.erick@gmail.com>
Date: Mon, 15 Apr 2024 13:57:39 -0300
Subject: [PATCH 13/13] Percent + fill commands added

---
 src/custom/text_mods.rs | 82 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 2 deletions(-)

diff --git a/src/custom/text_mods.rs b/src/custom/text_mods.rs
index 015c4e9..2a1b87b 100644
--- a/src/custom/text_mods.rs
+++ b/src/custom/text_mods.rs
@@ -93,7 +93,87 @@ pub async fn init(mgr: Arc<ModulesManager>) {
     };
     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;
 }
 
 
@@ -132,8 +212,6 @@ async fn the8ball(params : ExecBodyParams)
     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
-- 
2.49.0