- Added english commands description - Added russian commands description - Changed override option on /quest update to reset dates - Commented out all deadline functionality
215 lines
6.4 KiB
Rust
215 lines
6.4 KiB
Rust
use poise::serenity_prelude::User;
|
|
use squad_quest::{SquadObject, account::Account, map::Map};
|
|
|
|
use crate::{Context, Error, account::{account_full_balance, account_user_id, fetch_or_init_account}, strings::StringFormatter};
|
|
|
|
async fn account_balance_string(
|
|
ctx: &Context<'_>,
|
|
account: &Account,
|
|
map: &Map,
|
|
mut formatter: StringFormatter
|
|
) -> String {
|
|
let account_id = account_user_id(&account);
|
|
|
|
let Ok(user) = account_id.to_user(ctx).await else {
|
|
return String::new();
|
|
};
|
|
|
|
let strings = &ctx.data().strings;
|
|
formatter = formatter.user(&user).balance(account, map);
|
|
|
|
formatter.fmt(&strings.scoreboard.line_format)
|
|
}
|
|
|
|
/// Reset user account, including balance, unlocked rooms and completed quests
|
|
#[poise::command(
|
|
prefix_command,
|
|
slash_command,
|
|
guild_only,
|
|
required_permissions = "ADMINISTRATOR",
|
|
name_localized("ru", "сбросить"),
|
|
description_localized("ru", "Сбросить аккаунт пользователя, вкл. баланс, открытые комнаты и пройденные квесты"),
|
|
)]
|
|
pub async fn reset(
|
|
ctx: Context<'_>,
|
|
#[description = "The user to reset"]
|
|
#[name_localized("ru", "кого")]
|
|
#[description_localized("ru", "Сбрасываемый пользователь")]
|
|
who: User,
|
|
) -> Result<(), Error> {
|
|
let accounts = ctx.data().config.load_accounts();
|
|
|
|
let acc_id = format!("{}", who.id.get());
|
|
|
|
if let None = accounts.iter().find(|a| a.id == acc_id) {
|
|
return Err(Error::AccountNotFound);
|
|
}
|
|
|
|
let mut path = ctx.data().config.full_accounts_path();
|
|
path.push(format!("{acc_id}.toml"));
|
|
Account::delete(path)?;
|
|
|
|
let strings = &ctx.data().strings;
|
|
let formatter = strings.formatter().user(&who);
|
|
|
|
let reply_string = formatter.fmt(&strings.account.reset);
|
|
ctx.reply(reply_string).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Show scoreboard
|
|
#[poise::command(
|
|
prefix_command,
|
|
slash_command,
|
|
guild_only,
|
|
name_localized("ru", "счёт"),
|
|
description_localized("ru", "Отобразить таблицу лидеров"),
|
|
)]
|
|
pub async fn scoreboard(
|
|
ctx: Context<'_>,
|
|
) -> Result<(), Error> {
|
|
let map_path = ctx.data().config.full_map_path();
|
|
let map = Map::load(map_path).expect("map.toml should exist");
|
|
|
|
let strings = &ctx.data().strings;
|
|
let mut formatter = strings.formatter();
|
|
|
|
let mut accounts = ctx.data().config.load_accounts();
|
|
accounts.sort_by(|a,b| {
|
|
let a_balance = account_full_balance(a, &map);
|
|
let b_balance = account_full_balance(b, &map);
|
|
b_balance.cmp(&a_balance)
|
|
});
|
|
|
|
let this_user = ctx.author().id;
|
|
|
|
let mut reply_string = formatter.fmt(&strings.scoreboard.header);
|
|
for account in accounts {
|
|
let user_id = account_user_id(&account);
|
|
|
|
let mut str = account_balance_string(&ctx, &account, &map, formatter.clone()).await;
|
|
if user_id == this_user {
|
|
formatter = formatter.text(&str);
|
|
str = formatter.fmt(&strings.scoreboard.you_format);
|
|
}
|
|
|
|
reply_string.push_str(&str);
|
|
}
|
|
|
|
ctx.reply(reply_string).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[poise::command(
|
|
prefix_command,
|
|
slash_command,
|
|
guild_only,
|
|
subcommands("give", "set"),
|
|
name_localized("ru", "баланс"),
|
|
)]
|
|
pub async fn balance(
|
|
_ctx: Context<'_>,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
|
|
/// Give points to another user
|
|
#[poise::command(
|
|
prefix_command,
|
|
slash_command,
|
|
guild_only,
|
|
name_localized("ru", "передать"),
|
|
description_localized("ru", "Передать очки другому пользователю"),
|
|
)]
|
|
pub async fn give(
|
|
ctx: Context<'_>,
|
|
#[description = "Recipient"]
|
|
#[name_localized("ru", "кому")]
|
|
#[description_localized("ru", "Получатель")]
|
|
who: User,
|
|
#[description = "Amount of the points to give"]
|
|
#[name_localized("ru", "количество")]
|
|
#[description_localized("ru", "Количество очков для передачи")]
|
|
amount: u32,
|
|
) -> Result<(), Error> {
|
|
if ctx.author() == &who {
|
|
return Err(Error::AccountIsSelf);
|
|
}
|
|
|
|
let config = &ctx.data().config;
|
|
let mut accounts = config.load_accounts();
|
|
|
|
let user_id = format!("{}", ctx.author().id.get());
|
|
let mut user_account = fetch_or_init_account(config, user_id);
|
|
|
|
let who_id = format!("{}", who.id.get());
|
|
let Some(other_account) = accounts.iter_mut().find(|a| a.id == who_id ) else {
|
|
return Err(Error::AccountNotFound);
|
|
};
|
|
|
|
if user_account.balance < amount {
|
|
return Err(Error::InsufficientFunds(amount));
|
|
}
|
|
|
|
user_account.balance -= amount;
|
|
other_account.balance += amount;
|
|
|
|
let accounts_path = config.full_accounts_path();
|
|
user_account.save(accounts_path.clone())?;
|
|
other_account.save(accounts_path)?;
|
|
|
|
let strings = &ctx.data().strings;
|
|
let formatter = strings.formatter()
|
|
.user(&who)
|
|
.value(amount)
|
|
.current_balance(&user_account);
|
|
|
|
let reply_string = formatter.fmt(&strings.account.give_pt);
|
|
ctx.reply(reply_string).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Set current user balance
|
|
#[poise::command(
|
|
prefix_command,
|
|
slash_command,
|
|
guild_only,
|
|
required_permissions = "ADMINISTRATOR",
|
|
name_localized("ru", "установить"),
|
|
description_localized("ru", "Устанавливает текущий баланс пользователя"),
|
|
)]
|
|
pub async fn set(
|
|
ctx: Context<'_>,
|
|
#[description = "User, whose balance will be modified"]
|
|
#[name_localized("ru", "чей")]
|
|
#[description_localized("ru", "Пользователь, чей баланс будет изменён")]
|
|
who: User,
|
|
#[description = "New balance of the user"]
|
|
#[name_localized("ru", "количество")]
|
|
#[description_localized("ru", "Новый баланс пользователя")]
|
|
amount: u32,
|
|
) -> Result<(), Error> {
|
|
let mut accounts = ctx.data().config.load_accounts();
|
|
|
|
let who_id = format!("{}", who.id.get());
|
|
let Some(account) = accounts.iter_mut().find(|a| a.id == who_id ) else {
|
|
return Err(Error::AccountNotFound);
|
|
};
|
|
|
|
account.balance = amount;
|
|
let accounts_path = ctx.data().config.full_accounts_path();
|
|
account.save(accounts_path)?;
|
|
|
|
let strings = &ctx.data().strings;
|
|
let formatter = strings.formatter()
|
|
.user(&who)
|
|
.current_balance(&account);
|
|
|
|
let reply_string = formatter.fmt(&strings.account.set_pt);
|
|
ctx.reply(reply_string).await?;
|
|
|
|
Ok(())
|
|
}
|