Update GR to be less op (plz nerf)

This commit is contained in:
Joey Hines 2025-08-06 19:04:16 -06:00
parent ce6f0c0d9d
commit 5b4c6b50ae
Signed by: joeyahines
GPG Key ID: 38BA6F25C94C9382
5 changed files with 120 additions and 28 deletions

2
Cargo.lock generated
View File

@ -1093,7 +1093,7 @@ dependencies = [
[[package]] [[package]]
name = "fren" name = "fren"
version = "2.2.1" version = "2.3.0"
dependencies = [ dependencies = [
"axum 0.8.1", "axum 0.8.1",
"base64 0.22.1", "base64 0.22.1",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "fren" name = "fren"
version = "2.2.1" version = "2.3.0"
edition = "2024" 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

View File

@ -1,5 +1,6 @@
use crate::discord::voices::VoiceError; use crate::discord::voices::VoiceError;
use crate::image_manipulation::ModifyImageArgError; use crate::image_manipulation::ModifyImageArgError;
use crate::models::gogurt_reserves::GogurtError;
use crate::user; use crate::user;
use magick_rust::MagickError; use magick_rust::MagickError;
use serde::ser::StdError; use serde::ser::StdError;
@ -26,7 +27,7 @@ pub enum Error {
NoImageFound, NoImageFound,
PipelineArgumentError(ModifyImageArgError), PipelineArgumentError(ModifyImageArgError),
NoRandomFound, NoRandomFound,
NotEnoughGogurt, GogurtError(GogurtError),
} }
impl StdError for Error {} impl StdError for Error {}
@ -97,6 +98,12 @@ impl From<ModifyImageArgError> for Error {
} }
} }
impl From<GogurtError> for Error {
fn from(value: GogurtError) -> Self {
Self::GogurtError(value)
}
}
impl Display for Error { impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
@ -117,10 +124,7 @@ impl Display for Error {
Error::NoImageFound => write!(f, "Image not found"), Error::NoImageFound => write!(f, "Image not found"),
Error::PipelineArgumentError(err) => write!(f, "{err}"), Error::PipelineArgumentError(err) => write!(f, "{err}"),
Error::NoRandomFound => write!(f, "No random found"), Error::NoRandomFound => write!(f, "No random found"),
Error::NotEnoughGogurt => write!( Error::GogurtError(err) => write!(f, "{err}"),
f,
"Wow, you really don't have enough gogurt. What are you 12?? Just got buy some poor."
),
} }
} }
} }

View File

@ -1,12 +1,27 @@
use crate::error::Error; use crate::error::Error;
use crate::user::User; use crate::user::User;
use chrono::Utc; use chrono::{DateTime, NaiveTime, TimeZone, Utc};
use j_db::database::Database; use j_db::database::Database;
use log::info; use log::info;
use poise::serenity_prelude::UserId; use poise::serenity_prelude::UserId;
use rand::{Rng, rng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::f32::consts::PI; use thiserror::Error;
const OPENING_HOUR: u32 = 8;
const UPDATE_HOUR: u32 = 12;
const CLOSING_HOUR: u32 = 16;
#[derive(Debug, Error)]
pub enum GogurtError {
#[error("Wow, you really don't have enough gogurt. What are you 12?? Just got buy some poor.")]
NotEnoughGogurt,
#[error(
"Sorry, gogurt can only be bought and sold between the hours of 8AM to 4PM Naperville Time."
)]
OutsideOfGogurtTradingHours,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GogurtReserves { pub struct GogurtReserves {
@ -37,7 +52,30 @@ impl GogurtReserves {
.unwrap_or(Self::default())) .unwrap_or(Self::default()))
} }
pub fn market_opening_time() -> NaiveTime {
NaiveTime::from_hms_opt(OPENING_HOUR, 0, 0).unwrap()
}
pub fn market_update_time() -> NaiveTime {
NaiveTime::from_hms_opt(UPDATE_HOUR, 0, 0).unwrap()
}
pub fn market_closing_time() -> NaiveTime {
NaiveTime::from_hms_opt(CLOSING_HOUR, 0, 0).unwrap()
}
pub fn check_if_in_trading_hours(time: &DateTime<Utc>) -> bool {
let chicago_time = chrono_tz::America::Chicago.from_utc_datetime(&time.naive_utc());
chicago_time.time() >= Self::market_opening_time()
&& chicago_time.time() < Self::market_closing_time()
}
pub fn add_contribution(db: &Database, user: UserId, fc_amount: u64) -> Result<f64, Error> { pub fn add_contribution(db: &Database, user: UserId, fc_amount: u64) -> Result<f64, Error> {
if !Self::check_if_in_trading_hours(&Utc::now()) {
return Err(GogurtError::OutsideOfGogurtTradingHours.into());
}
let mut gogurt_reserve = Self::get_gogurt_reserve(db)?; let mut gogurt_reserve = Self::get_gogurt_reserve(db)?;
let gogurt_amount = gogurt_reserve.convert_fc_to_pounds(fc_amount); let gogurt_amount = gogurt_reserve.convert_fc_to_pounds(fc_amount);
@ -59,6 +97,10 @@ impl GogurtReserves {
user: UserId, user: UserId,
pounds_of_gogurt: f64, pounds_of_gogurt: f64,
) -> Result<u64, Error> { ) -> Result<u64, Error> {
if !Self::check_if_in_trading_hours(&Utc::now()) {
return Err(GogurtError::OutsideOfGogurtTradingHours.into());
}
let mut gogurt_reserve = Self::get_gogurt_reserve(db)?; let mut gogurt_reserve = Self::get_gogurt_reserve(db)?;
let contribution = gogurt_reserve let contribution = gogurt_reserve
.reserve_contributors .reserve_contributors
@ -72,7 +114,7 @@ impl GogurtReserves {
} }
if pounds_of_gogurt > *contribution { if pounds_of_gogurt > *contribution {
Err(Error::NotEnoughGogurt) Err(GogurtError::NotEnoughGogurt.into())
} else { } else {
*contribution -= pounds_of_gogurt; *contribution -= pounds_of_gogurt;
let fc_profit = gogurt_reserve.convert_pounds_to_fc(pounds_of_gogurt); let fc_profit = gogurt_reserve.convert_pounds_to_fc(pounds_of_gogurt);
@ -120,24 +162,23 @@ impl GogurtReserves {
} }
} }
pub fn market_function(time: i64) -> f64 { pub fn market_function() -> f64 {
let x = time as f64; match rng().random_range(0..100) {
(x.sin() + (PI as f64 * x).cos() + (PI as f64 * x).sin() + x.cos() 0..10 => rng().random_range(8.5..10.0),
- (x * 4.0).sin() 90..98 => rng().random_range(10.0..12.0),
- (x * 3.0).cos()) 98..100 => rng().random_range(12.0..14.0),
.clamp(0.01, 6.0) _ => rng().random_range(9.0..11.0),
}
} }
pub fn calculate_new_rate(time: i64) -> f64 { pub fn calculate_new_rate() -> f64 {
Self::market_function(time) Self::market_function()
} }
pub fn update_rate(db: &Database) -> Result<(), Error> { pub fn update_rate(db: &Database) -> Result<(), Error> {
let mut reserves = Self::get_gogurt_reserve(db)?; let mut reserves = Self::get_gogurt_reserve(db)?;
let time = Utc::now().timestamp(); let new_rate = Self::calculate_new_rate();
let new_rate = Self::calculate_new_rate(time);
info!("Updating rate to '{new_rate}'"); info!("Updating rate to '{new_rate}'");
reserves.gogurt_rate_per_pound = Some(new_rate); reserves.gogurt_rate_per_pound = Some(new_rate);
@ -151,13 +192,50 @@ impl GogurtReserves {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::models::gogurt_reserves::GogurtReserves; use crate::models::gogurt_reserves::GogurtReserves;
use chrono::{DateTime, NaiveTime, TimeZone, Utc};
#[test] #[test]
fn test_avg_market_function() { fn test_avg_market_function() {
let sum: f64 = (0..100000).map(GogurtReserves::market_function).sum(); let sum: f64 = (0..100000).map(|_| GogurtReserves::market_function()).sum();
let avg = sum / 100000.0; let avg = sum / 100000.0;
println!("Average = {avg}"); println!("Average = {avg}");
assert!(avg < 1.0 && avg > 0.0) assert!(avg < 11.0 && avg > 9.0)
}
fn gen_time(hour: u32, min: u32, sec: u32) -> DateTime<Utc> {
chrono_tz::America::Chicago
.from_utc_datetime(&Utc::now().naive_utc())
.with_time(NaiveTime::from_hms_opt(hour, min, sec).unwrap())
.unwrap()
.to_utc()
}
#[test]
fn test_is_market_open_before_open() {
assert!(!GogurtReserves::check_if_in_trading_hours(&gen_time(
7, 59, 0
)));
}
#[test]
fn test_is_market_open_after_open() {
assert!(GogurtReserves::check_if_in_trading_hours(&gen_time(
8, 0, 0
)));
}
#[test]
fn test_is_market_open_before_close() {
assert!(GogurtReserves::check_if_in_trading_hours(&gen_time(
15, 59, 0
)));
}
#[test]
fn test_is_market_open_after_close() {
assert!(!GogurtReserves::check_if_in_trading_hours(&gen_time(
16, 0, 0
)));
} }
} }

View File

@ -202,11 +202,21 @@ impl Task {
TaskType::UpdateGogurtRate => { TaskType::UpdateGogurtRate => {
GogurtReserves::update_rate(&data.db)?; GogurtReserves::update_rate(&data.db)?;
Task::add_task( let chicago_time =
&data.db, chrono_tz::America::Chicago.from_utc_datetime(&Utc::now().naive_utc());
TaskType::UpdateGogurtRate,
Utc::now() + Duration::minutes(5), let market_open_time = GogurtReserves::market_opening_time();
)?; let midday_update_time = GogurtReserves::market_update_time();
let next_check = if chicago_time.time() >= midday_update_time {
chicago_time.with_time(market_open_time)
} else {
chicago_time.with_time(midday_update_time)
};
let next_check = next_check.unwrap().with_timezone(&Utc);
Task::add_task(&data.db, TaskType::UpdateGogurtRate, next_check)?;
} }
} }