initial commit, completed lenny as poc
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
1236
Cargo.lock
generated
Normal file
1236
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "bobbit"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
irc = {version = "0.15.0"}
|
||||||
|
chrono = {version = "*"}
|
||||||
|
futures = {version = "*"}
|
||||||
|
tokio = {version = "*", features = ["full"]}
|
||||||
|
regex = "1"
|
||||||
|
rand = "0.8.5"
|
||||||
43
src/main.rs
Normal file
43
src/main.rs
Normal 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
31
src/module.rs
Normal 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
39
src/module/lenny.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user