diff --git a/Cargo.lock b/Cargo.lock index 35395b8..5320e7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "base64" version = "0.13.0" @@ -172,6 +181,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "mime" version = "0.3.16" @@ -285,6 +300,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -391,6 +423,7 @@ version = "0.1.0" dependencies = [ "frankenstein", "rand", + "regex", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c2f35f3..2575d0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] frankenstein = "0.13" -rand = { version = "0.8.5", features = ["small_rng"] } \ No newline at end of file +rand = { version = "0.8.5", features = ["small_rng"] } +regex = "1" diff --git a/src/commands.rs b/src/commands.rs index d6d3af4..c44c3ea 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -3,39 +3,26 @@ use frankenstein::{ MessageEntityType }; use super::utils; +use super::uwuify; use rand::prelude::*; #[derive(Hash, Eq, PartialEq, Clone)] pub enum Command { - Ping, - Marco, Dice, - Cookie + Cookie, + Uwu, + Brat } pub static COMMAND_LIST: [Command; 4] = [ - Command::Ping, - Command::Marco, Command::Dice, - Command::Cookie + Command::Cookie, + Command::Uwu, + Command::Brat ]; pub fn get_command_attrs<'a>(cmd: &Command) -> utils::CommandAttrs<'a> { match cmd { - Command::Ping => { - utils::CommandAttrs { - name: "ping", - description: "ping", - handler: ping as fn(&utils::Context, Message) - } - }, - Command::Marco => { - utils::CommandAttrs { - name: "marco", - description: "marco?", - handler: marco as fn(&utils::Context, Message) - } - }, Command::Dice => { utils::CommandAttrs { name: "dice", @@ -50,17 +37,23 @@ pub fn get_command_attrs<'a>(cmd: &Command) -> utils::CommandAttrs<'a> { handler: cookie as fn(&utils::Context, Message) } } + Command::Uwu => { + utils::CommandAttrs { + name: "uwu", + description: "Uwuify me", + handler: uwu as fn(&utils::Context, Message) + } + } + Command::Brat => { + utils::CommandAttrs { + name: "brat", + description: ":3", + handler: brat as fn(&utils::Context, Message) + } + } } } -fn ping(ctx: &utils::Context, message: Message) { - utils::send_message(ctx, message.chat.id, "pong!", Some(message.message_id)); -} - -fn marco(ctx: &utils::Context, message: Message) { - utils::send_message(ctx, message.chat.id, "Polo!", Some(message.message_id)); -} - fn dice(ctx: &utils::Context, message: Message) { let mut rng = thread_rng(); let mut payload = 6; @@ -78,4 +71,22 @@ fn dice(ctx: &utils::Context, message: Message) { fn cookie(ctx: &utils::Context, message: Message) { utils::send_message(ctx, message.chat.id, "Here, take a cookie 🍪", Some(message.message_id)); +} + +fn uwu(ctx: &utils::Context, message: Message) { + if let Some(reply) = message.reply_to_message { + utils::send_message(ctx, message.chat.id, &uwuify::uwuify(String::from(reply.text.unwrap())), Some(message.message_id)); + } +} + +fn brat(ctx: &utils::Context, message: Message) { + let mut rng = thread_rng(); + let brat_strings = vec![ + ":3", + "Make me", + "👀" + ]; + if let Some(reply) = message.reply_to_message { + utils::send_message(ctx, message.chat.id, brat_strings[rng.gen_range(0..brat_strings.len())], Some(reply.message_id)); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5fde68f..647df04 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use frankenstein::{ mod commands; mod utils; +mod uwuify; static TOKEN: &str = ""; @@ -36,7 +37,7 @@ fn main() { loop { let result = ctx.api.get_updates(&update_params); - println!("result: {:?}", result); + // println!("result: {:?}", result); match result { Ok (response) => { diff --git a/src/utils.rs b/src/utils.rs index 47d35f2..df3d1c7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -59,37 +59,37 @@ pub fn init_command_list(ctx: &Context) { pub fn exec_command(ctx: &Context, message: Message) { let mut cmd: Option = None; - match &message.reply_to_message { - Some (r_message) => { - if r_message.from.as_ref().unwrap().id == ctx.user_id { - cmd = Some(commands::Command::Ping); - } else { - cmd = None; - } - } - None => { - if let Some(entitites) = &message.entities { - let text = message.text.as_ref().unwrap(); - for e in entitites { - if e.type_field == MessageEntityType::BotCommand { - let command = &(text)[usize::from(e.offset)..usize::from(e.offset+e.length)]; - - for c in &commands::COMMAND_LIST { - if "/".to_string() + commands::get_command_attrs(c).name == command.split("@").collect::>()[0] { - cmd = Some(c.clone()); - break - } - } - - if cmd == None { - eprintln!("Unknown command: {:?}", e); - } + // match &message.reply_to_message { + // Some (r_message) => { + // if r_message.from.as_ref().unwrap().id == ctx.user_id { + // cmd = Some(commands::Command::Ping); + // } else { + // cmd = None; + // } + // } + // None => { + if let Some(entitites) = &message.entities { + let text = message.text.as_ref().unwrap(); + for e in entitites { + if e.type_field == MessageEntityType::BotCommand { + let command = &(text)[usize::from(e.offset)..usize::from(e.offset+e.length)]; + + for c in &commands::COMMAND_LIST { + if "/".to_string() + commands::get_command_attrs(c).name == command.split("@").collect::>()[0] { + cmd = Some(c.clone()); + break } - break; + } + + if cmd == None { + eprintln!("Unknown command: {:?}", e); } } + break; } - }; + } + // } + // }; if let Some(c) = cmd { (commands::get_command_attrs(&c).handler)(ctx, message); } diff --git a/src/uwuify.rs b/src/uwuify.rs new file mode 100644 index 0000000..771cb38 --- /dev/null +++ b/src/uwuify.rs @@ -0,0 +1,147 @@ +use regex::{ Captures, Regex }; +use rand::prelude::*; + +static UWU_PROBA: f64 = 0.5; +static STUTTER_PROBA: f64 = 0.2; +static NYA_PROBA: f64 = 1.0; + +fn replace_open_ponct(txt: String) -> String { + let open_ponct = "。・:*:・゚★₊。・:*:・゚☆ "; + let re = Regex::new(r"[(<{«]").unwrap(); + re.replace_all(&txt, open_ponct).to_string() +} + +fn replace_close_ponct(txt: String) -> String { + let close_ponct = " ☆゚・:*:・。₊★゚・:*:・。"; + let re = Regex::new(r"[)>}»]").unwrap(); + re.replace_all(&txt, close_ponct).to_string() +} + +fn replace_face_ponct(txt: String) -> String { + let mut rng = thread_rng(); + let faces = vec![ + "(・`ω´・)", + // ";;w;;", + "owo", + "UwU", + ">w<", + "^w^", + "(* ^ ω ^)", + "(⌒ω⌒)", + "ヽ(*・ω・)ノ", + "(○´∀`○)", + "(○・ω・○)", + "\(^▽^)/", + "nya~", + ":3" + ]; + let re = Regex::new(r"[.,?!]").unwrap(); + re.replace_all(&txt, |_: &Captures| { + String::from(" ") + faces[rng.gen_range(0..faces.len())] + }).to_string() +} + +fn uwu_injector(txt: String) -> String { + let mut rng = thread_rng(); + let re = Regex::new(r"(?i)(ou|owo|uwu|o|u|r)").unwrap(); + re.replace_all(&txt, |cap: &Captures| { + let c = cap.get(1).unwrap().as_str(); + if rng.gen_bool(UWU_PROBA) { + match c.to_lowercase().as_str() { + "o" => { String::from(c) + "wo" }, + "u" => { String::from(c) + "wu" }, + "r" => { String::from("w") }, + "owo" => { String::from(c) }, + "uwu" => { String::from(c) }, + "ou" => { match c { + "ou" => String::from("uwu"), + "Ou" => String::from("Uwu"), + "OU" => String::from("UWU"), + _ => panic!() + }}, + a => { String::from(a) } + } + } else { + c.to_string() + } + }).to_string() +} + +fn stutter(txt: String) -> String { + let mut rng = thread_rng(); + let re = Regex::new(r"(?i)\b([bcdfgjkptv])").unwrap(); + re.replace_all(&txt, |cap: &Captures| { + let c = cap.get(1).unwrap().as_str(); + if rng.gen_bool(STUTTER_PROBA) { + c.to_string() + "-" + c + } else { + c.to_string() + } + }).to_string() +} + +fn nyaifier(txt: String) -> String { + let mut rng = thread_rng(); + let re = Regex::new(r"(?i)(n)([aiou])").unwrap(); + re.replace_all(&txt, |cap: &Captures| { + let n = cap.get(1).unwrap().as_str(); + let c = cap.get(2).unwrap().as_str(); + if rng.gen_bool(NYA_PROBA) { + n.to_string() + match c { + "A" | "I" | "O" | "U" => "Y", + _ => "y" + } + c + } else { + n.to_string() + c + } + }).to_string() +} + +fn oui_replacer(txt: String) -> String { + let re = Regex::new(r"(?i)(o)(ui)|(u)(i)|(y)(up|ep)").unwrap(); + re.replace_all(&txt, |cap: &Captures| { + let c1 = cap.get(1).unwrap().as_str(); + let c2 = cap.get(2).unwrap().as_str(); + match c2 { + "UI" | "I" | "UP" | "EP" => "WI", + _ => { + match c1 { + "O" | "U" | "Y" => "Wi", + _ => "wi" + } + } + } + }).to_string() +} + +fn non_replacer(txt: String) -> String { + let re = Regex::new(r"(?i)(n)(on|ope|an)").unwrap(); + re.replace_all(&txt, |cap: &Captures| { + let c1 = cap.get(1).unwrap().as_str(); + let c2 = cap.get(2).unwrap().as_str(); + match c2 { + "ON" | "OPE" | "AN" => "NYON", + _ => { + match c1 { + "N" => "Nyon", + _ => "nyon" + } + } + } + }).to_string() +} + +pub fn uwuify(txt: String) -> String { + let mut text = txt; + println!("{:?}", text); + text = replace_open_ponct(text); + text = replace_close_ponct(text); + text = replace_face_ponct(text); + text = oui_replacer(text); + text = non_replacer(text); + text = uwu_injector(text); + text = stutter(text); + text = nyaifier(text); + + return text +} \ No newline at end of file