Add social credit system
This commit is contained in:
parent
32fa1a11d1
commit
6b2d4641cc
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1093,7 +1093,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fren"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
dependencies = [
|
||||
"axum 0.8.1",
|
||||
"base64 0.22.1",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fren"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
edition = "2024"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -7,8 +7,10 @@ use crate::models::lil_fren::{
|
||||
draw_resonance_cascade, draw_sick, draw_sleep, draw_standing, draw_tax_fraud,
|
||||
};
|
||||
use crate::models::managed_roles::ManagedRole;
|
||||
use crate::models::social_credit::SocialCreditPhrase;
|
||||
use crate::models::task::Task;
|
||||
use crate::user::User;
|
||||
use j_db::model::JdbModel;
|
||||
use json::JsonValue;
|
||||
use log::info;
|
||||
use poise::serenity_prelude::{
|
||||
@ -263,3 +265,66 @@ pub async fn remove_role(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a phrase to check for social credit
|
||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||
pub async fn add_social_credit_phrase(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Phrase to look for, wrap in \"s if you want multiple words"] phrase: String,
|
||||
#[description = "Upper limit of points to add/take away"] upper_limit: i64,
|
||||
#[description = "Lower limit of points to take away"] lower_limit: i64,
|
||||
) -> Result<(), Error> {
|
||||
let social_credit_phrase =
|
||||
SocialCreditPhrase::add_new_phrase(&ctx.data().db, phrase, upper_limit, lower_limit)?;
|
||||
|
||||
ctx.reply(format!(
|
||||
"Added new phrase '{}' with id `{}`",
|
||||
social_credit_phrase.phrase,
|
||||
social_credit_phrase.id().unwrap()
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove a social credit phrase
|
||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||
pub async fn remove_social_credit_phrase(
|
||||
ctx: Context<'_>,
|
||||
#[description = "ID of the phrase to remove"] id: u64,
|
||||
) -> Result<(), Error> {
|
||||
let social_credit_phrase = ctx.data().db.remove::<SocialCreditPhrase>(id)?;
|
||||
|
||||
ctx.reply(format!(
|
||||
"Removed phrase '{}' with id `{}`",
|
||||
social_credit_phrase.phrase,
|
||||
social_credit_phrase.id().unwrap()
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// List social credit phrases
|
||||
#[poise::command(prefix_command, category = "Admin", check = "is_admin")]
|
||||
pub async fn list_social_credit_phrases(ctx: Context<'_>) -> Result<(), Error> {
|
||||
let social_credit_phrase = SocialCreditPhrase::get_phrases(&ctx.data().db)?;
|
||||
|
||||
let mut list = MessageBuilder::new();
|
||||
|
||||
list.push_line("The following phrases are EXAMINED for their value for the state:");
|
||||
|
||||
for phrase in &social_credit_phrase {
|
||||
list.push_line(format!(
|
||||
"* id={} phrase={} upper_bound={} lower_bound={}",
|
||||
phrase.id().unwrap(),
|
||||
phrase.phrase,
|
||||
phrase.upper_bound,
|
||||
phrase.lower_bound
|
||||
));
|
||||
}
|
||||
|
||||
ctx.reply(list.build()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -64,6 +64,51 @@ pub async fn gift(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Find your social worth in the eyes of the glorious part
|
||||
#[poise::command(prefix_command, category = "Fren Coin")]
|
||||
pub async fn social_credit(
|
||||
ctx: Context<'_>,
|
||||
#[description = "User to get the social credit of"] user: Option<poise::serenity_prelude::User>,
|
||||
) -> Result<(), Error> {
|
||||
let user_id = user.map(|u| u.id).unwrap_or(ctx.author().id);
|
||||
|
||||
let user = User::get_user(&ctx.data().db, user_id)?;
|
||||
|
||||
let msg = if user.social_credit < -2000 {
|
||||
"||REDACTED||"
|
||||
} else if user.social_credit < -1000 {
|
||||
"Very bad person they are!"
|
||||
} else if user.social_credit < -500 {
|
||||
"Likely a capitalist!"
|
||||
} else if user.social_credit < -100 {
|
||||
"Tread carefully..."
|
||||
} else if user.social_credit < 0 {
|
||||
"There is always a chance, before its too late..."
|
||||
} else if user.social_credit < 100 {
|
||||
"Okay, but be cautious with your words."
|
||||
} else if user.social_credit < 500 {
|
||||
"There is only winners and losers."
|
||||
} else if user.social_credit < 1000 {
|
||||
"On the up and up!"
|
||||
} else if user.social_credit < 2000 {
|
||||
"A great member of our glorious society!"
|
||||
} else if user.social_credit >= 2000 {
|
||||
"Perfect in every way, may your deeds shine light in our world!!!"
|
||||
} else {
|
||||
"There is no god for you."
|
||||
};
|
||||
|
||||
ctx.reply(format!(
|
||||
"{}'s social credit is {}. {}",
|
||||
user_id.mention(),
|
||||
user.social_credit,
|
||||
msg
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn give_coin(
|
||||
db: &Database,
|
||||
user: UserId,
|
||||
|
||||
@ -18,12 +18,14 @@ use crate::discord::fren_coin::give_coin;
|
||||
use crate::discord::joke::random;
|
||||
use crate::error::Error;
|
||||
use crate::models::lil_fren::lil_fren_task;
|
||||
use crate::models::social_credit::SocialCreditPhrase;
|
||||
use crate::models::task::Task;
|
||||
use log::{error, info};
|
||||
use crate::user::User;
|
||||
use log::{debug, error, info};
|
||||
use poise::serenity_prelude::{GuildId, Http, Message, MessageBuilder, ReactionType, RoleId};
|
||||
use poise::{FrameworkOptions, find_command, serenity_prelude as serenity};
|
||||
use rand::prelude::IteratorRandom;
|
||||
use rand::rng;
|
||||
use rand::{Rng, rng};
|
||||
use songbird::SerenityInit;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@ -81,6 +83,18 @@ async fn handle_message(
|
||||
data: &Arc<GlobalData>,
|
||||
new_message: &Message,
|
||||
) -> Result<(), Error> {
|
||||
if new_message.content.eq_ignore_ascii_case("yes")
|
||||
|| new_message.content.eq_ignore_ascii_case("mhmm")
|
||||
{
|
||||
let mut bot_state = data.bot_state.lock().await;
|
||||
if let Some(u) = bot_state.accepted_nsfw {
|
||||
if new_message.author.id == u {
|
||||
new_message.reply(&ctx.http, "||https://cdn.discordapp.com/attachments/614891432079130625/1041545254362423368/unknown.png||").await.unwrap();
|
||||
bot_state.accepted_nsfw = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if new_message.content.to_lowercase().contains("good bot") {
|
||||
let recv_coin = give_coin(&data.db, new_message.author.id, 0.50, 25).await?;
|
||||
|
||||
@ -113,6 +127,18 @@ async fn handle_message(
|
||||
|
||||
give_coin(&data.db, new_message.author.id, 0.05, 10).await?;
|
||||
|
||||
if let Some(phrase) = SocialCreditPhrase::check_if_match(&data.db, &new_message.content)? {
|
||||
debug!(
|
||||
"{} matched phrase '{}' for social credit checking",
|
||||
new_message.author.name, phrase.phrase
|
||||
);
|
||||
|
||||
let social_credit_change =
|
||||
rand::rng().random_range(phrase.lower_bound..=phrase.upper_bound);
|
||||
|
||||
User::update_social_credit(&data.db, new_message.author.id, social_credit_change)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -275,6 +301,9 @@ pub async fn run_bot(global_data: GlobalData) {
|
||||
admin::list_tasks(),
|
||||
admin::add_role(),
|
||||
admin::remove_role(),
|
||||
admin::add_social_credit_phrase(),
|
||||
admin::remove_social_credit_phrase(),
|
||||
admin::list_social_credit_phrases(),
|
||||
album::add_image(),
|
||||
album::list_albums(),
|
||||
birthday::add_birthday(),
|
||||
@ -289,6 +318,7 @@ pub async fn run_bot(global_data: GlobalData) {
|
||||
emoji_race::start_race(),
|
||||
fren_coin::balance(),
|
||||
fren_coin::gift(),
|
||||
fren_coin::social_credit(),
|
||||
joke::add_random(),
|
||||
joke::dad_joke(),
|
||||
joke::bad_apple(),
|
||||
|
||||
30
src/migrations/migration_6_add_social_credit.rs
Normal file
30
src/migrations/migration_6_add_social_credit.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use j_db::database::Database;
|
||||
use j_db::migration::Migration;
|
||||
|
||||
pub struct Migration6AddSocialCredit {}
|
||||
|
||||
impl Migration for Migration6AddSocialCredit {
|
||||
fn up(&self, db: &Database) -> j_db::error::Result<()> {
|
||||
let tree = db.db.open_tree("Users")?;
|
||||
|
||||
for user_entry in tree.iter() {
|
||||
let (id, user) = user_entry?;
|
||||
|
||||
let mut user = json::parse(std::str::from_utf8(&user).unwrap()).unwrap();
|
||||
|
||||
user["social_credit"] = json::JsonValue::Number(json::number::Number::from(1000));
|
||||
|
||||
tree.insert(id, user.to_string().as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn down(&self, _db: &Database) -> j_db::error::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn version(&self) -> u64 {
|
||||
6
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::migrations::migration_4_update_random::Migration4UpdateRandoms;
|
||||
use crate::migrations::migration_5_update_motivation::Migration5UpdateMotivation;
|
||||
use crate::migrations::migration_6_add_social_credit::Migration6AddSocialCredit;
|
||||
use crate::migrations::migration2_remove_imgur::Migration2RemoveImgur;
|
||||
use crate::migrations::migration3_remove_img::Migration3RemoveImage;
|
||||
use j_db::database::Database;
|
||||
@ -10,8 +11,9 @@ mod migration2_remove_imgur;
|
||||
mod migration3_remove_img;
|
||||
mod migration_4_update_random;
|
||||
mod migration_5_update_motivation;
|
||||
mod migration_6_add_social_credit;
|
||||
|
||||
pub const CURRENT_DB_VERSION: u64 = 5;
|
||||
pub const CURRENT_DB_VERSION: u64 = 6;
|
||||
|
||||
#[allow(clippy::single_match)]
|
||||
pub fn do_migration(db: &Database) {
|
||||
@ -48,6 +50,12 @@ pub fn do_migration(db: &Database) {
|
||||
Direction::Up,
|
||||
)
|
||||
.unwrap(),
|
||||
6 => migration::do_migration::<Migration6AddSocialCredit>(
|
||||
db,
|
||||
Migration6AddSocialCredit {},
|
||||
Direction::Up,
|
||||
)
|
||||
.unwrap(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,4 +6,5 @@ pub mod managed_roles;
|
||||
pub mod motivation;
|
||||
pub mod race;
|
||||
pub mod random;
|
||||
pub mod social_credit;
|
||||
pub mod task;
|
||||
|
||||
62
src/models/social_credit.rs
Normal file
62
src/models/social_credit.rs
Normal file
@ -0,0 +1,62 @@
|
||||
use crate::error::Error;
|
||||
use j_db::database::Database;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct SocialCreditPhrase {
|
||||
id: Option<u64>,
|
||||
pub phrase: String,
|
||||
pub lower_bound: i64,
|
||||
pub upper_bound: i64,
|
||||
}
|
||||
|
||||
impl j_db::model::JdbModel for SocialCreditPhrase {
|
||||
fn id(&self) -> Option<u64> {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn set_id(&mut self, id: u64) {
|
||||
self.id = Some(id)
|
||||
}
|
||||
|
||||
fn tree() -> String {
|
||||
"SocialCreditPhrase".to_string()
|
||||
}
|
||||
|
||||
fn check_unique(&self, other: &Self) -> bool {
|
||||
other.phrase.to_lowercase() == self.phrase.to_lowercase()
|
||||
}
|
||||
}
|
||||
|
||||
impl SocialCreditPhrase {
|
||||
pub fn check_if_match(db: &Database, msg: &str) -> Result<Option<Self>, Error> {
|
||||
let lowercase_msg = msg.to_lowercase();
|
||||
let matches = db
|
||||
.filter(|_, phrase: &Self| lowercase_msg.contains(&phrase.phrase.to_lowercase()))?
|
||||
.next();
|
||||
|
||||
Ok(matches)
|
||||
}
|
||||
|
||||
pub fn add_new_phrase(
|
||||
db: &Database,
|
||||
phrase: String,
|
||||
lower_bound: i64,
|
||||
upper_bound: i64,
|
||||
) -> Result<Self, Error> {
|
||||
let new_phrase = db.insert(Self {
|
||||
id: None,
|
||||
phrase,
|
||||
lower_bound,
|
||||
upper_bound,
|
||||
})?;
|
||||
|
||||
Ok(new_phrase)
|
||||
}
|
||||
|
||||
pub fn get_phrases(db: &Database) -> Result<Vec<Self>, Error> {
|
||||
let phrases = db.filter(|_, _phrase: &Self| true)?.collect();
|
||||
|
||||
Ok(phrases)
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,7 @@ pub struct User {
|
||||
pub id: Option<u64>,
|
||||
pub user_id: UserId,
|
||||
pub coin_count: i64,
|
||||
pub social_credit: i64,
|
||||
#[serde(default)]
|
||||
pub inventory: InventoryManager,
|
||||
}
|
||||
@ -46,6 +47,7 @@ impl User {
|
||||
id: None,
|
||||
user_id,
|
||||
coin_count: 0,
|
||||
social_credit: 1000,
|
||||
inventory: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -201,6 +203,15 @@ impl User {
|
||||
db.insert::<User>(buyer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_social_credit(db: &Database, user: UserId, amount: i64) -> Result<(), Error> {
|
||||
let mut user = User::get_user(db, user)?;
|
||||
|
||||
user.social_credit += amount;
|
||||
|
||||
db.insert::<User>(user)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl JdbModel for User {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user