clap and cube commands
This commit is contained in:
parent
fec0b49e25
commit
2626b22683
3 changed files with 136 additions and 3 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -305,10 +305,12 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"serenity",
|
"serenity",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1573,6 +1575,12 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
|
@ -14,3 +14,5 @@ sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
tokio = { version = "0.2", features = ["full"] }
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
|
rand = "0.7"
|
||||||
|
unicode-segmentation = "1.6.0"
|
127
src/main.rs
127
src/main.rs
|
@ -9,10 +9,14 @@ use serenity::model::channel::Message;
|
||||||
use serenity::prelude::{Context, EventHandler, TypeMapKey};
|
use serenity::prelude::{Context, EventHandler, TypeMapKey};
|
||||||
use sqlx::sqlite::SqlitePool;
|
use sqlx::sqlite::SqlitePool;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
|
const COMMAND_PREFIX: &str = "~";
|
||||||
|
|
||||||
struct Handler {
|
struct Handler {
|
||||||
ah_regex: Regex,
|
ah_regex: Regex,
|
||||||
best_doctor_regex: Regex,
|
best_doctor_regex: Regex,
|
||||||
|
fufufu_regex: Regex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Handler {
|
impl Default for Handler {
|
||||||
|
@ -20,6 +24,7 @@ impl Default for Handler {
|
||||||
Self {
|
Self {
|
||||||
ah_regex: Regex::new(r"A+H{5,}").unwrap(),
|
ah_regex: Regex::new(r"A+H{5,}").unwrap(),
|
||||||
best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(),
|
best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(),
|
||||||
|
fufufu_regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,13 +45,46 @@ impl EventHandler for Handler {
|
||||||
.say(ctx, "no, u is smol brain doctor...")
|
.say(ctx, "no, u is smol brain doctor...")
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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 {
|
struct DbConnPool {
|
||||||
pool: sqlx::pool::Pool<sqlx::sqlite::SqliteConnection>,
|
pool: sqlx::pool::Pool<sqlx::sqlite::SqliteConnection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DbConnPool {
|
impl DbConnPool {
|
||||||
async fn get_heck(&self) -> i32 {
|
async fn get_heck(&self) -> i32 {
|
||||||
sqlx::query!("UPDATE Heck SET count = count + 1")
|
sqlx::query!("UPDATE Heck SET count = count + 1")
|
||||||
|
@ -61,6 +99,7 @@ impl DbConnPool {
|
||||||
.count
|
.count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeMapKey for DbConnPool {
|
impl TypeMapKey for DbConnPool {
|
||||||
type Value = Self;
|
type Value = Self;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +109,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
let framework = StandardFramework::new()
|
let framework = StandardFramework::new()
|
||||||
.configure(|c| c.prefix("~"))
|
.configure(|c| c.prefix(COMMAND_PREFIX))
|
||||||
.group(&GENERAL_GROUP);
|
.group(&GENERAL_GROUP);
|
||||||
|
|
||||||
// Login with a bot token from the environment
|
// Login with a bot token from the environment
|
||||||
|
@ -124,7 +163,7 @@ async fn init_pool(pool: &sqlx::pool::Pool<sqlx::sqlite::SqliteConnection>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(heck)]
|
#[commands(heck, clap, cube)]
|
||||||
struct General;
|
struct General;
|
||||||
#[command]
|
#[command]
|
||||||
async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult {
|
async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||||
|
@ -138,3 +177,87 @@ async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult {
|
||||||
|
|
||||||
Ok(())
|
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()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue