Update GR to be less op (plz nerf)
This commit is contained in:
parent
ce6f0c0d9d
commit
5b4c6b50ae
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -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",
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
14
src/error.rs
14
src/error.rs
@ -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."
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user