discord-kurante/src/commands/op/mod.rs

228 lines
6.3 KiB
Rust

use crate::{
util::{
debug_say,
operators::{get_china_ops, get_global_ops, Operator},
},
DbConnPool,
};
use pity::{pity, PITY_COMMAND};
use queries::OpCommandQueries;
use serenity::framework::standard::{macros::command, Args, CommandResult};
use serenity::model::{channel::Message, id::UserId};
use serenity::prelude::Context;
use std::{collections::HashSet, str::FromStr};
mod pity;
mod queries;
#[command]
#[sub_commands(list, add, remove, missing, roll, pity)]
async fn op(_: &Context, _: &Message) -> CommandResult {
Ok(())
}
#[command]
async fn list(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
let db_pool = ctx.data.clone();
let db_pool = db_pool.read().await;
let db_pool = db_pool
.get::<DbConnPool>()
.expect("No db pool in context?!");
let user_id = match args.current().map(|id| UserId::from_str(id.trim())) {
Some(Ok(user_id)) => user_id,
_ => msg.author.id,
}
.as_u64()
.to_string();
debug_say(
msg,
ctx,
format!(
"{}'s 6\u{2605} Operators:\n{}",
msg.author,
db_pool
.get_operators(user_id)
.await?
.iter()
.map(|(op, pot)| format!("{:?} (Pot {})", op, pot))
.collect::<Vec<_>>()
.join("\n")
),
)
.await?;
Ok(())
}
#[command]
async fn add(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let db_pool = ctx.data.clone();
let db_pool = db_pool.read().await;
let db_pool = db_pool
.get::<DbConnPool>()
.expect("No db pool in context?!");
let mut failed_parses = false;
let mut num_added: usize = 0;
for arg in args.iter::<Operator>() {
match arg {
Ok(op) => {
db_pool
.add_operator(msg.author.id.as_u64().to_string(), op)
.await?;
num_added += 1;
}
Err(_) => {
failed_parses = true;
}
};
}
if failed_parses {
debug_say(
msg,
ctx,
"Unable to add some operators. Check your spelling and try again.",
)
.await?;
}
match num_added {
0 => debug_say(msg, ctx, "Didn't add any operators...").await?,
1 => debug_say(msg, ctx, "Added an operator!").await?,
n => debug_say(msg, ctx, format!("Added {} operators!", n)).await?,
};
Ok(())
}
#[command]
async fn remove(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let db_pool = ctx.data.clone();
let db_pool = db_pool.read().await;
let db_pool = db_pool
.get::<DbConnPool>()
.expect("No db pool in context?!");
let mut failed_parses = false;
let mut num_added: usize = 0;
for arg in args.iter::<Operator>() {
match arg {
Ok(op) => {
db_pool
.remove_operator(msg.author.id.as_u64().to_string(), op)
.await?;
num_added += 1;
}
Err(_) => {
failed_parses = true;
}
};
}
if failed_parses {
debug_say(
msg,
ctx,
"Unable to remove some operators. Check your spelling and try again.",
)
.await?;
}
match num_added {
0 => debug_say(msg, ctx, "Didn't remove any operators...").await?,
1 => debug_say(msg, ctx, "Removed an operator!").await?,
n => debug_say(msg, ctx, format!("Removed {} operators!", n)).await?,
};
Ok(())
}
#[command]
async fn missing(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let db_pool = ctx.data.clone();
let db_pool = db_pool.read().await;
let db_pool = db_pool
.get::<DbConnPool>()
.expect("No db pool in context?!");
let user_id = match args.current().map(|id| UserId::from_str(id.trim())) {
Some(Ok(user_id)) => user_id,
_ => msg.author.id,
}
.as_u64()
.to_string();
let operators = db_pool
.get_operators(user_id)
.await?
.iter()
.map(|(op, _)| *op)
.collect::<HashSet<_>>();
let compare_ops = match args.single_quoted::<String>() {
Ok(arg) if arg == "china" || arg == "cn" => get_china_ops(),
_ => get_global_ops(),
};
let operators = operators
.symmetric_difference(&compare_ops)
.collect::<Vec<_>>();
let resp = if operators.len() > 5 {
format!(
"Missing {} and {} more...",
operators
.iter()
.take(5)
.map(|op| format!("{:?}", op))
.collect::<Vec<_>>()
.join(", "),
operators.len() - 5,
)
} else {
format!(
"Missing {}",
operators
.iter()
.map(|op| format!("{:?}", op))
.collect::<Vec<_>>()
.join(", ")
)
};
debug_say(msg, ctx, resp).await?;
Ok(())
}
#[command]
async fn roll(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let db_pool = ctx.data.clone();
let db_pool = db_pool.read().await;
let db_pool = db_pool
.get::<DbConnPool>()
.expect("No db pool in context?!");
if args.current().is_none() {
args = Args::new("1", &[]);
}
while args.current().is_some() {
match args.quoted().current() {
Some(amt) if amt.parse::<u64>().is_ok() => {
db_pool
.add_roll_count(msg.author.id.as_u64().to_string(), amt.parse().unwrap())
.await?;
}
Some(operator) if Operator::from_str(operator).is_ok() => {
let new_op = Operator::from_str(operator).unwrap();
db_pool
.add_operator(msg.author.id.as_u64().to_string(), new_op)
.await?;
debug_say(msg, ctx, format!("Congratulations on {:?}!", new_op)).await?;
db_pool
.reset_roll_count(msg.author.id.as_u64().to_string())
.await?;
}
_ => (),
}
args.advance();
}
pity(ctx, msg, args).await?;
Ok(())
}