272 lines
7.7 KiB
Rust
272 lines
7.7 KiB
Rust
use crate::config::BotConfig;
|
|
use crate::inventory::ItemType;
|
|
use crate::models::api_key::Apikey;
|
|
use crate::models::lil_fren::{
|
|
draw_dancing, draw_frankenstein, draw_gone, draw_magic, draw_mining, draw_resonance_cascade,
|
|
draw_sick, draw_sleep, draw_standing, draw_tax_fraud, AliveState, LilFren,
|
|
};
|
|
use crate::models::task::Task;
|
|
use crate::user::User;
|
|
use crate::{command, group, GlobalData};
|
|
use json::JsonValue;
|
|
use serenity::all::{CreateAttachment, CreateMessage, FormattedTimestamp, FormattedTimestampStyle};
|
|
use serenity::client::Context;
|
|
use serenity::framework::standard::{Args, CommandResult};
|
|
use serenity::model::channel::Message;
|
|
use serenity::model::misc::EmojiIdentifier;
|
|
use serenity::model::prelude::UserId;
|
|
use serenity::model::Timestamp;
|
|
use serenity::utils::MessageBuilder;
|
|
use std::borrow::Cow;
|
|
|
|
#[group]
|
|
#[commands(
|
|
reload,
|
|
dump_db,
|
|
load_db,
|
|
add_key,
|
|
debug_buddy,
|
|
draw_buddy_states,
|
|
op_give,
|
|
list_tasks
|
|
)]
|
|
pub struct ADMIN;
|
|
|
|
pub fn is_admin(user_id: &UserId, cfg: &BotConfig) -> bool {
|
|
cfg.admins.contains(user_id)
|
|
}
|
|
|
|
#[command]
|
|
async fn reload(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
global_data.reload().await?;
|
|
msg.reply(&ctx.http, "Reload done ;)").await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
async fn dump_db(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
let db_dump = global_data.db.dump_db()?;
|
|
|
|
let output = db_dump.pretty(4);
|
|
|
|
msg.author
|
|
.id
|
|
.create_dm_channel(&ctx.http)
|
|
.await?
|
|
.send_message(
|
|
&ctx.http,
|
|
CreateMessage::new()
|
|
.content("The current DB state")
|
|
.add_file(CreateAttachment::bytes(
|
|
Cow::from(output.as_bytes()),
|
|
"db.json".to_string(),
|
|
)),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
async fn load_db(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
if let Some(attachment) = msg.attachments.first() {
|
|
let db_bytes = attachment.download().await?;
|
|
let db_string = String::from_utf8(db_bytes)?;
|
|
|
|
let json_value: JsonValue = match json::parse(&db_string) {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
msg.reply(&ctx.http, format!("Error parsing json: {}", e))
|
|
.await?;
|
|
return Ok(());
|
|
}
|
|
};
|
|
|
|
match global_data.db.import_db(json_value) {
|
|
Ok(_) => {
|
|
msg.reply(&ctx.http, "Database imported successfully")
|
|
.await?
|
|
}
|
|
Err(err) => {
|
|
msg.reply(&ctx.http, format!("Error importing db: {}", err))
|
|
.await?;
|
|
return Ok(());
|
|
}
|
|
};
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
async fn add_key(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
let (api_key, key) = if args.len() == 1 {
|
|
let user_id = args.parse::<UserId>()?;
|
|
let user = user_id.to_user(&ctx.http).await?;
|
|
Apikey::new(&format!("{}'s Key", user.name), Some(user_id))
|
|
} else {
|
|
Apikey::new(&format!("{}'s Key", msg.author.name), Some(msg.author.id))
|
|
};
|
|
|
|
global_data.db.insert::<Apikey>(api_key.clone())?;
|
|
|
|
let dm = msg.author.create_dm_channel(&ctx.http).await?;
|
|
|
|
dm.say(
|
|
&ctx.http,
|
|
format!("Key '{}' added. Api Key: {}", api_key.name, key),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Check little buddy stats")]
|
|
async fn debug_buddy(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
|
|
|
if let Some(lil_fren) = lil_fren {
|
|
if lil_fren.is_alive() == AliveState::Alive {
|
|
msg.reply(
|
|
&ctx.http,
|
|
format!(
|
|
"Hunger: {} Thirst: {} Entertainment: {} Smarts: {} Metabolism: {} State: {:?}",
|
|
lil_fren.hunger,
|
|
lil_fren.thirst,
|
|
lil_fren.entertainment,
|
|
lil_fren.smarts,
|
|
lil_fren.metabolism,
|
|
lil_fren.state
|
|
),
|
|
)
|
|
.await?;
|
|
} else {
|
|
msg.reply(&ctx.http, "Lil buddy is dead!").await?;
|
|
}
|
|
} else {
|
|
msg.reply(&ctx.http, "Sorry no little buddy found!").await?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Check little buddy stats")]
|
|
async fn draw_buddy_states(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let emoji = args.parse::<EmojiIdentifier>()?;
|
|
|
|
let emoji = msg.guild_id.unwrap().emoji(&ctx.http, emoji.id).await?;
|
|
|
|
msg.reply(&ctx.http, draw_standing(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_dancing(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_frankenstein(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_sick(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_magic(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_resonance_cascade(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_tax_fraud(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_sleep(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_mining(&emoji)).await?;
|
|
msg.reply(&ctx.http, draw_gone()).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Hey can I get op? I'm from planet minecraft")]
|
|
async fn op_give(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let mut data = ctx.data.write().await;
|
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
|
|
|
if args.is_empty() {
|
|
msg.reply(&ctx.http, "You need to select an item to give")
|
|
.await?;
|
|
return Ok(());
|
|
}
|
|
|
|
if !is_admin(&msg.author.id, &global_data.cfg) {
|
|
return Ok(());
|
|
}
|
|
|
|
let msg_content = args.rest().to_lowercase();
|
|
let item = match msg_content.parse::<ItemType>() {
|
|
Ok(i) => i,
|
|
Err(_) => {
|
|
msg.reply(&ctx.http, "I don't know what the heck that is tbh.")
|
|
.await?;
|
|
return Ok(());
|
|
}
|
|
};
|
|
|
|
User::give_item(&global_data.db, msg.author.id, item, 1, None)?;
|
|
|
|
msg.reply(
|
|
&ctx,
|
|
format!("[Console] Op has given {} 1 {}", msg.author.name, item),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("List scheduled tasks")]
|
|
async fn list_tasks(ctx: &Context, msg: &Message) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
|
|
let tasks: Vec<Task> = global_data.db.filter(|_, _task: &Task| true)?.collect();
|
|
|
|
let mut resp = MessageBuilder::new();
|
|
|
|
for task in &tasks {
|
|
let timestamp = Timestamp::from(task.time);
|
|
let time_tag =
|
|
FormattedTimestamp::new(timestamp, Some(FormattedTimestampStyle::ShortDateTime));
|
|
resp.push_line(format!(
|
|
"* **Task**: {:?} **Next Execution**: {}",
|
|
task.task_type, time_tag
|
|
));
|
|
}
|
|
|
|
msg.reply(&ctx.http, resp.build()).await?;
|
|
|
|
Ok(())
|
|
}
|