From 8d4db0c657c6721345b0c2a3483ee8d49b1f4b2f Mon Sep 17 00:00:00 2001
From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com>
Date: Sun, 4 Feb 2024 14:28:37 -0500
Subject: [PATCH] 2024.02.04 - LATEST PROBLEM

---
 Cargo.lock                 |  62 ++++++
 Cargo.toml                 |   2 +
 src/core/botinstance.rs    | 403 +++++++++++++++++++++++++++++++++----
 src/core/botmodules.rs     | 125 +++++++++---
 src/core/identity.rs       | 274 ++++++++++++++++++++-----
 src/main.rs                |   6 +-
 src/modules.rs             |   6 +-
 src/modules/experiments.rs |  58 +++++-
 8 files changed, 815 insertions(+), 121 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 6a76afd..1425d4b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -151,7 +151,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
 name = "forcebot_rs"
 version = "0.1.0"
 dependencies = [
+ "async-trait",
  "dotenv",
+ "futures",
  "rand",
  "tokio",
  "twitch-irc",
@@ -198,7 +200,67 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
 dependencies = [
  "futures-core",
  "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+dependencies = [
+ "futures-core",
  "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
diff --git a/Cargo.toml b/Cargo.toml
index 417031d..0043332 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,3 +10,5 @@ dotenv = "0.15.0"
 tokio = { version = "1.33.0", features = ["full"] }
 twitch-irc = "5.0.1"
 rand = { version = "0.8.5", features = [] }
+futures = "0.3"
+async-trait = "0.1.77"
\ No newline at end of file
diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs
index 568d4e6..5f9561d 100644
--- a/src/core/botinstance.rs
+++ b/src/core/botinstance.rs
@@ -1,4 +1,5 @@
 
+use futures::lock::Mutex;
 use tokio::sync::mpsc::UnboundedReceiver;
 use twitch_irc::login::StaticLoginCredentials;
 use twitch_irc::ClientConfig;
@@ -8,6 +9,10 @@ use twitch_irc::message::PrivmsgMessage;
 use twitch_irc::message::ServerMessage;
 use twitch_irc::transport::tcp::TCPTransport;
 use twitch_irc::transport::tcp::TLS;
+// use std::borrow::Borrow;
+use std::borrow::BorrowMut;
+use std::boxed;
+use std::cell::Ref;
 use std::env;
 use dotenv::dotenv;
 
@@ -21,9 +26,19 @@ use crate::core::ratelimiter::RateLimiter;
 use crate::core::ratelimiter;
 
 use crate::core::botmodules;
-use crate::core::botmodules::ModulesManager;
+use crate::core::botmodules::{ModulesManager,BotAction};
 use crate::core::identity::{IdentityManager,Permissible};
 
+use std::rc::Rc;
+use std::cell::RefCell;
+use std::sync::{Arc, RwLock};
+// use futures::lock::Mutex;
+
+use std::pin::Pin;
+
+//use std::borrow::Borrow;
+use core::borrow::Borrow;
+
 
 #[derive(Debug, PartialEq, Eq, Hash, Clone)]
 pub enum ChType {
@@ -41,7 +56,8 @@ pub use ModType::BotModule;
 
 #[derive(Clone)]
 pub struct Chat {
-    pub ratelimiters : HashMap<ChType,RateLimiter>, // used to limit messages sent per channel 
+    // pub ratelimiters : HashMap<ChType,RateLimiter>, // used to limit messages sent per channel 
+    pub ratelimiters : Arc<Mutex<HashMap<ChType,RateLimiter>>>, // used to limit messages sent per channel 
     pub client : TwitchIRCClient<TCPTransport<TLS>,StaticLoginCredentials>, 
 }
 
@@ -51,19 +67,21 @@ impl Chat {
     pub fn init(ratelimiters:HashMap<ChType, RateLimiter>,
         client:TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>) -> Chat {
             Chat{
-                ratelimiters : ratelimiters,
+                ratelimiters : Arc::new(Mutex::new(ratelimiters)),
                 client : client,
             } 
     }
 
-    pub fn init_channel(&mut self, chnl:ChType) -> () {
+    // pub fn init_channel(&mut self, chnl:ChType) -> () {
+    pub async fn init_channel(&mut self, chnl:ChType) -> () {
         let n = RateLimiter::new();
-        self.ratelimiters.insert(chnl,n);
+        self.ratelimiters.lock().await.insert(chnl,n);
     } 
 
 
 
-	pub async fn say_in_reply_to(&mut self, msg:& PrivmsgMessage , mut outmsg:String) -> () {
+	// pub async fn say_in_reply_to(&mut self, msg:& PrivmsgMessage , mut outmsg:String) -> () {
+    pub async fn say_in_reply_to(&self, msg:& PrivmsgMessage , mut outmsg:String) -> () {
         /*
         formats message before sending to TwitchIRC 
 
@@ -76,7 +94,12 @@ impl Chat {
 		// self.client.say_in_reply_to(msg,outmsg).await.unwrap();
 
         // // let contextratelimiter = ratelimiters.get_mut(&msg.channel_login).expect("ERROR: Issue with Rate limiters");
-        let contextratelimiter = self.ratelimiters
+        let a = Arc::clone(&self.ratelimiters);
+        let mut a = a.lock().await;
+
+        // let contextratelimiter = self.ratelimiters
+        let contextratelimiter = a
+            // .get_mut()
             .get_mut(&Channel(String::from(&msg.channel_login)))
             .expect("ERROR: Issue with Rate limiters");
         // let contextratelimiter = self.ratelimiters.get(&msg.channel_login).expect("ERROR: Issue with Rate limiters");
@@ -140,7 +163,7 @@ impl Chat {
 #[derive(Clone)]
 pub struct BotManagers {
     // pub botmodules : ModulesManager,
-    pub identity : IdentityManager,
+    pub identity : Arc<Mutex<IdentityManager>>,
     pub chat : Chat,
 }
 
@@ -148,29 +171,49 @@ impl BotManagers {
 
     pub fn init(ratelimiters:HashMap<ChType, RateLimiter>,
         client:TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>) 
-        -> BotManagers {
-        BotManagers {
+        -> Arc<Mutex<BotManagers>> {
+        let a = Arc::new(Mutex::new(BotManagers {
             // botmodules : ModulesManager::init(),
-            identity : IdentityManager::init(),
+            identity : Arc::new(Mutex::new(IdentityManager::init())),
             chat : Chat::init(ratelimiters,client),
-        }
-
+        }));
+        a
+        
+    }
 
+    pub fn rIdentity(self) -> Arc<Mutex<IdentityManager>> {
+        self.identity
+    }
 
+    pub fn rChat(&self) -> Arc<Mutex<Chat>> {
+        Arc::new(Mutex::new(self.chat))
     }
 }
 
+
+pub struct ArcBox<T: Clone>(pub Arc<Mutex<T>>);
+
+impl<T: Clone> ArcBox<T>{
+    pub fn inst(&self) -> &Mutex<T> {
+        &self.0
+    }
+
+}
+
+//#[derive(Clone)]
+// #[derive(Copy)] // <-- Cannot be derived
 pub struct BotInstance
 {
-	prefix : char,
-	bot_channel : ChType,
+	pub prefix : char,
+	pub bot_channel : ChType,
     pub incoming_messages : UnboundedReceiver<ServerMessage>,
+    // pub incoming_messages : RefCell<UnboundedReceiver<ServerMessage>>,
     // pub chat : Chat,
-    pub botmodules : ModulesManager,
-	twitch_oauth : String,
+    pub botmodules : Arc<Mutex<ModulesManager>>,
+	pub twitch_oauth : String,
 	pub bot_channels : Vec<ChType>,
     // pub identity : IdentityManager,
-    pub botmgrs : BotManagers,
+    pub botmgrs : Arc<Mutex<BotManagers>>,
 }
 
 
@@ -179,7 +222,8 @@ impl BotInstance
 {
 
 
-    pub fn init() -> BotInstance
+    // pub fn init() -> BotInstance
+    pub fn init() -> Arc<BotInstance>
     {
         dotenv().ok();
 
@@ -242,19 +286,113 @@ impl BotInstance
         };
 
 
-        println!("{:?}",b.botmgrs.chat.ratelimiters);
+        //println!("{:?}",b.botmgrs.chat.ratelimiters);
 
 
-        b
+        Arc::new(b)
     }
 
-    pub async fn runner(mut self) -> () {
+    // async fn rcv_helper(self) -> Option<ServerMessage> {
+    //     // self.incoming_messages.get_mut().recv().await
+    //     let mut a = self.incoming_messages;
+    //     a.get_mut().recv().await
+    // }
+
+    // pub async fn runner(mut self) -> () {
+        pub async fn runner(mut self) -> () {
+
+
+        // let mut boxed_bot = Arc::new(RefCell::new(self)); // <-- [ERROR] Future cannot be handled safely 
+        
 
         let join_handle = tokio::spawn(async move {
 
-            while let Some(message) = &self.incoming_messages.recv().await {
-                // Below can be used to debug if I want to capture all messages
+            // let boxed_bot = Arc::new(Mutex::new(self));
+            // let mut boxed_bot = Arc::new(self);
+            // let bot = Rc::new(RefCell::new(self));
+            // let mut bot = Rc::new(RefCell::new(&self));
+            //let bot = Arc::new(Mutex::new(&self));
+            // let mut boxed_bot = Arc::new(RefCell::new(self));
+            let mut boxed_bot = Arc::new(Mutex::new(self));
+
+            // while let Some(message) = bot.borrow_mut().incoming_messages.recv().await {
+
+            // let bot = Arc::clone(&botinit);
+
+            // while let Some(message) = bot.lock().unwrap().incoming_messages.recv().await {
+            //let b = Arc::clone(&bot);
+
+            // let mut bot = RefCell::new(&self);
+
+            // let mut bota = bot.clone().borrow();
+
+            // let boxed_bot = Rc::new(RefCell::new(self));
+            // let  boxed_bot = Rc::new(self);
+            // let boxed_bot = Pin::new(Rc::new(self));
+            //let mut boxed_bot = Rc::new(RefCell::new(self));
+            // let mut a = (*boxed_bot).clone().into_inner();
+            // let mut a = Rc::clone(&boxed_bot).borrow_mut();
+            //let mut a =  Rc::<Rc<RefCell<BotInstance>>>::Borrow(Rc::clone(&boxed_bot));
+
+
+            // while let Some(message) = Rc::clone(&boxed_bot).into_inner().incoming_messages.recv().await {
+            // while let Some(message) = Rc::<BotInstance>::borrow(Rc::<BotInstance>::as_ref(boxed_bot)) {
+
+            // let a = boxed_bot.borrow();
+
+            // let boxed_bota = boxed_bot.borrow_mut();
+
+            // let a = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner();
+
+            // let boxed_bot = RefCell::new(Rc::new(self));
+            //let boxed_bot = Rc::new(RefCell::new(self));
+            // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await;
+
+            // let a:Borrowed = boxed_bot.borrow();
+            // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await {
+            //  while let Some(message) = RefCell::new(self).borrow_mut().incoming_messages.recv().await {
+            // while let Some(message) = Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().incoming_messages.recv().await {
+            // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().rcv_helper().await {
+            // while let Some(message) = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await {
+            // let mut a = Arc::try_unwrap(boxed_bot.clone())
+            //     .ok().unwrap()
+            //     .into_inner()
+            //     .ok().unwrap();
+            // let a = Arc::clone(&boxed_bot).into_inner().unwrap().incoming_messages;
+                // .into_inner()
+                // .try_into().
+                // .ok().unwrap();
+            // while let Some(message) = a.lock().unwrap().incoming_messages.recv().await {
+                // while let Some(message) = a.recv().await {
+            // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+            // let mut a = Arc::try_unwrap(boxed_bot.clone())
+            // .ok()
+            // .unwrap();
+            // .into_inner()
+            // .get_mut()
+            // .ok();
+            // .unwrap();
+            //let mut a = a.lock().unwrap();
+            // let a = *a;
+            // while let Some(message) = a.lock().ok().unwrap().incoming_messages.recv().await {
+            // while let Some(message) = a.get_mut().expect("Error").incoming_messages.recv().await {
+            //let tempbot = boxed_bot.clone();
+            // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().ok().unwrap().incoming_messages.recv().await {
+            // while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().incoming_messages.recv().await {
+            // while let Some(message) = boxed_bot.to_owned().incoming_messages.recv().await {
+            // while let Some(message) = self.incoming_messages.recv().await {
+            // let a:Arc<RefCell<BotInstance>> = Arc::clone(&boxed_bot);
+                // while let Some(message) = a.incoming_messages.recv().await {
+            // let a = Arc::clone(&boxed_bot).into_inner();
+            //  while let Some(message) = a.incoming_messages.recv().await {
+            let tempbot = boxed_bot.clone();
+            while let Some(message) = Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().incoming_messages.recv().await {
+            // while let Some(message) = tempbot.into_inner().incoming_messages.recv().await {
+            //while let Some(message) = boxed_bot.borrow().incoming_messages.recv().await {
+                // // Below can be used to debug if I want to capture all messages
                 // println!("Received message: {:?}", message);
+
+                // let boxed_bot = Arc::new(self);
     
                 match message {
                     ServerMessage::Notice(msg) => {
@@ -272,7 +410,35 @@ impl BotInstance
                         println!("Privmsg section");
 
                         // b.listener_main_prvmsg(&msg);
-                        self.listener_main_prvmsg(&msg).await;
+                        // self.listener_main_prvmsg(&msg).await;
+                        // bot.into_inner().listener_main_prvmsg(&msg).await;
+                        //let bot = Rc::<RefCell<&BotInstance>>::clone(&bot);
+                        
+                        // bot.borrow().listener_main_prvmsg(&msg).await;
+                        // let mut a = Rc::Clone(&bot);
+                        // a.borrow_mut().listener_main_prvmsg(&msg).await;
+                        // bot.borrow_mut().into_inner().listener_main_prvmsg(&msg).await;
+                        // bot.listener_main_prvmsg(&msg).await;
+                        // bot.lock().unwrap().listener_main_prvmsg(&msg).await;
+                        // bot.borrow_mut().listener_main_prvmsg(&msg).await;
+                        // Rc::clone(&boxed_bot).into_inner().listener_main_prvmsg(&msg).await;
+                        // boxed_bot.borrow().listener_main_prvmsg(&msg).await;
+                        // let bottemp = boxed_bot.borrow_mut();
+                        // let a = **bottemp;
+                        // Rc::try_unwrap(boxed_bot).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await;
+                        // Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await;
+                        // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().ok().unwrap().listener_main_prvmsg(&msg).await;
+                        // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+                        // let mut a = a.lock().unwrap();  
+                        // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+                        // a.listener_main_prvmsg(&msg).await;  
+
+                        // (*a).listener_main_prvmsg(&msg).await;
+                        // let a:Arc<RefCell<BotInstance>> = Arc::clone(&boxed_bot);
+                        // a.into_inner().listener_main_prvmsg(&msg).await;
+                        let tempbot = boxed_bot.clone();
+                        Arc::try_unwrap(tempbot.clone()).ok().unwrap().into_inner().listener_main_prvmsg(&msg).await ;
+
                         // - BotCommand listener should likely need to be called within the above
 
 
@@ -296,24 +462,103 @@ impl BotInstance
     
     
         join_handle.await.unwrap();
+
+
     }
 
 
+
+    pub fn get_botmodules(self) -> Arc<Mutex<ModulesManager>> {
+        // let a = self.botmodules;
+        // Arc::clone(&Arc::new(Mutex::new(self.botmodules)))
+        self.botmodules
+
+    } 
+
+    pub fn get_botactions(&self) -> &HashMap<ModType,Vec<BotAction>> {
+        self.get_botactions()
+    }
+
+    pub async fn get_botmgrs(self) -> Arc<Mutex<BotManagers>> {
+        // Arc::new(self.botmgrs)
+        // Arc::clone(&Arc::new(Mutex::new(self.botmgrs)))
+        let a = self.botmgrs;
+        // let a = *a.lock().await;
+        // let a = a.rIdentity();
+        a
+    }
+
+    pub async fn get_identity(self) -> Arc<Mutex<IdentityManager>> {
+        // let a = self.botmgrs;
+        // Arc::clone(&Arc::new(Mutex::new(a.rIdentity())))
+        // let a = self.botmgrs;
+        // Arc::clone(&Arc::new(Mutex::new(a.rIdentity())))
+        let a = self.get_botmgrs().await;
+        let a = a.lock().await;
+        // let a = a.rIdentity();
+        let a = a.clone().identity;
+        a.clone()
+    }
+
+    pub fn get_prefix(&self) -> String {
+        self.prefix.to_string()
+    }
+
 // -----------------
 // PRIVATE FUNCTIONS 
 
 
     // async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () {
-    async fn listener_main_prvmsg(&self,msg:&PrivmsgMessage) -> () {
+    async fn listener_main_prvmsg(self,msg:&PrivmsgMessage) -> () {
 
         // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
                             
         // // [ ] Need to run through all Listener Bodies for Enabled Modules for the context of the message (e.g., ModStatus is Enabled in the context for the channel)
 
-        for (_m,acts) in &self.botmodules.botactions {
+        // let botmgr = Rc::new(&self.botmgrs);
+
+        // let mut boxedbot = Rc::new(RefCell::new(self));
+        // let boxed_bot = Rc::new(RefCell::new(self));
+        // let boxed_bot = Arc::new(Mutex::new(self));
+        // let boxed_bot = Arc::new(self);
+        //let boxed_bot = Arc::clone(self);
+        // let mut boxed_bot = Arc::new(RefCell::new(self));
+        // let mut boxed_bot = Arc::new(RwLock::new(self));
+        // let boxed_bot = Arc::new(RwLock::new(self));
+        // let boxed_bot = Arc::new(Mutex::new(self));
+        let boxed_bot = Arc::new(Mutex::new(self));
+        
+
+        // for (_m,acts) in &self.botmodules.botactions {
+        // for (_m,acts) in &self.botmodules.botactions {
+            // for (_m,acts) in bot.into_inner().botmodules.botactions {
+        // let mut bot = Rc::clone(&bot);
+        // for (_m,acts) in bot.into_inner().botmodules.botactions {
+            // for (_m,acts) in bot.into_inner().botmodules.botactions {
+        // for (_m,acts) in Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions {
+            // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().botmodules.botactions {
+        // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().botmodules.botactions {
+        // for (_m,acts) in Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmodules.botactions {
+            // let a = Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmodules.botactions
+        // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+        // let b = a.read().unwrap();
+        // for (_m,acts) in a.read().unwrap().botmodules.botactions {
+        // for (_m,acts) in b.rbotmodules().botactions {
+        // for (_m,acts) in b.rbotactions() {
+            // for (_m,acts) in (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).rbotactions() {
+        // let a = boxed_bot.clone().into_inner();
+        let a = boxed_bot.lock().await;
+        //let a = a.lock().in
+        // for (_m,acts) in self.rbotactions() {
+        // for (_m,acts) in a.read().ok().unwrap().rbotactions() {
+        // for (_m,acts) in a.into_inner().ok().unwrap().rbotactions() {
+        for (_m,acts) in a.get_botactions() {
+            
             for a in acts {
 
-                match a {
+                
+
+                let _act = match a {
 
                     crate::core::botmodules::BotAction::C(c) => {
                         /* 
@@ -340,13 +585,43 @@ impl BotInstance
                         //    [x] prefix + command
 
                         let mut confirmed_bot_command = false;
-                        if inpt == self.prefix.to_string() + c.command.as_str() {
+                        
+                        // if inpt == self.prefix.to_string() + c.command.as_str() {
+                        // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + c.command.as_str() {
+                            // let a = Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string();
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string();
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string();
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string();
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+                            // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap());
+                            // let a = (*Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().read().unwrap()).prefix.to_string();
+                            // let a = self.prefix.to_string();
+                        // let a = boxed_bot.clone();
+
+                            // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() {
+                            // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + c.command.as_str() 
+                        let a = boxed_bot.lock().await;
+                        // 
+                        // if inpt == a.into_inner().prefix.to_string() + c.command.as_str() {
+                        if inpt == a.get_prefix() + c.command.as_str() {
                             confirmed_bot_command = true;
                         } 
 
                         //    [x] prefix + alias
                         for alias in &c.alias {
-                            if inpt == self.prefix.to_string() + alias.as_str() {
+                            // if inpt == self.prefix.to_string() + alias.as_str() {
+                            // if inpt == Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().prefix.to_string() + alias.as_str() {
+                            // 
+                            // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner().ok().unwrap().prefix.to_string() + alias.as_str() {
+                                // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner()
+                                // if inpt == Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().prefix.to_string() + alias.as_str() {
+                                // if inpt == Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().prefix.to_string() + alias.as_str() {
+                                // if inpt == self.prefix.to_string() + alias.as_str() {
+                                // let a = boxed_bot.clone();
+                                let a = boxed_bot.lock().await;
+                                // if inpt == a.into_inner().ok().unwrap().prefix.to_string() + alias.as_str() {
+                            // if inpt == a.into_inner().prefix.to_string() + alias.as_str() {
+                                if inpt == a.get_prefix() + alias.as_str() {
                                 confirmed_bot_command = true;
                             } 
                         }
@@ -364,24 +639,80 @@ impl BotInstance
 
                             // match self.botmgrs.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
                             // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
-                            match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+
+                            // let botref = Rc::clone(&botmgr);
+                            // if let Rc(botmgr) = botref {
+                            //     ()
+                            // } 
+
+                            // match self.botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match boxed_bot.clone().into_inner().botmgrs.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match Rc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            //let boxed_bot1 = Arc::clone(&boxed_bot);
+                            //let a = boxed_bot1.into_inner().ok().unwrap();
+                            // match boxed_bot1.into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match Arc::try_unwrap(boxed_bot.clone())
+                            //     .ok()
+                            //     .unwrap().into_inner().ok().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok() .unwrap().into_inner();
+                            // let a = Arc::try_unwrap(boxed_bot.clone()).ok().unwrap();
+                            // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner()
+                            // match a.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match Arc::try_unwrap(boxed_bot).ok().unwrap().read().unwrap().botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                                // match self.botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // match (boxed_bot.clone().into_inner().ok().unwrap()).botmgrs.identity.can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
+                            // let a = boxed_bot.clone();
+                            // let a = boxed_bot.lock().await;
+                            // // let a = a.read().ok().unwrap().botmgrs.identity;
+                            // let a = a.get_identity();
+                            // // let a = a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()) ;
+                            
+                            // match a.lock().await.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await {
+
+                            {
+                            let le = boxed_bot.lock().await;
+                            // let le = le.lock().await;
+                            let le = le.get_identity().await;
+                            let le = *le;
+                            let le = le.lock().await;
+                            let le = le.clone();
+                            let le = le.can_user_run_PRVMSG(&msg, c.required_roles.clone()).await;
+                            match le {
                                 // Ok(Permissible::Allow) => (),
                                 Permissible::Allow => {
                                     println!("Executed as permissible");
-                                    c.execute(self.botmgrs.clone(), msg.clone()).await;
+                                    // c.execute(bot, msg.clone()).await;
+                                    // if let bot = Rc::<RefCell<BotInstance>>::clone(*bot) {
+                                    //     c.execute(bot, msg.clone()).await;
+                                    // }
+                                    // let boxed_bot = Arc::new(RwLock::new(self));
+                                    c.execute(boxed_bot.clone(), msg.clone()).await;
+                                    
                                 }
-                                Permissible::Block => println!("User Not allowed to run command"),
+                                Permissible::Block => {
+                                    println!("User Not allowed to run command")
+                                },
                                 // _ => (),
-                            }
+                            };
 
                             // c.execute(self.chat.clone(), msg.clone()).await;
+                            }
                         }
                     },
 
-                    crate::core::botmodules::BotAction::L(l) => l.execute(self.botmgrs.clone(), msg.clone()).await,
+                    crate::core::botmodules::BotAction::L(l) => {
+                        // if let bot = Rc::clone(&bot) {
+                        //     l.into_inner().execute(bot, msg.clone()).await
+                        // }
+                        //let bot = Rc::clone(&bot).into_inner();
+                        // l.execute(boxed_bot.clone(), msg.clone()).await
+                        // let boxed_bot = Arc::new(RwLock::new(self));
+                        l.execute(boxed_bot.clone(), msg.clone()).await;
+                    },
 
                     _ => (),
-                }
+                };
             }
         };
 
diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs
index ab52696..a05db7d 100644
--- a/src/core/botmodules.rs
+++ b/src/core/botmodules.rs
@@ -5,6 +5,18 @@ use std::collections::HashMap;
 
 use crate::core::identity;
 
+use std::cell::RefCell;
+use std::sync::{Arc, RwLock};
+
+use std::future::Future;
+use futures::lock::Mutex;
+
+
+
+use crate::core::botinstance::{self, BotInstance};
+use std::rc::Rc;
+
+use async_trait::async_trait;
 
 /*
 
@@ -43,8 +55,6 @@ pub enum ChType {
 pub use ChType::Channel;
 use twitch_irc::message::PrivmsgMessage;
 
-use crate::core::botinstance::{self, BotInstance};
-
 
 #[derive(Debug)]
 enum StatusLvl {
@@ -57,7 +67,8 @@ pub enum ModStatusType {
     Enabled(StatusLvl),
     Disabled(StatusLvl),
 }
-    
+
+// #[derive(Clone)]
 pub enum BotAction
 {
 	C(BotCommand),
@@ -66,7 +77,8 @@ pub enum BotAction
 }
 
 impl BotAction {
-    pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){
+    // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){
+    pub async fn execute(&self,m:Arc<Mutex<BotInstance>>,n:PrivmsgMessage){
         
         match self {
             BotAction::L(a) => a.execute(m,n).await,
@@ -77,13 +89,14 @@ impl BotAction {
     }
 }
 
+#[async_trait]
 pub trait BotActionTrait 
 {
-    fn add_to_bot(self, bot:BotInstance);
-    fn add_to_modmgr(self,modmgr:&mut ModulesManager);
+    async fn add_to_bot(&self, bot:BotInstance);
+    async fn add_to_modmgr(self,modmgr:Arc<Mutex<ModulesManager>>);
 }
 
-
+// #[derive(Clone)]
 pub struct BotCommand {
     pub module : ModType,
     pub command : String, // command call name
@@ -96,20 +109,26 @@ pub struct BotCommand {
 
 impl BotCommand
 {
-    pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){
+    // pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){
+    // pub async fn execute(&self,m:Rc<&botinstance::BotManagers>,n:PrivmsgMessage){
+        pub async fn execute(&self,m:Arc<Mutex<BotInstance>>,n:PrivmsgMessage){
         (self.exec_body)(m,n).await;
     }
 }
 
-
+#[async_trait]
 impl BotActionTrait for BotCommand 
 {
-    fn add_to_bot(self, mut bot:BotInstance) {    
-        let mgr = &mut bot.botmodules;
-        self.add_to_modmgr(mgr);
+    async fn add_to_bot(&self, mut bot:BotInstance) {    
+        // let mgr = &mut bot.botmodules;
+        // let mut mgr = *mgr.lock().await;
+        // let mut mgr = &mut mgr;
+        self.add_to_modmgr(bot.botmodules);
     }
 
-    fn add_to_modmgr(self, modmgr:&mut ModulesManager) {
+    async fn add_to_modmgr(self, modmgr:Arc<Mutex<ModulesManager>>) {
+        // modmgr.add_botaction(self.module.clone(), BotAction::C(self))
+        let modmgr = *modmgr.lock().await;
         modmgr.add_botaction(self.module.clone(), BotAction::C(self))
     }
 
@@ -125,18 +144,53 @@ pub mod bot_actions {
         use std::boxed::Box;
         use std::pin::Pin;
 
-        use crate::core::botinstance::{BotManagers, Chat};
+        use std::rc::Rc;
+
+        use crate::core::botinstance::{BotInstance, BotManagers, Chat};
         use twitch_irc::message::PrivmsgMessage;
+        use std::cell::RefCell;
+        use std::sync::{Arc, RwLock};
+        use futures::lock::Mutex;
+
         
         // pub type ExecBody = Box<dyn Fn(Chat,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
         //pub type ExecBody<F> = Box<dyn Fn(Chat,PrivmsgMessage) -> Pin<Box<dyn Future<Output=F> + Send>> + Send + Sync>;
-        pub type ExecBody = Box<dyn Fn(BotManagers,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(BotManagers,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Rc<&BotManagers>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Rc<&BotInstance>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        
+        // pub type ExecBody = Box<dyn Fn(Rc<RefCell<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Rc<RefCell<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Rc<RefCell<&BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<&BotInstance>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<RefCell<&BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(RefCell<&BotInstance>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Rc<RefCell<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<Mutex<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<BotInstance>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<RefCell<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        // pub type ExecBody = Box<dyn Fn(Arc<RwLock<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        pub type ExecBody = Box<dyn Fn(Arc<Mutex<BotInstance>>,PrivmsgMessage) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
+        
+
 
         //pub fn asyncbox<T,F>(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody<F>
         // pub fn asyncbox<T>(f: fn(Chat,PrivmsgMessage) -> T) -> ExecBody
-        pub fn asyncbox<T>(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(BotManagers,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Rc<&BotManagers>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Rc<RefCell<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Rc<RefCell<&BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<&BotInstance>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<RefCell<&BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Rc<RefCell<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<Mutex<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<BotInstance>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<RefCell<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        // pub fn asyncbox<T>(f: fn(Arc<RwLock<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
+        pub fn asyncbox<T>(f: fn(Arc<Mutex<BotInstance>>,PrivmsgMessage) -> T) -> ExecBody
         where
-            T: Future<Output=()> + Send + 'static,
+            //T: Future<Output=()> + Send + 'static
+            T: Future<Output=()> + Send + 'static
         {
             Box::new(move |a,b| Box::pin(f(a,b)))
         }
@@ -157,21 +211,24 @@ pub struct Listener
 
 impl Listener
 {
-    pub async fn execute(&self,m:botinstance::BotManagers,n:PrivmsgMessage){
+    pub async fn execute(&self,m:Arc<Mutex<BotInstance>>,n:PrivmsgMessage){
         (self.exec_body)(m,n).await;
     }
 }
 
+#[async_trait]
 impl BotActionTrait for Listener 
 {
-    fn add_to_bot(self, mut bot:BotInstance) {    
-
-        let mgr = &mut bot.botmodules;
+    async fn add_to_bot(&self, mut bot:BotInstance) {    
 
+        // let mgr = &mut bot.botmodules;
+        let mgr = bot.botmodules;
         self.add_to_modmgr(mgr);
     }
 
-    fn add_to_modmgr(self, modmgr:&mut ModulesManager) {
+    // fn add_to_modmgr(self, modmgr:&mut ModulesManager) {
+    async fn add_to_modmgr(self, modmgr:Arc<Mutex<ModulesManager>>) {
+        let modmgr = *modmgr.lock().await;
         modmgr.add_botaction(self.module.clone(), BotAction::L(self))
     }
 
@@ -182,6 +239,8 @@ impl BotActionTrait for Listener
 #[derive(Debug)]
 struct Routine {}
 
+// #[derive(Clone)]
+
 pub struct ModulesManager 
 {
     statusdb: HashMap<ModType,Vec<ModStatusType>>,
@@ -191,7 +250,7 @@ pub struct ModulesManager
 impl ModulesManager 
 {
 
-    pub fn init() -> ModulesManager
+    pub fn init() -> Arc<Mutex<ModulesManager>>
     {
 
 
@@ -203,19 +262,31 @@ impl ModulesManager
             botactions : act,
         };
 
-        // initialize core modules
-        crate::core::identity::init(&mut mgr);
+        // :: [x] initialize core modules
+        // crate::core::identity::init(&mut mgr);
+
+        let a = Arc::new(Mutex::new(mgr));
+        // let a = a.clone();
+        crate::core::identity::init(a.clone());
 
         // initialize custom crate modules
-        crate::modules::init(&mut mgr);
+        // crate::modules::init(&mut mgr);
+        // let a = a.clone();
+        crate::modules::init(a.clone());
 
 
 
         println!(">> Modules Manager : End of Init");
 
-        mgr
+        // mgr
+        a
     } 
 
+    pub fn rbotactions(self) -> HashMap<ModType,Vec<BotAction>> {
+        self.botactions
+    } 
+
+
     pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType {
         // Example usage : botmanager.modstatus(
         //     BotModule("GambaCore"),
diff --git a/src/core/identity.rs b/src/core/identity.rs
index a6c6337..224aa20 100644
--- a/src/core/identity.rs
+++ b/src/core/identity.rs
@@ -1,21 +1,32 @@
 
+use std::borrow::Borrow;
 use std::collections::HashMap;
 use std::error::Error;
 
 use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand};
 use crate::core::botmodules::bot_actions::actions_util;
 
-use crate::core::botinstance::{self};
+use crate::core::botinstance::{self,BotInstance};
+use futures::lock::Mutex;
 use twitch_irc::message::{Badge, PrivmsgMessage};
 
 use crate::core::botmodules::ChType;
 
+use crate::core::botinstance::ArcBox;
+
+
+use std::rc::Rc;
+use std::cell::RefCell;
+
+use std::sync::{Arc, RwLock};
+
 fn adminvector() -> Vec<String> {
     vec![String::from("ModulatingForce")]
 }
 
 
-pub fn init(mgr:&mut ModulesManager)
+// pub fn init(mgr:&mut ModulesManager)
+pub fn init(mgr:Arc<Mutex<ModulesManager>>)
 {
 
     BotCommand {
@@ -32,7 +43,8 @@ pub fn init(mgr:&mut ModulesManager)
             ],
     }.add_to_modmgr(mgr);
 
-    async fn cmd_promote(bot:botinstance::BotManagers,msg:PrivmsgMessage) {
+    async fn cmd_promote(mut bot:Arc<Mutex<BotInstance>>,msg:PrivmsgMessage) 
+    {
         //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
         println!("Called cmd promote");
 
@@ -63,6 +75,8 @@ pub fn init(mgr:&mut ModulesManager)
             
          */
 
+        //let bot = Rcbot;
+
          println!("{}",msg.message_text);
          let mut argv = msg.message_text.split(" ");
  
@@ -84,21 +98,104 @@ pub fn init(mgr:&mut ModulesManager)
 
 
          match arg1 {
-             Some(a) if a == String::from("admin") => {
+             Some(a1) if a1 == String::from("admin") => {
                 // - BotAdmins can promote admin to give BotAdmin UserRole 
-                let a = bot.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase())));
+                //let mut bot = Rc::clone(&bot);
+                // let a = bot.botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase())));
+                // let a = Rc::try_unwrap(bot).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase())));
+                // let a = Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase())));
+
+                // let a = Rc::try_unwrap(bot).ok().unwrap()
+                // // .borrow_mut()
+                // .into_inner()
+                // .botmgrs
+                // .identity
+                // .getspecialuserroles(msg.sender.name.to_lowercase(), 
+                //     Some(ChType::Channel(msg.channel_login.to_lowercase())));
+                // let p = Rc::try_unwrap(bot.clone())
+                // let p = Arc::try_unwrap(bot.clone())
+                // .ok()
+                // .unwrap()
+                // //.into_inner()
+                // //.to_owned()
+                // // .get_mut()
+                // .into_inner();
+                // // .ok()
+                // // .unwrap();
+                // // let p = p.ok().unwrap();
+
+                // let p = bot.lock().await.get_identity();
+                // let p = p.lock().await;
+                // let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await;
+                // // let ta = *ta.await;
+                // let ta = *ta.lock().await;
+
+                // if let Some(a) = ta {
+
+
+                let p = bot.lock().await.get_identity();
+                let mut p = p.lock().await;
+                let ta = p.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await;
+
+                if let Some(a) = ta {
 
-                if let Some(a) = a {
                     if a.contains(&UserRole::BotAdmin) {
                         println!("BotAdmin allowed to promote admin");
-                        match bot.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
-                            // Success(_) => {
-                            //             ;
-                            // },
-                            ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"),
-                            ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "),
-                            ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "),
+                        // let bota = Rc::clone(&bot);
+                        // let bota = Rc::get_mut(&bota);
+                        // match bota.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                        //let mut bot = Rc::clone(&bot);
+                        // let bot = Rc::<&botinstance::BotInstance>::get_mut(&mut bot);
+                        // let mut bot = Rc::make_mut(&mut bot);
+                        // let mut bot = Rc::make_mut(&bot);
+                        // match Rc::<&botinstance::BotInstance>::get_mut(bot) {
+                        //     Some(bot) => {
+                        //         match bot.botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                        //             // Success(_) => {
+                        //             //             ;
+                        //             // },
+                        //             ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"),
+                        //             ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "),
+                        //             ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "),
+        
+                        //         }
+                        //     },
+                        //     None => (),
+                        // }
+                        //let bot = Rc::<botinstance::BotInstance>::make_mut(bot);
+                        // match Rc::<IdentityManager>::make_mut(&mut Rc::new(bot.botmgrs.identity)).promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                        // match Rc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                            // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().ok().unwrap().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                                // match Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner().botmgrs.identity.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                            // match bot.read().ok().unwrap().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                        // let a =  bot.get_mut();
+                        // match a.get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                        // let a = (*bot).clone();
+                        {
+                            // let a = bot.lock().await.get_botmgrs().clone();
+                            // let a = bot.lock().await;
+                            // let mut mutex = Arc::clone(&bot);
+                            // match mutex.get_mut().get_identity().promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)) {
+                            // slet ee = ArcBox(bot);
+                            // println!("tester: {:?}",(*bot).lock().await.get_prefix());
+                            // let mutex = Arc::clone(&bot);
+                            // let mut mutex2 = Arc::new(*mutex).into_inner().get_identity();
+                            // let mut mutex2 = Arc::clone(&mutex).into_inner().get_identity();
+                            // let a = (*bot).lock().await.get_identity();
+                            // let mut a = a.lock().await;
+                            let p = bot.lock().await.get_identity();
+                            let mut p = p.lock().await;
+                            let ta = p.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await;
 
+                            match ta {
+                                // Success(_) => {
+                                //             ;
+                                // },
+                                ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"),
+                                ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "),
+                                ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "),
+
+                            }
                         }
                     }
                 }
@@ -151,7 +248,7 @@ pub fn init(mgr:&mut ModulesManager)
     }.add_to_modmgr(mgr);
 
 
-    async fn cmd_demote(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage) {
+    async fn cmd_demote(mut _chat:Arc<Mutex<BotInstance>>,_msg:PrivmsgMessage) {
         println!("Called cmd demote");
     }
 
@@ -172,7 +269,7 @@ pub fn init(mgr:&mut ModulesManager)
     }.add_to_modmgr(mgr);
 
 
-    async fn getroles(bot:botinstance::BotManagers,msg:PrivmsgMessage) {
+    async fn getroles(bot:Arc<Mutex<BotInstance>>,msg:PrivmsgMessage) {
         println!("Called cmd getroles");
 
         /*
@@ -224,17 +321,57 @@ pub fn init(mgr:&mut ModulesManager)
 
         let targetchnl = arg2; 
 
-        match targetchnl {
+        // // let a = bot.read().ok().unwrap().get_identity();
+        // let a = bot.lock().await;
+        // // let a = a.lock().await;
+        // // let a = a.get_identity().await;
+        // let a = a.botmgrs;
+        // // let a = *(*a).lock().await;
+        // let a = *a.lock().await;
+        // let a = a.identity;
+        // let a = *a.lock().await;
+
+        // let a = bot.clone();
+        // let a = a.into_inner();
+        // let a = a.botmgrs;
+        // let a = a.into_inner();
+        // let a = a.identity;
+        // let a = a.into_inner();
+        let a = bot.clone();
+        let a = a.lock().await;
+        let a = a.get_identity().await;
+        // let a = a.lock().await;
+        let sproles = match targetchnl {
             None => {
-                let a = bot.identity.getspecialuserroles(String::from(targetuser),None);
-                println!("Retrieved User Roles >> {:?}",a);
+                // let bot = Rc::clone(&bot);
+                //let bot = Arc::clone(&bot);
+                // let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser),None);
+                // let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap();
+                // let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner();
+                // let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser),None);
+                // let a = a.ok().getspecialuserroles(String::from(targetuser),None);
+                // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None);
+                // println!("Retrieved User Roles >> {:?}",a);
+                a.lock().await.getspecialuserroles(String::from(targetuser),None).await
             },
             Some(targetchnl) => {
-                let a = bot.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl))));
-                 println!("Retrieved User Roles >> {:?}",a);
-            }, 
-        }
+                // let bot = Rc::clone(&bot);
+                // let bot = Arc::clone(&bot);
+                // let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl))));
+                // Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner()
+                // let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap();
+                // let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner();
+                // let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl))));
+                // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None);
+                // println!("Retrieved User Roles >> {:?}",a);
+                // bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None)
+                a.lock().await.getspecialuserroles(String::from(targetuser),None).await
 
+            }, 
+        };
+
+        
+        println!("Retrieved User Roles >> {:?}",sproles);
 
         // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot"))));
         // println!("{:?}",a);
@@ -271,7 +408,8 @@ pub enum Permissible {
 
 #[derive(Clone)]
 pub struct IdentityManager {
-    special_roles_users : HashMap<String,Vec<UserRole>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
+    // special_roles_users : HashMap<String,Vec<UserRole>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
+    special_roles_users : Arc<Mutex<HashMap<String,Vec<UserRole>>>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
     // parent_mgr : Box<crate::core::botinstance::BotManagers>,
     //parent_mgr : Option<Box<crate::core::botinstance::BotManagers>>,
 } 
@@ -298,7 +436,7 @@ impl IdentityManager {
         };
 
         IdentityManager {
-            special_roles_users : a,
+            special_roles_users : Arc::new(Mutex::new(a)),
             //parent_mgr : None,
         }
     }
@@ -306,7 +444,8 @@ impl IdentityManager {
     // [ ] Maybe I should create a can_user_run version that simply takes PrvMsg, but then calls can_user_run directly
     
     // pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Result<Permissible,Box<dyn Error>> 
-    pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible 
+    // pub fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible
+    pub async fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible 
     {
         // println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
 
@@ -331,11 +470,28 @@ impl IdentityManager {
             //     ChType::Channel(msg.channel_login.to_owned()),
             //     sender_badge,
             //     cmdreqroles
-            return self.can_user_run(msg.sender.name.to_owned(),
-                ChType::Channel(msg.channel_login.to_owned()),
-                sender_badge,
-                cmdreqroles
-            ) ;
+            // return self.can_user_run(msg.sender.name.to_owned(),
+            // let a = Arc::new(Mutex::new(self));
+            // let mut a = a.lock().await;
+            // let a = **a;
+            // let a = a.can_user_run(msg.sender.name.to_owned(),
+            // ChType::Channel(msg.channel_login.to_owned()),
+            // sender_badge,
+            // cmdreqroles
+            //  ) ;
+            // let a = *self;
+            // let a = Arc::new(Mutex::new(a));
+            // let a = a.lock().await.can_user_run(msg.sender.name.to_owned(),
+            //                         ChType::Channel(msg.channel_login.to_owned()),
+            //                         sender_badge,
+            //                                     cmdreqroles
+            //                                     ) ;
+            // return a;
+            self.can_user_run(msg.sender.name.to_owned(),
+                                    ChType::Channel(msg.channel_login.to_owned()),
+                                    sender_badge,
+                                                cmdreqroles
+                                                ) ;
         }
 
         
@@ -344,7 +500,7 @@ impl IdentityManager {
         Permissible::Block
     }
 
-    pub fn can_user_run(mut self,
+    pub async fn can_user_run(&self,
         usr:String,
         channelname:ChType,
         chat_badge:ChatBadge,
@@ -424,7 +580,8 @@ impl IdentityManager {
 
                         // let Some((k,v)) = self.special_roles_users.get_key_value(usr);
                         // match self.special_roles_users.get_mut(&usr.to_lowercase()) {
-                        match self.special_roles_users.get(&usr.to_lowercase()) {
+                        // match self.special_roles_users.get(&usr.to_lowercase()) {
+                        match self.special_roles_users.lock().await.get(&usr.to_lowercase()) {
                             Some(usrroles) => {
                                 // println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone())));
                                 // println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone())));
@@ -437,6 +594,7 @@ impl IdentityManager {
                                     // usrroles.push(UserRole::Mod(channelname.clone()));
                                     // a.push(UserRole::Mod(channelname.clone()));
                                     self.special_roles_users
+                                        .lock().await
                                         .get_mut(&usr.to_lowercase())
                                         .expect("ERROR")
                                         .push(UserRole::Mod(channelname.clone()));
@@ -463,7 +621,7 @@ impl IdentityManager {
 
                     println!("Mod Role required");
 
-                    if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
+                    if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) {
                         if a.contains(&UserRole::Mod(channelname.clone())) || a.contains(&UserRole::SupMod(channelname.clone())){
                             // return Ok(Permissible::Allow);
                             return Permissible::Allow
@@ -476,7 +634,7 @@ impl IdentityManager {
                 
 
                 if cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) {
-                    if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
+                    if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) {
                         if a.contains(&UserRole::SupMod(channelname.clone())) {
                             // return Ok(Permissible::Allow);
                             return Permissible::Allow
@@ -490,8 +648,8 @@ impl IdentityManager {
                 println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin));
 
                 if cmdreqroles.contains(&UserRole::BotAdmin) {
-                    println!("special roles get : {:?}",self.special_roles_users.get(&usr.to_lowercase()));
-                    if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
+                    println!("special roles get : {:?}",self.special_roles_users.lock().await.get(&usr.to_lowercase()));
+                    if let Some(a) = self.special_roles_users.lock().await.get(&usr.to_lowercase()) {
                         println!("special roles contains BotAdmin: {}",a.contains(&UserRole::BotAdmin));
                         if a.contains(&UserRole::BotAdmin) {
                             // return Ok(Permissible::Allow);
@@ -503,20 +661,31 @@ impl IdentityManager {
             Permissible::Block
         }
 
-    pub fn promote(mut self,trgchatter:String,channel:Option<ChType>,trg_role:Option<UserRole>) -> ChangeResult {
+    pub async fn promote(&mut self,trgchatter:String,channel:Option<ChType>,trg_role:Option<UserRole>) -> ChangeResult {
 
         // Note : If channel is none, getspecialuserroles() returns all roles for the user
         
         // let chatterroles = self.getspecialuserroles(trgchatter, channel);
 
-        let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone());
+        // let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone());
+        // let chatterroles = *self.getspecialuserroles(trgchatter.clone(), channel.clone()).await;
+        // let chatterroles = chatterroles.lock().await;
+        // // let chatterroles = *chatterroles;
+        // let chatterroles = chatterroles.unwrap();
 
-        let emptyvec = vec![];
 
-        let chatterroles = match chatterroles {
-            Some(a) => a,
-            _ => &(emptyvec),
-        };
+        let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await;
+        // let chatterroles = chatterroles.lock().await;
+        // let chatterroles = *chatterroles;
+        let chatterroles = chatterroles.unwrap();
+
+
+        // let emptyvec = vec![];
+
+        // let chatterroles = match chatterroles {
+        //     Some(a) => a,
+        //     _ => &(emptyvec),
+        // };
 
 
         match trg_role {
@@ -528,6 +697,7 @@ impl IdentityManager {
                     // # otherwise, trg_role for the given chnl is not assigned to the trgchatter
                     // chatterroles.push(UserRole::Mod(trg_chnl.clone()));
                     self.special_roles_users
+                        .lock().await
                         .get_mut(&trgchatter)
                         .expect("Error getting roles")
                         .push(UserRole::Mod(trg_chnl));
@@ -615,7 +785,7 @@ impl IdentityManager {
         ChangeResult::Success(String::from("TEST > Promotion Successful"))
     }
 
-    pub fn getspecialuserroles(&self,chattername:String,channel:Option<ChType>) -> Option<&Vec<UserRole>> {
+    pub async fn getspecialuserroles(&self,chattername:String,channel:Option<ChType>) -> Option<Vec<UserRole>> {
         
         // let a = chattername.to_lowercase();
 
@@ -637,7 +807,21 @@ impl IdentityManager {
 
         // println!("{a}");
 
-        self.special_roles_users.get(&a)
+        // let b = self.special_roles_users.lock().await.get(&a);
+        // match b 
+        // {
+        //     Some(b) => Some(*b),
+        //     None => None,
+        // }
+
+        let b = self.special_roles_users.lock().await.remove(&a);
+        let outp = b;
+        // let b = Arc::new(Mutex::new(outp));
+        outp
+
+
+        // let b = Arc::new(Mutex::new(b));
+        // b
 
 
 
diff --git a/src/main.rs b/src/main.rs
index cd71f0f..3ef7654 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,8 @@ pub mod core;
 pub mod modules;
 use std::process::Output;
 
+use crate::core::botinstance::ArcBox;
+
 use crate::core::botinstance::BotInstance;
 
 #[tokio::main]
@@ -11,6 +13,8 @@ pub async fn main() {
 
     let bot = BotInstance::init();
 
-    bot.runner().await;
+    bot.clone().runner().await;
+
+    println!("ERROR : EXIT Game loop");
 
 }
\ No newline at end of file
diff --git a/src/modules.rs b/src/modules.rs
index 5fbaa8a..13e39ae 100644
--- a/src/modules.rs
+++ b/src/modules.rs
@@ -10,7 +10,8 @@ pub use crate::core::botmodules::ModulesManager;
 
 // use crate::core::botinstance;
 pub use crate::core::botinstance::BotInstance;
-
+use std::sync::Arc;
+use futures::lock::Mutex;
 
 // [ ] Load submodules
 
@@ -25,7 +26,8 @@ mod experiments;
 //     // F: std::future::Future + Send,
 //     // F : Send,
 //     F : Send + ?Sized,
-pub fn init(mgr:&mut ModulesManager)
+// pub fn init(mgr:&mut ModulesManager)
+pub fn init(mgr:Arc<Mutex<ModulesManager>>)
 {
     // Modules initializer loads modules into the bot
     // this is achieved by calling submodules that also have fn init() defined
diff --git a/src/modules/experiments.rs b/src/modules/experiments.rs
index 0c3709b..828d9f2 100644
--- a/src/modules/experiments.rs
+++ b/src/modules/experiments.rs
@@ -17,7 +17,8 @@ use std::future::Future;
 use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType};
 use crate::core::botmodules::bot_actions::actions_util;
 
-use crate::core::botinstance::{self};
+use crate::core::botinstance::{self,BotInstance};
+use futures::lock::Mutex;
 use twitch_irc::message::PrivmsgMessage;
 
 use crate::core::identity;
@@ -25,8 +26,13 @@ use crate::core::identity;
 
 use rand::Rng;
 
+use std::rc::Rc;
 
-pub fn init(mgr:&mut ModulesManager)
+use std::sync::{Arc, RwLock};
+
+
+// pub fn init(mgr:&mut ModulesManager)
+pub fn init(mgr:Arc<Mutex<ModulesManager>>)
 {
 
 
@@ -69,7 +75,7 @@ pub fn init(mgr:&mut ModulesManager)
 }
 
 
-async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage)
+async fn good_girl(mut bot:Arc<Mutex<BotInstance>>,msg:PrivmsgMessage) 
 {
     println!("In GoodGirl() Listener");
     //println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
@@ -82,6 +88,13 @@ async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage)
 
     // let roll = rand::thread_rng().gen_range(1..=5);
 
+    // let mut bot = Rc::clone(&bot);
+    // let mut bot = Rc::get_mut(&mut bot);
+    // let bot = match bot {
+    //     Some(bot) => bot,
+    //     None => (),
+    // }
+
 
 
     if msg.sender.name == "ModulatingForce" // && msg.message_text.contains("GoodGirl") 
@@ -92,17 +105,42 @@ async fn good_girl(mut bot:botinstance::BotManagers,msg:PrivmsgMessage)
         let rollwin = rand::thread_rng().gen_ratio(1,5);
         if rollwin {
             println!("In GoodGirl() > Win");
-            bot.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await;
+            // let bot = Rc::get_mut(&bot).expect("Error");
+            // bot.botmgrs.chat.say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await;
+            // Rc::<botinstance::BotInstance>::get_mut(mut bot)
+            // if let Some(bot) = Rc::<&botinstance::BotInstance>::get_mut(bot) {
+
+                // match bot{
+                //     Some(bot) => {
+                //         bot
+                //         .botmgrs
+                //         .chat
+                //         .say_in_reply_to(&msg,String::from("GoodGirl xdd ")).await;
+                //     }
+                //     None => (),
+                // }
+                // Arc::try_unwrap(bot).ok().unwrap().botmgrs.chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await;
+                let a = bot.clone();
+                // let a = a.read().ok().unwrap();
+                // let a = a.lock().await.get_botmgrs();
+                // let a = a.lock().await.rChat();
+
+                let a = (*bot).lock().await.get_botmgrs();
+                let a = a.lock().await.rChat();
+                let mut a = (*a).lock().await;
+
+                // a.rbotmgrs().chat.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await;
+                // a.lock().await.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await;
+                a.say_in_reply_to(&msg, String::from("GoodGirl xdd ")).await;
         }
-            
+        
+
     }
-
-    
-
-    
+            
 }
 
-async fn testy(mut _chat:botinstance::BotManagers,_msg:PrivmsgMessage)
+
+async fn testy(mut _chat:Arc<Mutex<BotInstance>>,_msg:PrivmsgMessage)
 {
     println!("testy triggered!")