1.0 bby
This commit is contained in:
parent
1d5b44128b
commit
c5cada372e
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1080,7 +1080,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fren"
|
name = "fren"
|
||||||
version = "0.8.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum 0.8.1",
|
"axum 0.8.1",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fren"
|
name = "fren"
|
||||||
version = "0.8.0"
|
version = "1.0.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,7 @@ impl BotState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct GlobalData {
|
pub struct GlobalData {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub args: Args,
|
pub args: Args,
|
||||||
pub cfg: BotConfig,
|
pub cfg: BotConfig,
|
||||||
pub bot_state: Mutex<BotState>,
|
pub bot_state: Mutex<BotState>,
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use crate::config::BotConfig;
|
|
||||||
use crate::discord::Context;
|
use crate::discord::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::inventory::ItemType;
|
use crate::inventory::ItemType;
|
||||||
@ -21,6 +20,7 @@ pub async fn is_admin(ctx: Context<'_>) -> Result<bool, Error> {
|
|||||||
Ok(ctx.data().cfg.admins.contains(&ctx.author().id))
|
Ok(ctx.data().cfg.admins.contains(&ctx.author().id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Dumps the bot's internal database as JSON
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn dump_db(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn dump_db(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let db_dump = ctx.data().db.dump_db()?;
|
let db_dump = ctx.data().db.dump_db()?;
|
||||||
@ -45,6 +45,7 @@ pub async fn dump_db(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the bot's database state from the attached file
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn load_db(
|
pub async fn load_db(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -73,6 +74,7 @@ pub async fn load_db(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a new token for the bot's API
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn add_key(
|
pub async fn add_key(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -102,6 +104,7 @@ pub async fn add_key(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get Lil Buddy's Stats
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn debug_buddy(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn debug_buddy(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
||||||
@ -128,6 +131,7 @@ pub async fn debug_buddy(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Draw all the Lil Buddy states for debugging
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn draw_buddy_states(
|
pub async fn draw_buddy_states(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -149,6 +153,7 @@ pub async fn draw_buddy_states(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// I'm from planet Minectaft, plz give op
|
||||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||||
pub async fn op_give(
|
pub async fn op_give(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -169,6 +174,7 @@ pub async fn op_give(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List the tasks the bot is preforming in the background
|
||||||
#[poise::command(prefix_command, category = "Admin")]
|
#[poise::command(prefix_command, category = "Admin")]
|
||||||
pub async fn list_tasks(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn list_tasks(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let tasks: Vec<Task> = ctx.data().db.filter(|_, _task: &Task| true)?.collect();
|
let tasks: Vec<Task> = ctx.data().db.filter(|_, _task: &Task| true)?.collect();
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::discord::Context;
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use poise::serenity_prelude::{Attachment, MessageBuilder};
|
use poise::serenity_prelude::{Attachment, MessageBuilder};
|
||||||
|
|
||||||
|
/// Add an image to a new or existing album
|
||||||
#[poise::command(prefix_command, category = "Albums")]
|
#[poise::command(prefix_command, category = "Albums")]
|
||||||
pub async fn add_image(
|
pub async fn add_image(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -28,6 +29,7 @@ pub async fn add_image(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List all albumbs
|
||||||
#[poise::command(prefix_command, category = "Albums")]
|
#[poise::command(prefix_command, category = "Albums")]
|
||||||
pub async fn list_albums(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn list_albums(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let albums = ctx
|
let albums = ctx
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use poise::serenity_prelude::model::id::UserId;
|
|||||||
use poise::serenity_prelude::utils::MessageBuilder;
|
use poise::serenity_prelude::utils::MessageBuilder;
|
||||||
use rand::{rng, Rng};
|
use rand::{rng, Rng};
|
||||||
|
|
||||||
|
/// Add your birthday to the bot, it can probably be trusted with this info
|
||||||
#[poise::command(prefix_command, category = "Birthdays")]
|
#[poise::command(prefix_command, category = "Birthdays")]
|
||||||
pub async fn add_birthday(
|
pub async fn add_birthday(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -43,6 +44,7 @@ pub async fn add_birthday(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List birthdays added to the bot
|
||||||
#[poise::command(prefix_command, category = "Birthdays")]
|
#[poise::command(prefix_command, category = "Birthdays")]
|
||||||
pub async fn list_birthdays(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn list_birthdays(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let birthdays: Vec<BirthdayEntry> =
|
let birthdays: Vec<BirthdayEntry> =
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
use crate::config::GlobalData;
|
|
||||||
use crate::discord::Context;
|
use crate::discord::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use std::net::ToSocketAddrs;
|
|
||||||
|
|
||||||
#[poise::command(prefix_command)]
|
/// Are you sure?
|
||||||
|
#[poise::command(prefix_command, category = "Celery Man")]
|
||||||
pub async fn nudetayne(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn nudetayne(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
if ctx.invoked_command_name() == "nudetayne".to_string() {
|
if ctx.invoked_command_name() == "nudetayne" {
|
||||||
ctx.reply("Not computing, please repeat.").await?;
|
ctx.reply("Not computing, please repeat.").await?;
|
||||||
} else if ctx.invoked_command_name() == "NUDETAYNE".to_string() {
|
} else if ctx.invoked_command_name() == "NUDETAYNE" {
|
||||||
ctx.reply("This is not suitable for work are you sure?")
|
ctx.reply("This is not suitable for work are you sure?")
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -19,14 +18,16 @@ pub async fn nudetayne(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[poise::command(prefix_command)]
|
/// Tayne
|
||||||
|
#[poise::command(prefix_command, category = "Celery Man")]
|
||||||
pub async fn tayne(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn tayne(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
ctx.reply("https://media.tenor.com/115eUl2XUaAAAAAM/flarhgunnstow-paul-rudd.gif")
|
ctx.reply("https://media.tenor.com/115eUl2XUaAAAAAM/flarhgunnstow-paul-rudd.gif")
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[poise::command(prefix_command)]
|
/// THE Celeryman
|
||||||
|
#[poise::command(prefix_command, category = "Celery Man")]
|
||||||
pub async fn celeryman(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn celeryman(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
ctx.reply("https://media.tenor.com/1iOUXZFLpBgAAAAM/dance-dancing.gif")
|
ctx.reply("https://media.tenor.com/1iOUXZFLpBgAAAAM/dance-dancing.gif")
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::error::Error;
|
|||||||
use poise::serenity_prelude::builder::EditRole;
|
use poise::serenity_prelude::builder::EditRole;
|
||||||
use poise::serenity_prelude::model::Colour;
|
use poise::serenity_prelude::model::Colour;
|
||||||
|
|
||||||
|
/// Set your discord name's color
|
||||||
#[poise::command(prefix_command, guild_only, category = "color")]
|
#[poise::command(prefix_command, guild_only, category = "color")]
|
||||||
pub async fn set_color(
|
pub async fn set_color(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -45,7 +46,7 @@ pub async fn set_color(
|
|||||||
let guild_id = ctx.guild_id().unwrap();
|
let guild_id = ctx.guild_id().unwrap();
|
||||||
let member = ctx.author_member().await.unwrap();
|
let member = ctx.author_member().await.unwrap();
|
||||||
|
|
||||||
let roles = member.roles(&ctx.cache()).unwrap();
|
let roles = member.roles(ctx.cache()).unwrap();
|
||||||
|
|
||||||
let color_role = roles.iter().find(|role| role.name.contains("COwOlor"));
|
let color_role = roles.iter().find(|role| role.name.contains("COwOlor"));
|
||||||
|
|
||||||
@ -77,11 +78,12 @@ pub async fn set_color(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove your color (good for you!)
|
||||||
#[poise::command(prefix_command, guild_only, category = "Color")]
|
#[poise::command(prefix_command, guild_only, category = "Color")]
|
||||||
pub async fn remove_color(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn remove_color(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let guild_id = ctx.guild_id().unwrap();
|
let guild_id = ctx.guild_id().unwrap();
|
||||||
let member = ctx.author_member().await.unwrap();
|
let member = ctx.author_member().await.unwrap();
|
||||||
let roles = member.roles(&ctx.cache()).unwrap();
|
let roles = member.roles(ctx.cache()).unwrap();
|
||||||
let color_role = roles.iter().find(|role| role.name.contains("COwOlor"));
|
let color_role = roles.iter().find(|role| role.name.contains("COwOlor"));
|
||||||
|
|
||||||
if let Some(role) = color_role {
|
if let Some(role) = color_role {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use poise::serenity_prelude::model::id::UserId;
|
|||||||
use poise::serenity_prelude::utils::MessageBuilder;
|
use poise::serenity_prelude::utils::MessageBuilder;
|
||||||
use poise::serenity_prelude::{EmojiIdentifier, Mentionable};
|
use poise::serenity_prelude::{EmojiIdentifier, Mentionable};
|
||||||
use rand::seq::IteratorRandom;
|
use rand::seq::IteratorRandom;
|
||||||
use rand::{rng, Rng};
|
use rand::rng;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
fn cleanup_race(db: &Database) -> Result<(), Error> {
|
fn cleanup_race(db: &Database) -> Result<(), Error> {
|
||||||
@ -39,6 +39,7 @@ async fn add_bet(ctx: Context<'_>, bet: Bet, racers: &[Racer]) -> Result<(), Rac
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Setup an emoji race to bet on
|
||||||
#[poise::command(prefix_command, guild_only, category = "Race")]
|
#[poise::command(prefix_command, guild_only, category = "Race")]
|
||||||
pub async fn race(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn race(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
cleanup_race(&ctx.data().db)?;
|
cleanup_race(&ctx.data().db)?;
|
||||||
@ -64,6 +65,7 @@ pub async fn race(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start the race!
|
||||||
#[poise::command(prefix_command, guild_only, category = "Race")]
|
#[poise::command(prefix_command, guild_only, category = "Race")]
|
||||||
pub async fn start_race(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn start_race(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let mut racers = Racer::get_racers(&ctx.data().db)?;
|
let mut racers = Racer::get_racers(&ctx.data().db)?;
|
||||||
@ -154,6 +156,7 @@ pub async fn start_race(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Bet on a race of emojis, a sound idea
|
||||||
#[poise::command(prefix_command, guild_only, category = "Race")]
|
#[poise::command(prefix_command, guild_only, category = "Race")]
|
||||||
pub async fn bet(
|
pub async fn bet(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use poise::serenity_prelude::model::id::UserId;
|
|||||||
use poise::serenity_prelude::prelude::Mentionable;
|
use poise::serenity_prelude::prelude::Mentionable;
|
||||||
use rand::{rng, Rng};
|
use rand::{rng, Rng};
|
||||||
|
|
||||||
|
/// Get your balance or someone else's
|
||||||
#[poise::command(prefix_command, category = "Fren Coin", aliases("audit"))]
|
#[poise::command(prefix_command, category = "Fren Coin", aliases("audit"))]
|
||||||
pub async fn balance(
|
pub async fn balance(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -26,6 +27,7 @@ pub async fn balance(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gift someone the gift that keeps on giving, Fren Coins!
|
||||||
#[poise::command(prefix_command, category = "Fren Coin", aliases("audit"))]
|
#[poise::command(prefix_command, category = "Fren Coin", aliases("audit"))]
|
||||||
pub async fn gift(
|
pub async fn gift(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use chrono::Utc;
|
|||||||
use emojis::Group;
|
use emojis::Group;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use poise::serenity_prelude::all::{CreateAttachment, CreateMessage};
|
use poise::serenity_prelude::all::{CreateAttachment, CreateMessage};
|
||||||
use poise::serenity_prelude::builder::EditMessage;
|
|
||||||
use poise::serenity_prelude::constants::MESSAGE_CODE_LIMIT;
|
use poise::serenity_prelude::constants::MESSAGE_CODE_LIMIT;
|
||||||
use poise::serenity_prelude::model::channel::Message;
|
use poise::serenity_prelude::model::channel::Message;
|
||||||
use poise::serenity_prelude::utils::MessageBuilder;
|
use poise::serenity_prelude::utils::MessageBuilder;
|
||||||
@ -21,7 +20,6 @@ use rand::prelude::IndexedRandom;
|
|||||||
use rand::rng;
|
use rand::rng;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use songbird::id::UserId;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -32,6 +30,7 @@ struct DadJoke {
|
|||||||
pub status: i32,
|
pub status: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ask your dad
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn dad_joke(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn dad_joke(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
@ -136,6 +135,7 @@ pub async fn random(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a random command to the bot
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn add_random(
|
pub async fn add_random(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -143,7 +143,7 @@ pub async fn add_random(
|
|||||||
#[description = "Random message"] random_response: String,
|
#[description = "Random message"] random_response: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
render_random(&ctx.author().display_name(), ctx.data(), &random_response).await
|
render_random(ctx.author().display_name(), ctx.data(), &random_response).await
|
||||||
{
|
{
|
||||||
ctx.reply(format!("Template failed test render, try again: {}", err))
|
ctx.reply(format!("Template failed test render, try again: {}", err))
|
||||||
.await?;
|
.await?;
|
||||||
@ -155,6 +155,7 @@ pub async fn add_random(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List all of the random sets
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn list_random(
|
pub async fn list_random(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -195,6 +196,7 @@ pub async fn list_random(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Roll a totally not loaded digital die!
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn roll(
|
pub async fn roll(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -214,6 +216,7 @@ pub async fn roll(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Roll a totally not loaded, real actual die! (No joke)
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn real_roll(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn real_roll(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let addr = ctx.data().cfg.raas_server.clone();
|
let addr = ctx.data().cfg.raas_server.clone();
|
||||||
@ -271,6 +274,7 @@ pub async fn real_roll(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Play critically the acclaimed Bad Apple music video as god intended
|
||||||
#[poise::command(prefix_command, category = "Joke")]
|
#[poise::command(prefix_command, category = "Joke")]
|
||||||
pub async fn bad_apple(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn bad_apple(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let mut frames = BAD_APPLE.split('|');
|
let mut frames = BAD_APPLE.split('|');
|
||||||
@ -311,6 +315,7 @@ pub async fn bad_apple(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insult or compliment your "friends"!
|
||||||
#[poise::command(prefix_command, category = "Joke", aliases("compliment"))]
|
#[poise::command(prefix_command, category = "Joke", aliases("compliment"))]
|
||||||
pub async fn insult(
|
pub async fn insult(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -355,6 +360,7 @@ fn get_unicode_emojis() -> Vec<String> {
|
|||||||
emoji.iter().map(|e| e.to_string()).collect()
|
emoji.iter().map(|e| e.to_string()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stare into the digital black mirror and see what it reflects
|
||||||
#[poise::command(prefix_command, category = "Joke", aliases("🎱"))]
|
#[poise::command(prefix_command, category = "Joke", aliases("🎱"))]
|
||||||
pub async fn emoji_8ball(
|
pub async fn emoji_8ball(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use poise::serenity_prelude::utils::MessageBuilder;
|
|||||||
use rand::prelude::IndexedRandom;
|
use rand::prelude::IndexedRandom;
|
||||||
use rand::{rng, Rng};
|
use rand::{rng, Rng};
|
||||||
|
|
||||||
|
/// Adopt a new little buddy!
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn adopt(
|
pub async fn adopt(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -34,6 +35,7 @@ pub async fn adopt(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checkup on your little buddy!
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn checkup(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn checkup(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
||||||
@ -82,6 +84,7 @@ pub async fn checkup(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Feed your little buddy something totally normal!
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn feed(
|
pub async fn feed(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -91,7 +94,7 @@ pub async fn feed(
|
|||||||
|
|
||||||
if let Some(mut lil_fren) = lil_fren {
|
if let Some(mut lil_fren) = lil_fren {
|
||||||
if lil_fren.is_alive() == AliveState::Alive {
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
let feed: f32 = rng().gen_range(-0.1..=1.0);
|
let feed: f32 = rng().random_range(-0.1..=1.0);
|
||||||
lil_fren.hunger = (lil_fren.hunger + feed).clamp(-1.0, 1.0);
|
lil_fren.hunger = (lil_fren.hunger + feed).clamp(-1.0, 1.0);
|
||||||
let guild = ctx.guild_id().unwrap();
|
let guild = ctx.guild_id().unwrap();
|
||||||
|
|
||||||
@ -117,6 +120,7 @@ pub async fn feed(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Give your little buddy the juice of life.
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn give_water(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn give_water(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
||||||
@ -149,6 +153,7 @@ pub async fn give_water(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Play with little buddy before he shreds up the remote again
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn play(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn play(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
||||||
@ -175,6 +180,7 @@ pub async fn play(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Give your little buddy medicine
|
||||||
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
#[poise::command(prefix_command, guild_only, category = "Lil Buddy")]
|
||||||
pub async fn give_medicine(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn give_medicine(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
|
||||||
|
|||||||
@ -55,7 +55,7 @@ async fn event_handler(
|
|||||||
{
|
{
|
||||||
info!("Starting lil buddy task...");
|
info!("Starting lil buddy task...");
|
||||||
let data = data.clone();
|
let data = data.clone();
|
||||||
tokio::spawn(async move { lil_fren_task(data) });
|
tokio::spawn(async move { lil_fren_task(data).await });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serenity::FullEvent::Message { new_message } => {
|
serenity::FullEvent::Message { new_message } => {
|
||||||
@ -155,6 +155,18 @@ async fn pre_command(ctx: Context<'_>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[poise::command(prefix_command)]
|
||||||
|
pub async fn help(ctx: Context<'_>, command: Option<String>) -> Result<(), Error> {
|
||||||
|
let configuration = poise::builtins::HelpConfiguration {
|
||||||
|
extra_text_at_bottom: "Made with 💖 by Joey",
|
||||||
|
include_description: false,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
poise::builtins::help(ctx, command.as_deref(), configuration).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn run_bot(global_data: GlobalData) {
|
pub async fn run_bot(global_data: GlobalData) {
|
||||||
let framework_options: FrameworkOptions<Arc<GlobalData>, Error> = poise::FrameworkOptions {
|
let framework_options: FrameworkOptions<Arc<GlobalData>, Error> = poise::FrameworkOptions {
|
||||||
prefix_options: poise::PrefixFrameworkOptions {
|
prefix_options: poise::PrefixFrameworkOptions {
|
||||||
@ -165,6 +177,7 @@ pub async fn run_bot(global_data: GlobalData) {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
commands: vec![
|
commands: vec![
|
||||||
|
help(),
|
||||||
admin::dump_db(),
|
admin::dump_db(),
|
||||||
admin::load_db(),
|
admin::load_db(),
|
||||||
admin::add_key(),
|
admin::add_key(),
|
||||||
|
|||||||
@ -57,6 +57,7 @@ pub async fn create_motivation_image(motivation: Motivation) -> Result<Vec<u8>,
|
|||||||
Ok(wand.write_image_blob("jpg")?)
|
Ok(wand.write_image_blob("jpg")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Become motivated
|
||||||
#[poise::command(prefix_command, category = "Motivation")]
|
#[poise::command(prefix_command, category = "Motivation")]
|
||||||
pub async fn motivation(
|
pub async fn motivation(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -87,6 +88,7 @@ pub async fn motivation(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an album to the pool of images to be used for motivations
|
||||||
#[poise::command(prefix_command, category = "Motivation")]
|
#[poise::command(prefix_command, category = "Motivation")]
|
||||||
pub async fn motivation_add_album(
|
pub async fn motivation_add_album(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use crate::user::{User, UserError};
|
|||||||
use poise::serenity_prelude::all::{
|
use poise::serenity_prelude::all::{
|
||||||
parse_user_mention, CreateAttachment, CreateMessage, EditRole, GuildId, Member,
|
parse_user_mention, CreateAttachment, CreateMessage, EditRole, GuildId, Member,
|
||||||
};
|
};
|
||||||
use poise::serenity_prelude::model::channel::Message;
|
|
||||||
use poise::serenity_prelude::model::Colour;
|
use poise::serenity_prelude::model::Colour;
|
||||||
use poise::serenity_prelude::prelude::Mentionable;
|
use poise::serenity_prelude::prelude::Mentionable;
|
||||||
use poise::serenity_prelude::utils::MessageBuilder;
|
use poise::serenity_prelude::utils::MessageBuilder;
|
||||||
@ -20,6 +19,7 @@ use std::hash::Hasher;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
/// Shop at a real virtual shop in the Metaverse!
|
||||||
#[poise::command(prefix_command, category = "Shop")]
|
#[poise::command(prefix_command, category = "Shop")]
|
||||||
pub async fn shop(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn shop(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let bot_user = User::get_user(&ctx.data().db, ctx.cache().current_user().id)?;
|
let bot_user = User::get_user(&ctx.data().db, ctx.cache().current_user().id)?;
|
||||||
@ -40,6 +40,7 @@ pub async fn shop(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Look at your inventory, this button is forced bound to any key other than "B"
|
||||||
#[poise::command(prefix_command, category = "Shop")]
|
#[poise::command(prefix_command, category = "Shop")]
|
||||||
pub async fn inventory(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn inventory(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let mut inv_msg = MessageBuilder::new();
|
let mut inv_msg = MessageBuilder::new();
|
||||||
@ -59,6 +60,7 @@ pub async fn inventory(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Buy an item from the shop with your hard earned cash
|
||||||
#[poise::command(prefix_command, category = "Shop")]
|
#[poise::command(prefix_command, category = "Shop")]
|
||||||
pub async fn buy(
|
pub async fn buy(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -84,7 +86,7 @@ pub async fn buy(
|
|||||||
|
|
||||||
ctx.reply(resp).await?;
|
ctx.reply(resp).await?;
|
||||||
} else {
|
} else {
|
||||||
return Err(err.into());
|
return Err(err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.reply(format!("Congrats, you now own a '{}'", item))
|
ctx.reply(format!("Congrats, you now own a '{}'", item))
|
||||||
@ -150,6 +152,7 @@ async fn blockable_item(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use an item and hope it doesn't use you
|
||||||
#[poise::command(prefix_command, category = "Shop", guild_only, aliases("use"))]
|
#[poise::command(prefix_command, category = "Shop", guild_only, aliases("use"))]
|
||||||
pub async fn use_item(
|
pub async fn use_item(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -323,6 +326,7 @@ pub async fn use_item(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sell an item for profit
|
||||||
#[poise::command(prefix_command, category = "Shop", aliases("sell"))]
|
#[poise::command(prefix_command, category = "Shop", aliases("sell"))]
|
||||||
pub async fn sell_item(
|
pub async fn sell_item(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -359,17 +363,19 @@ pub async fn sell_item(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(err.into());
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get help on what an item does
|
||||||
#[poise::command(prefix_command, category = "Shop")]
|
#[poise::command(prefix_command, category = "Shop")]
|
||||||
pub async fn item_help(
|
pub async fn item_help(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
#[description = "I"]
|
#[description = "Item to get help on"]
|
||||||
#[rest]
|
#[rest]
|
||||||
item: ItemType,
|
item: ItemType,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
use crate::discord::Context;
|
use crate::discord::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use magick_rust::bindings::wchar_t;
|
|
||||||
use poise::async_trait;
|
use poise::async_trait;
|
||||||
use poise::serenity_prelude::all::CreateAttachment;
|
use poise::serenity_prelude::all::CreateAttachment;
|
||||||
use poise::serenity_prelude::builder::CreateMessage;
|
use poise::serenity_prelude::builder::CreateMessage;
|
||||||
use poise::serenity_prelude::model::channel::Message;
|
|
||||||
use poise::serenity_prelude::model::id::UserId;
|
use poise::serenity_prelude::model::id::UserId;
|
||||||
use poise::serenity_prelude::model::prelude::GuildId;
|
use poise::serenity_prelude::model::prelude::GuildId;
|
||||||
use poise::serenity_prelude::utils::MessageBuilder;
|
use poise::serenity_prelude::utils::MessageBuilder;
|
||||||
@ -132,7 +130,7 @@ pub async fn speak(
|
|||||||
voice: &str,
|
voice: &str,
|
||||||
phrase: &str,
|
phrase: &str,
|
||||||
) -> Result<(), VoiceError> {
|
) -> Result<(), VoiceError> {
|
||||||
let _ = ctx.data().speak_lock.lock();
|
let _ = ctx.data().speak_lock.lock().await;
|
||||||
|
|
||||||
let voice_path = match find_voice(&ctx.data().cfg.voice_path, voice).await.unwrap() {
|
let voice_path = match find_voice(&ctx.data().cfg.voice_path, voice).await.unwrap() {
|
||||||
None => return Err(VoiceError::VoiceNotFound(voice.to_string())),
|
None => return Err(VoiceError::VoiceNotFound(voice.to_string())),
|
||||||
@ -231,6 +229,7 @@ pub async fn speak(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Speak in the language of the gods
|
||||||
#[poise::command(prefix_command, category = "Voice", guild_only)]
|
#[poise::command(prefix_command, category = "Voice", guild_only)]
|
||||||
pub async fn say(
|
pub async fn say(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -296,6 +295,7 @@ pub async fn list_words(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List all voices the bot has
|
||||||
#[poise::command(prefix_command, category = "Voice", guild_only)]
|
#[poise::command(prefix_command, category = "Voice", guild_only)]
|
||||||
pub async fn list_voices(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn list_voices(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let mut voice_message = MessageBuilder::new();
|
let mut voice_message = MessageBuilder::new();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::discord::voices::VoiceError;
|
|||||||
use crate::user;
|
use crate::user;
|
||||||
use magick_rust::MagickError;
|
use magick_rust::MagickError;
|
||||||
use serde::ser::StdError;
|
use serde::ser::StdError;
|
||||||
use std::fmt::{write, Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(clippy::enum_variant_names)]
|
#[allow(clippy::enum_variant_names)]
|
||||||
|
|||||||
@ -9,9 +9,8 @@ mod user;
|
|||||||
|
|
||||||
use crate::config::{Args, BotConfig, GlobalData};
|
use crate::config::{Args, BotConfig, GlobalData};
|
||||||
use crate::discord::run_bot;
|
use crate::discord::run_bot;
|
||||||
use log::{error, info, LevelFilter};
|
use log::{error, info};
|
||||||
use magick_rust::magick_wand_genesis;
|
use magick_rust::magick_wand_genesis;
|
||||||
use songbird::SerenityInit;
|
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,8 @@ impl Apikey {
|
|||||||
general_purpose::STANDARD_NO_PAD.encode(hash)
|
general_purpose::STANDARD_NO_PAD.encode(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn find_key_from_secret(db: &Database, secret: &str) -> Result<Option<Self>, Error> {
|
pub fn find_key_from_secret(db: &Database, secret: &str) -> Result<Option<Self>, Error> {
|
||||||
let hash = Self::hash_secret(secret);
|
let hash = Self::hash_secret(secret);
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ use j_db::database::Database;
|
|||||||
use j_db::model::JdbModel;
|
use j_db::model::JdbModel;
|
||||||
use rand::prelude::IndexedRandom;
|
use rand::prelude::IndexedRandom;
|
||||||
use rand::rng;
|
use rand::rng;
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tera::{Context, Tera};
|
use tera::{Context, Tera};
|
||||||
|
|||||||
@ -194,7 +194,7 @@ pub enum LilFrenState {
|
|||||||
|
|
||||||
impl Distribution<LilFrenState> for StandardUniform {
|
impl Distribution<LilFrenState> for StandardUniform {
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> LilFrenState {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> LilFrenState {
|
||||||
match rng.gen_range(0..10) {
|
match rng.random_range(0..10) {
|
||||||
0 => LilFrenState::Standing,
|
0 => LilFrenState::Standing,
|
||||||
1 => LilFrenState::TaxFraud,
|
1 => LilFrenState::TaxFraud,
|
||||||
2 => LilFrenState::Sick,
|
2 => LilFrenState::Sick,
|
||||||
@ -253,8 +253,8 @@ impl LilFren {
|
|||||||
thirst: 1.0,
|
thirst: 1.0,
|
||||||
entertainment: 1.0,
|
entertainment: 1.0,
|
||||||
state: LilFrenState::Standing,
|
state: LilFrenState::Standing,
|
||||||
smarts: rng().gen_range(0.0..0.5),
|
smarts: rng().random_range(0.0..0.5),
|
||||||
metabolism: rng().gen_range(0.2..0.75),
|
metabolism: rng().random_range(0.2..0.75),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::user::UserError;
|
use crate::user::UserError;
|
||||||
use j_db::database::Database;
|
use j_db::database::Database;
|
||||||
use j_db::error::JDbError;
|
|
||||||
use j_db::model::JdbModel;
|
use j_db::model::JdbModel;
|
||||||
use poise::serenity_prelude::{Emoji, EmojiId, MessageBuilder, UserId};
|
use poise::serenity_prelude::{Emoji, EmojiId, MessageBuilder, UserId};
|
||||||
use rand::{rng, Rng};
|
use rand::{rng, Rng};
|
||||||
@ -134,7 +133,7 @@ impl Racer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_pos(&mut self) {
|
pub fn update_pos(&mut self) {
|
||||||
let speed_boost = rng().gen_range(-0.75..0.75);
|
let speed_boost = rng().random_range(-0.75..0.75);
|
||||||
self.pos += self.speed + (self.speed * speed_boost);
|
self.pos += self.speed + (self.speed * speed_boost);
|
||||||
|
|
||||||
self.pos = self.pos.clamp(0.0, RACE_SIZE as f32);
|
self.pos = self.pos.clamp(0.0, RACE_SIZE as f32);
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use j_db::database::Database;
|
|||||||
use j_db::model::JdbModel;
|
use j_db::model::JdbModel;
|
||||||
use rand::distr::weighted::WeightedIndex;
|
use rand::distr::weighted::WeightedIndex;
|
||||||
use rand::prelude::Distribution;
|
use rand::prelude::Distribution;
|
||||||
use rand::thread_rng;
|
use rand::rng;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ impl RandomConfig {
|
|||||||
|
|
||||||
let dist = WeightedIndex::new(responses.iter().map(|r| r.score)).unwrap();
|
let dist = WeightedIndex::new(responses.iter().map(|r| r.score)).unwrap();
|
||||||
|
|
||||||
let mut resp = responses[dist.sample(&mut thread_rng())].clone();
|
let mut resp = responses[dist.sample(&mut rng())].clone();
|
||||||
|
|
||||||
resp.score = resp.score.saturating_sub(1);
|
resp.score = resp.score.saturating_sub(1);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user