refactor
This commit is contained in:
parent
2626b22683
commit
a57fa13004
9 changed files with 326 additions and 178 deletions
23
src/commands/clap.rs
Normal file
23
src/commands/clap.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use serenity::framework::standard::{macros::command, Args, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::Context;
|
||||
|
||||
#[command]
|
||||
async fn clap(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let resp = match args
|
||||
.iter()
|
||||
.map(|e: Result<String, _>| e.unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice()
|
||||
{
|
||||
[] => ":clap:".to_string(),
|
||||
[_] => "You can't clap a single word."
|
||||
.split_whitespace()
|
||||
.collect::<Vec<_>>()
|
||||
.join(" :clap: "),
|
||||
args => args.join(" :clap: "),
|
||||
};
|
||||
|
||||
msg.channel_id.say(ctx, resp).await?;
|
||||
Ok(())
|
||||
}
|
72
src/commands/cube.rs
Normal file
72
src/commands/cube.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use serenity::framework::standard::{macros::command, Args, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::Context;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
#[command]
|
||||
pub(crate) async fn cube(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let resp = match args
|
||||
.iter()
|
||||
.map(|e: Result<String, _>| e.unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice()
|
||||
{
|
||||
[] => "What do you wanna cube?".to_string(),
|
||||
args => {
|
||||
let to_cube: &str = &args.join(" ");
|
||||
let to_cube = UnicodeSegmentation::graphemes(to_cube, true).collect::<Vec<_>>();
|
||||
let cube_len = to_cube.len();
|
||||
let should_reverse = to_cube.last() != to_cube.first();
|
||||
|
||||
let offset = cube_len / 2;
|
||||
let mut field =
|
||||
vec![vec![" ".to_string(); (cube_len + offset) * 2 - 1]; cube_len + offset];
|
||||
|
||||
draw_diagonal(&mut field, cube_len, offset);
|
||||
draw_box(&mut field, &to_cube, should_reverse, offset * 2, 0);
|
||||
draw_box(&mut field, &to_cube, should_reverse, 0, offset);
|
||||
|
||||
let text = field
|
||||
.iter()
|
||||
.map(|r| r.join("").trim_end().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
["```\n".to_string(), text, "```".to_string()].concat()
|
||||
}
|
||||
};
|
||||
|
||||
msg.channel_id.say(ctx, resp).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_diagonal(field: &mut Vec<Vec<String>>, cube_len: usize, offset: usize) {
|
||||
let diag_char = "/".to_string();
|
||||
for x in 0..offset {
|
||||
field[offset - x][x * 2] = diag_char.clone();
|
||||
field[cube_len - x + offset - 1][x * 2] = diag_char.clone();
|
||||
field[offset - x][(x + cube_len - 1) * 2] = diag_char.clone();
|
||||
field[cube_len - x + offset - 1][(x + cube_len - 1) * 2] = diag_char.clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_box(field: &mut Vec<Vec<String>>, chars: &[&str], should_rev: bool, x: usize, y: usize) {
|
||||
let word_len = chars.len();
|
||||
|
||||
// Magic numbers are good as long as they're 1 or 2 right?
|
||||
for i in 0..word_len {
|
||||
field[y + i][x] = chars[i].to_string();
|
||||
field[y][x + i * 2] = chars[i].to_string();
|
||||
field[y + (word_len - 1)][x + (word_len - 1 - i) * 2] = if should_rev {
|
||||
chars[i].to_string()
|
||||
} else {
|
||||
chars[word_len - i - 1].to_string()
|
||||
};
|
||||
field[y + (word_len - 1) - i][x + (word_len - 1) * 2] = if should_rev {
|
||||
chars[i].to_string()
|
||||
} else {
|
||||
chars[word_len - i - 1].to_string()
|
||||
};
|
||||
}
|
||||
}
|
17
src/commands/heck.rs
Normal file
17
src/commands/heck.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use crate::DbConnPool;
|
||||
use serenity::framework::standard::{macros::command, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::Context;
|
||||
|
||||
#[command]
|
||||
async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||
let db_pool = ctx.data.clone();
|
||||
let mut db_pool = db_pool.write().await;
|
||||
let db_pool = db_pool.get_mut::<DbConnPool>().unwrap();
|
||||
let value = db_pool.get_heck().await;
|
||||
msg.channel_id
|
||||
.say(ctx, format!("This command has been hecked {} times", value))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
10
src/commands/mod.rs
Normal file
10
src/commands/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use crate::commands::{clap::CLAP_COMMAND, cube::CUBE_COMMAND, heck::HECK_COMMAND};
|
||||
use serenity::framework::standard::macros::group;
|
||||
|
||||
mod clap;
|
||||
mod cube;
|
||||
mod heck;
|
||||
|
||||
#[group]
|
||||
#[commands(heck, clap, cube)]
|
||||
pub(crate) struct General;
|
186
src/main.rs
186
src/main.rs
|
@ -1,87 +1,17 @@
|
|||
use regex::Regex;
|
||||
use serenity::async_trait;
|
||||
use crate::commands::GENERAL_GROUP;
|
||||
use crate::passive::Handler;
|
||||
use serenity::client::Client;
|
||||
use serenity::framework::standard::{
|
||||
macros::{command, group},
|
||||
CommandResult, StandardFramework,
|
||||
};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::{Context, EventHandler, TypeMapKey};
|
||||
use serenity::framework::standard::StandardFramework;
|
||||
use serenity::prelude::TypeMapKey;
|
||||
use sqlx::sqlite::SqlitePool;
|
||||
use std::env;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
const COMMAND_PREFIX: &str = "~";
|
||||
mod commands;
|
||||
mod passive;
|
||||
|
||||
struct Handler {
|
||||
ah_regex: Regex,
|
||||
best_doctor_regex: Regex,
|
||||
fufufu_regex: Regex,
|
||||
}
|
||||
pub(crate) const COMMAND_PREFIX: &str = "~";
|
||||
|
||||
impl Default for Handler {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ah_regex: Regex::new(r"A+H{5,}").unwrap(),
|
||||
best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(),
|
||||
fufufu_regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn message(&self, ctx: Context, message: Message) {
|
||||
let content = &message.content_safe(ctx.clone()).await;
|
||||
if self.ah_regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "its ok ur gonna get a 6* someday")
|
||||
.await
|
||||
.unwrap();
|
||||
} else if self.best_doctor_regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "no, u is smol brain doctor...")
|
||||
.await
|
||||
.unwrap();
|
||||
} else if self.fufufu_regex.is_match(content) {
|
||||
message.channel_id.say(ctx, get_desu()).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DESU_STRINGS: &[&str] = &[
|
||||
"です。",
|
||||
"desu~",
|
||||
"desu.",
|
||||
r#"
|
||||
```
|
||||
ででででででででででで すす
|
||||
ででで すすすすすすすすす
|
||||
でで でで すす
|
||||
でで でで すすす
|
||||
でで す す
|
||||
でで すすす
|
||||
でで すす
|
||||
でで すす
|
||||
でで すす
|
||||
```"#,
|
||||
];
|
||||
|
||||
fn get_desu() -> &'static str {
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
|
||||
DESU_STRINGS.choose(&mut thread_rng()).unwrap()
|
||||
// // https://imgur.com/a/yOb5n
|
||||
// messageList.add(channel -> channel.sendMessage(new MessageBuilder()
|
||||
// .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build()));
|
||||
// messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg"));
|
||||
// messageList.add(channel -> channel.sendMessage("desu~"));
|
||||
}
|
||||
|
||||
struct DbConnPool {
|
||||
pub(crate) struct DbConnPool {
|
||||
pool: sqlx::pool::Pool<sqlx::sqlite::SqliteConnection>,
|
||||
}
|
||||
|
||||
|
@ -161,103 +91,3 @@ async fn init_pool(pool: &sqlx::pool::Pool<sqlx::sqlite::SqliteConnection>) {
|
|||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[group]
|
||||
#[commands(heck, clap, cube)]
|
||||
struct General;
|
||||
#[command]
|
||||
async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||
let db_pool = ctx.data.clone();
|
||||
let mut db_pool = db_pool.write().await;
|
||||
let db_pool = db_pool.get_mut::<DbConnPool>().unwrap();
|
||||
let value = db_pool.get_heck().await;
|
||||
msg.channel_id
|
||||
.say(ctx, format!("This command has been hecked {} times", value))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
async fn clap(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||
let content = msg.content_safe(ctx.cache.clone()).await;
|
||||
let tokens: Vec<_> = content.split_whitespace().collect();
|
||||
let resp = match tokens.len() {
|
||||
1 => ":clap:".to_string(),
|
||||
2 => "You can't clap a single word."
|
||||
.split_whitespace()
|
||||
.collect::<Vec<_>>()
|
||||
.join(" :clap: "),
|
||||
_ => tokens[1..].join(" :clap: "),
|
||||
};
|
||||
|
||||
msg.channel_id.say(ctx, resp).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
async fn cube(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||
let mut original_msg = msg.content_safe(ctx.cache.clone()).await;
|
||||
let tokens = original_msg.split_ascii_whitespace().collect::<Vec<_>>();
|
||||
|
||||
let resp = match tokens.len() {
|
||||
0 => unreachable!("wat"),
|
||||
1 => "What do you wanna cube?".to_string(),
|
||||
_ => {
|
||||
let to_cube: &str = &original_msg.split_off(COMMAND_PREFIX.len() + "cube".len() + 1);
|
||||
let to_cube = UnicodeSegmentation::graphemes(to_cube, true).collect::<Vec<_>>();
|
||||
let cube_len = to_cube.len();
|
||||
let should_reverse = to_cube.last() != to_cube.first();
|
||||
|
||||
let offset = cube_len / 2;
|
||||
let mut field =
|
||||
vec![vec![" ".to_string(); (cube_len + offset) * 2 - 1]; cube_len + offset];
|
||||
|
||||
draw_diagonal(&mut field, cube_len, offset);
|
||||
draw_box(&mut field, &to_cube, should_reverse, offset * 2, 0);
|
||||
draw_box(&mut field, &to_cube, should_reverse, 0, offset);
|
||||
|
||||
let text = field
|
||||
.iter()
|
||||
.map(|r| r.join("").trim_end().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
["```\n".to_string(), text, "```".to_string()].concat()
|
||||
}
|
||||
};
|
||||
|
||||
msg.channel_id.say(ctx, resp).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_diagonal(field: &mut Vec<Vec<String>>, cube_len: usize, offset: usize) {
|
||||
let diag_char = "/".to_string();
|
||||
for x in 0..offset {
|
||||
field[offset - x][x * 2] = diag_char.clone();
|
||||
field[cube_len - x + offset - 1][x * 2] = diag_char.clone();
|
||||
field[offset - x][(x + cube_len - 1) * 2] = diag_char.clone();
|
||||
field[cube_len - x + offset - 1][(x + cube_len - 1) * 2] = diag_char.clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_box(field: &mut Vec<Vec<String>>, chars: &[&str], should_rev: bool, x: usize, y: usize) {
|
||||
let word_len = chars.len();
|
||||
|
||||
// Magic numbers are good as long as they're 1 or 2 right?
|
||||
for i in 0..word_len {
|
||||
field[y + i][x] = chars[i].to_string();
|
||||
field[y][x + i * 2] = chars[i].to_string();
|
||||
field[y + (word_len - 1)][x + (word_len - 1 - i) * 2] = if should_rev {
|
||||
chars[i].to_string()
|
||||
} else {
|
||||
chars[word_len - i - 1].to_string()
|
||||
};
|
||||
field[y + (word_len - 1) - i][x + (word_len - 1) * 2] = if should_rev {
|
||||
chars[i].to_string()
|
||||
} else {
|
||||
chars[word_len - i - 1].to_string()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
30
src/passive/best_doctor.rs
Normal file
30
src/passive/best_doctor.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use regex::Regex;
|
||||
use serenity::async_trait;
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::{Context, EventHandler};
|
||||
|
||||
pub(crate) struct BestDoctorResponder {
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl Default for BestDoctorResponder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for BestDoctorResponder {
|
||||
async fn message(&self, ctx: Context, message: Message) {
|
||||
let content = &message.content_safe(ctx.clone()).await;
|
||||
if self.regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "its ok ur gonna get a 6* someday")
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
60
src/passive/fufufu.rs
Normal file
60
src/passive/fufufu.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use regex::Regex;
|
||||
use serenity::async_trait;
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::{Context, EventHandler};
|
||||
|
||||
pub(crate) struct BestDoctorResponder {
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl Default for BestDoctorResponder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for BestDoctorResponder {
|
||||
async fn message(&self, ctx: Context, message: Message) {
|
||||
let content = &message.content_safe(ctx.clone()).await;
|
||||
if self.regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, get_desu())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DESU_STRINGS: &[&str] = &[
|
||||
"です。",
|
||||
"desu~",
|
||||
"desu.",
|
||||
r#"
|
||||
```
|
||||
ででででででででででで すす
|
||||
ででで すすすすすすすすす
|
||||
でで でで すす
|
||||
でで でで すすす
|
||||
でで す す
|
||||
でで すすす
|
||||
でで すす
|
||||
でで すす
|
||||
でで すす
|
||||
```"#,
|
||||
];
|
||||
|
||||
fn get_desu() -> &'static str {
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
|
||||
DESU_STRINGS.choose(&mut thread_rng()).unwrap()
|
||||
// // https://imgur.com/a/yOb5n
|
||||
// messageList.add(channel -> channel.sendMessage(new MessageBuilder()
|
||||
// .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build()));
|
||||
// messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg"));
|
||||
// messageList.add(channel -> channel.sendMessage("desu~"));
|
||||
}
|
76
src/passive/mod.rs
Normal file
76
src/passive/mod.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use regex::Regex;
|
||||
use serenity::async_trait;
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::{Context, EventHandler};
|
||||
|
||||
mod best_doctor;
|
||||
mod fufufu;
|
||||
mod yell_resp;
|
||||
|
||||
pub(crate) struct Handler {
|
||||
ah_regex: Regex,
|
||||
best_doctor_regex: Regex,
|
||||
fufufu_regex: Regex,
|
||||
}
|
||||
|
||||
impl Default for Handler {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ah_regex: Regex::new(r"A+H{5,}").unwrap(),
|
||||
best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(),
|
||||
fufufu_regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn message(&self, ctx: Context, message: Message) {
|
||||
let content = &message.content_safe(ctx.clone()).await;
|
||||
if self.ah_regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "its ok ur gonna get a 6* someday")
|
||||
.await
|
||||
.unwrap();
|
||||
} else if self.best_doctor_regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "no, u is smol brain doctor...")
|
||||
.await
|
||||
.unwrap();
|
||||
} else if self.fufufu_regex.is_match(content) {
|
||||
message.channel_id.say(ctx, get_desu()).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DESU_STRINGS: &[&str] = &[
|
||||
"です。",
|
||||
"desu~",
|
||||
"desu.",
|
||||
r#"
|
||||
```
|
||||
ででででででででででで すす
|
||||
ででで すすすすすすすすす
|
||||
でで でで すす
|
||||
でで でで すすす
|
||||
でで す す
|
||||
でで すすす
|
||||
でで すす
|
||||
でで すす
|
||||
でで すす
|
||||
```"#,
|
||||
];
|
||||
|
||||
fn get_desu() -> &'static str {
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
|
||||
DESU_STRINGS.choose(&mut thread_rng()).unwrap()
|
||||
// // https://imgur.com/a/yOb5n
|
||||
// messageList.add(channel -> channel.sendMessage(new MessageBuilder()
|
||||
// .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build()));
|
||||
// messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg"));
|
||||
// messageList.add(channel -> channel.sendMessage("desu~"));
|
||||
}
|
30
src/passive/yell_resp.rs
Normal file
30
src/passive/yell_resp.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use regex::Regex;
|
||||
use serenity::async_trait;
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::{Context, EventHandler};
|
||||
|
||||
pub(crate) struct YellResponder {
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl Default for YellResponder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
regex: Regex::new(r"A+H{5,}").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for YellResponder {
|
||||
async fn message(&self, ctx: Context, message: Message) {
|
||||
let content = &message.content_safe(ctx.clone()).await;
|
||||
if self.regex.is_match(content) {
|
||||
message
|
||||
.channel_id
|
||||
.say(ctx, "no, u is smol brain doctor..")
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue