feat: Added /quest delete command
- Also fixed formatting and sorting in /scoreboard
This commit is contained in:
parent
213ecca8b9
commit
38e3f149b1
2 changed files with 68 additions and 26 deletions
|
|
@ -6,7 +6,7 @@ use crate::{Context, Error};
|
||||||
fn account_balance_string(account: &Account, map: &Map) -> String {
|
fn account_balance_string(account: &Account, map: &Map) -> String {
|
||||||
let rooms_value = account_rooms_value(account, map);
|
let rooms_value = account_rooms_value(account, map);
|
||||||
let full_balance = account_full_balance(account, map);
|
let full_balance = account_full_balance(account, map);
|
||||||
format!("{account}: **{full_balance}** points (**{balance}** on balance \
|
format!("\n{account}: **{full_balance}** points (**{balance}** on balance \
|
||||||
+ **{rooms_value}** unlocked rooms networth)",
|
+ **{rooms_value}** unlocked rooms networth)",
|
||||||
account = account_user_id(&account).mention(),
|
account = account_user_id(&account).mention(),
|
||||||
balance = account.balance,
|
balance = account.balance,
|
||||||
|
|
@ -48,12 +48,12 @@ pub async fn scoreboard(
|
||||||
accounts.sort_by(|a,b| {
|
accounts.sort_by(|a,b| {
|
||||||
let a_balance = account_full_balance(a, &map);
|
let a_balance = account_full_balance(a, &map);
|
||||||
let b_balance = account_full_balance(b, &map);
|
let b_balance = account_full_balance(b, &map);
|
||||||
a_balance.cmp(&b_balance)
|
b_balance.cmp(&a_balance)
|
||||||
});
|
});
|
||||||
|
|
||||||
let this_user = ctx.author().id;
|
let this_user = ctx.author().id;
|
||||||
|
|
||||||
let mut reply_string = String::new();
|
let mut reply_string = "Current scoreboard:".to_string();
|
||||||
for account in accounts {
|
for account in accounts {
|
||||||
let user_id = account_user_id(&account);
|
let user_id = account_user_id(&account);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,29 @@
|
||||||
use std::{future, path::Path, str::FromStr};
|
use std::{future, path::Path, str::FromStr};
|
||||||
|
|
||||||
use poise::serenity_prelude::{CreateMessage, EditMessage, Mentionable, futures::StreamExt};
|
use poise::serenity_prelude::{CreateMessage, EditMessage, Message, futures::StreamExt};
|
||||||
use squad_quest::{SquadObject, quest::{Quest, QuestDifficulty}};
|
use squad_quest::{SquadObject, quest::{Quest, QuestDifficulty}};
|
||||||
use toml::value::Date;
|
use toml::value::Date;
|
||||||
use crate::{Context, Error, commands::ERROR_MSG};
|
use crate::{Context, Error, commands::ERROR_MSG};
|
||||||
|
|
||||||
|
async fn find_quest_message(ctx: Context<'_>, id: u16) -> Option<Message>{
|
||||||
|
let _ = ctx.defer().await;
|
||||||
|
let channel = {
|
||||||
|
let dc = ctx.data().discord.clone();
|
||||||
|
let guard = dc.lock().expect("shouldn't be locked");
|
||||||
|
guard.quests_channel
|
||||||
|
};
|
||||||
|
let messages = channel.messages_iter(ctx)
|
||||||
|
.filter_map(|m| async move { if m.is_ok() { Some(m.unwrap()) } else {
|
||||||
|
eprintln!("{}", m.unwrap_err());
|
||||||
|
None
|
||||||
|
} })
|
||||||
|
.filter(|m| {
|
||||||
|
future::ready(m.content.contains(&format!("#{id}")))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>().await;
|
||||||
|
messages.first().cloned()
|
||||||
|
}
|
||||||
|
|
||||||
fn make_quest_message_content(quest: &Quest) -> String {
|
fn make_quest_message_content(quest: &Quest) -> String {
|
||||||
format!("### `#{id}` {name} (+{reward})\n\
|
format!("### `#{id}` {name} (+{reward})\n\
|
||||||
Difficulty: *{difficulty:?}*\n\
|
Difficulty: *{difficulty:?}*\n\
|
||||||
|
|
@ -20,7 +39,7 @@ fn make_quest_message_content(quest: &Quest) -> String {
|
||||||
#[poise::command(
|
#[poise::command(
|
||||||
prefix_command,
|
prefix_command,
|
||||||
slash_command,
|
slash_command,
|
||||||
subcommands("list", "create", "update", "publish"),
|
subcommands("list", "create", "update", "publish", "delete"),
|
||||||
)]
|
)]
|
||||||
pub async fn quest(
|
pub async fn quest(
|
||||||
_ctx: Context<'_>,
|
_ctx: Context<'_>,
|
||||||
|
|
@ -229,33 +248,16 @@ pub async fn update(
|
||||||
let content = make_quest_message_content(&new_quest);
|
let content = make_quest_message_content(&new_quest);
|
||||||
let builder = EditMessage::new().content(content);
|
let builder = EditMessage::new().content(content);
|
||||||
|
|
||||||
let channel = {
|
let message = find_quest_message(ctx, id);
|
||||||
let dc = ctx.data().discord.clone();
|
if let Some(mut message) = message.await {
|
||||||
let guard = dc.lock().expect("shouldn't be locked");
|
|
||||||
guard.quests_channel
|
|
||||||
};
|
|
||||||
let message = {
|
|
||||||
let messages = channel.messages_iter(ctx)
|
|
||||||
.filter_map(|m| async move { if m.is_ok() { Some(m.unwrap()) } else {
|
|
||||||
eprintln!("{}", m.unwrap_err());
|
|
||||||
None
|
|
||||||
} })
|
|
||||||
.filter(|m| {
|
|
||||||
future::ready(m.content.contains(&format!("#{id}")))
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>().await;
|
|
||||||
messages.first().cloned()
|
|
||||||
};
|
|
||||||
if let Some(mut message) = message {
|
|
||||||
message.edit(ctx, builder).await?;
|
message.edit(ctx, builder).await?;
|
||||||
} else {
|
} else {
|
||||||
let reply_string = format!("Quest #{id} is public, but its message was not found in the {channel}",
|
let reply_string = format!("Quest #{id} is public, but its message was not found in the quest channel",
|
||||||
channel = channel.mention()
|
|
||||||
);
|
);
|
||||||
ctx.reply(reply_string).await?;
|
ctx.reply(reply_string).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = conf.full_quests_path();
|
let path = conf.full_quests_path();
|
||||||
let reply_string = match new_quest.save(path) {
|
let reply_string = match new_quest.save(path) {
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
|
@ -336,3 +338,43 @@ pub async fn publish(
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "ADMINISTRATOR",
|
||||||
|
guild_only,
|
||||||
|
)]
|
||||||
|
pub async fn delete(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
id: u16,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if let Some(msg) = find_quest_message(ctx, id).await {
|
||||||
|
msg.delete(ctx).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path = ctx.data().config.full_quests_path();
|
||||||
|
path.push(format!("{id}.toml"));
|
||||||
|
if let Err(error) = Quest::delete(path) {
|
||||||
|
eprintln!("{error}");
|
||||||
|
let reply_string = ERROR_MSG.to_string();
|
||||||
|
ctx.reply(reply_string).await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut accounts = ctx.data().config.load_accounts();
|
||||||
|
let accounts_path = ctx.data().config.full_accounts_path();
|
||||||
|
|
||||||
|
for account in accounts.iter_mut().filter(|a| a.quests_completed.contains(&id)) {
|
||||||
|
let index = account.quests_completed.iter().position(|qid| *qid == id).expect("We just filtered it");
|
||||||
|
account.quests_completed.remove(index);
|
||||||
|
if let Err(error) = account.save(accounts_path.clone()) {
|
||||||
|
eprintln!("{error}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let reply_string = format!("Successfully deleted quest #{id}");
|
||||||
|
ctx.reply(reply_string).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue