initial commit, completed lenny as poc

This commit is contained in:
2023-03-02 20:14:02 -05:00
commit 2a79a12c8a
6 changed files with 1365 additions and 0 deletions

43
src/main.rs Normal file
View File

@@ -0,0 +1,43 @@
use std::collections::VecDeque;
use irc::{client::prelude::*, error::Error};
use futures::prelude::*;
mod module;
#[tokio::main]
async fn main() -> Result<(), Error>{
let max_len = 100;
let config = Config::load("config.toml")?;
let mut client = Client::from_config(config).await?;
client.identify()?;
let mut stream = client.stream()?;
let sender = client.sender();
let mut message_buf: VecDeque<Message> = VecDeque::with_capacity(max_len);
while let Some(message) = stream.next().await.transpose()? {
print!("{}",message);
let response = module::handle(&message, &message_buf);
if let Some((target,msg))= response {
print!("{}",message);
sender.send_privmsg(target,msg)?;
}
if message_buf.len() < max_len {
message_buf.push_front(message);
}
else {
let _ = message_buf.pop_back();
message_buf.push_front(message);
}
}
return Ok(());
}

31
src/module.rs Normal file
View File

@@ -0,0 +1,31 @@
use std::collections::VecDeque;
use irc::proto::{Message, Command::*};
//list of available modules, add mod [MODULE_NAME]; when you complete a new module
mod lenny;
type ModuleFunc = fn(&Message, &VecDeque<Message>)->Option<(String, String)>;
const NUM_MODS:usize = 1;
const MOD_FUNCS: [ModuleFunc;NUM_MODS] = [lenny::Lenny::mod_message];
pub fn handle(message: &Message, message_buf: &VecDeque<Message>) -> Option<(String,String)> {
if let PRIVMSG(_,_) = message.command.clone() {
for function in MOD_FUNCS{
let response = function(message, message_buf);
if response.is_some() {
return response;
}
}
}
None
}
pub trait Module {
fn usage(message: &Message) -> (String,String);
fn mod_message(message: &Message, message_buf: &VecDeque<Message>) -> Option<(String,String)>;
}

39
src/module/lenny.rs Normal file
View File

@@ -0,0 +1,39 @@
use std::collections::VecDeque;
use irc::proto::{Message, Command::*};
use regex::Regex;
use rand::prelude::Rng;
const LENNYS:[&'static str;12] = ["( ͡° ͜ʖ ͡°)","( ͠° ͟ʖ ͡°)","ᕦ( ͡° ͜ʖ ͡°)ᕤ","( ͡° ͜ʖ ͡°)","( ͡~ ͜ʖ ͡°)","( ͡o ͜ʖ ͡o)","͡° ͜ʖ ͡ -","( ͡͡ ° ͜ ʖ ͡ °)","( ͡ ͡° ͡° ʖ ͡° ͡°)","(ง ͠° ͟ل͜ ͡°)ง","( ͡° ͜ʖ ͡ °)","( ͡°╭͜ʖ╮͡° )"];
const PATTERN: &'static str = "^![Ll]enny\\s*(?P<text>.*)$";
const USAGE: &'static str = "Usage: ![Ll]enny
Displays a Lenny face ( ͡° ͜ʖ ͡°)";
pub struct Lenny {}
impl super::Module for Lenny {
fn mod_message(message: &Message, message_buf: &VecDeque<Message>) -> Option<(String,String)> {
let regex: Regex = Regex::new(PATTERN).expect("Error creating regex");
//checks if it was a PRIVMSG
if let PRIVMSG(_,msg) = message.command.clone() {
//checks if it was lenny
if let Some(captures) = regex.captures(msg.as_str()) {
let lenny = LENNYS[rand::thread_rng().gen_range(0..12)].to_string();
let text = captures.get(1).unwrap().as_str();
return Some((message.response_target().unwrap_or("#lug").to_string(),format!("{} {}", lenny, text)));
}
}
None
}
fn usage(message: &Message) -> (String,String) {
//prints a usage, not sure when I'm gonna use this but let's see
(message.response_target().unwrap_or("#lug").to_string(),USAGE.to_string())
}
}