Skip to content

Commit

Permalink
Seperated gaw decay compute from gaw lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtread committed Sep 18, 2023
1 parent 098c7d4 commit ae6c4fe
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 66 deletions.
117 changes: 54 additions & 63 deletions src/database/entities/galaxy_at_war.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use sea_orm::prelude::*;
use sea_orm::{
ActiveModelTrait,
ActiveValue::{NotSet, Set},
DatabaseConnection, IntoActiveModel,
DatabaseConnection,
};
use serde::Serialize;
use std::cmp;
use std::future::Future;

/// Structure for a galaxy at war model stored in the database
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]
Expand Down Expand Up @@ -49,29 +49,18 @@ impl Model {
/// The maximum value for galaxy at war entries
const MAX_VALUE: u16 = 10099;

/// Finds or creates a new galaxy at war entry for the provided
/// player. If one exists then the provided decay value will be
/// applied to it.
///
/// `db` The database connection
/// `player` The player to search for galaxy at war models for
/// `decay` The decay value
pub async fn find_or_create(
db: &DatabaseConnection,
player_id: PlayerID,
decay: f32,
) -> DbResult<Self> {
pub async fn get(db: &DatabaseConnection, player_id: PlayerID) -> DbResult<Self> {
let existing = Entity::find()
.filter(Column::PlayerId.eq(player_id))
.one(db)
.await?;

if let Some(value) = existing {
return value.apply_decay(db, decay).await;
return Ok(value);
}

let current_time = Local::now().naive_local();
let model = ActiveModel {
ActiveModel {
id: NotSet,
player_id: Set(player_id),
last_modified: Set(current_time),
Expand All @@ -80,45 +69,62 @@ impl Model {
group_c: Set(Self::MIN_VALUE),
group_d: Set(Self::MIN_VALUE),
group_e: Set(Self::MIN_VALUE),
};
}
.insert(db)
.await
}

model.insert(db).await
/// Increases the stored group values increasing them by the `values`
/// provided for each respective group
pub fn add(
self,
db: &DatabaseConnection,
values: [u16; 5],
) -> impl Future<Output = DbResult<Self>> + '_ {
self.transform(db, |a, b| a.saturating_add(b).min(Model::MAX_VALUE), values)
}

/// Increases the group values stored on the provided
/// galaxy at war models by the values provided.
///
/// `db` The database connection
/// `value` The galaxy at war model to increase
/// `values` The values to increase each group by
pub async fn increase(
/// Decrease the stored group values decreasuing them by the `values`
/// provided for each respective group
pub fn sub(
self,
db: &DatabaseConnection,
values: (u16, u16, u16, u16, u16),
) -> DbResult<Self> {
let new_a = self.group_a + values.0;
let new_b = self.group_b + values.1;
let new_c = self.group_c + values.2;
let new_d = self.group_d + values.3;
let new_e = self.group_e + values.4;
values: [u16; 5],
) -> impl Future<Output = DbResult<Self>> + '_ {
self.transform(db, |a, b| a.saturating_sub(b).max(Model::MIN_VALUE), values)
}

let mut gaw_data = self.into_active_model();
gaw_data.group_a = Set(cmp::min(new_a, Self::MAX_VALUE));
gaw_data.group_b = Set(cmp::min(new_b, Self::MAX_VALUE));
gaw_data.group_c = Set(cmp::min(new_c, Self::MAX_VALUE));
gaw_data.group_d = Set(cmp::min(new_d, Self::MAX_VALUE));
gaw_data.group_e = Set(cmp::min(new_e, Self::MAX_VALUE));
gaw_data.update(db).await
/// Transforms the underlying group values using the provided action
/// function which is given the current value as the first argument
/// and the respective value from `values` as the second argument
#[inline]
pub async fn transform<F>(
self,
db: &DatabaseConnection,
action: F,
values: [u16; 5],
) -> DbResult<Self>
where
F: Fn(u16, u16) -> u16,
{
let current_time = Local::now().naive_local();
ActiveModel {
id: Set(self.id),
player_id: Set(self.player_id),
last_modified: Set(current_time),
group_a: Set(action(self.group_a, values[0])),
group_b: Set(action(self.group_b, values[1])),
group_c: Set(action(self.group_c, values[2])),
group_d: Set(action(self.group_d, values[3])),
group_e: Set(action(self.group_e, values[4])),
}
.update(db)
.await
}

/// Applies the provided galaxy at war decay value to the provided
/// galaxy at war model decreasing the values by the number of days
/// that have passed.
///
/// `db` The database connection
/// `value` The galaxy at war model to decay
/// `decay` The decay value
async fn apply_decay(self, db: &DatabaseConnection, decay: f32) -> DbResult<Self> {
/// Applies the daily decay progress to the group values calculating the
/// decay amount from the number of days passed
pub async fn apply_decay(self, db: &DatabaseConnection, decay: f32) -> DbResult<Self> {
// Skip decaying if decay is non existent
if decay <= 0.0 {
return Ok(self);
Expand All @@ -128,21 +134,6 @@ impl Model {
let days_passed = (current_time - self.last_modified).num_days() as f32;
let decay_value = (decay * days_passed * 100.0) as u16;

// Apply decay while keeping minimum
let a = cmp::max(self.group_a - decay_value, Self::MIN_VALUE);
let b = cmp::max(self.group_b - decay_value, Self::MIN_VALUE);
let c = cmp::max(self.group_c - decay_value, Self::MIN_VALUE);
let d = cmp::max(self.group_d - decay_value, Self::MIN_VALUE);
let e = cmp::max(self.group_e - decay_value, Self::MIN_VALUE);

// Update stored copy
let mut value = self.into_active_model();
value.group_a = Set(a);
value.group_b = Set(b);
value.group_c = Set(c);
value.group_d = Set(d);
value.group_e = Set(e);

value.update(db).await
self.sub(db, [decay_value; 5]).await
}
}
6 changes: 4 additions & 2 deletions src/routes/gaw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub async fn increase_ratings(
) -> Result<Xml, GAWError> {
let (gaw_data, promotions) = get_player_gaw_data(&db, sessions, &id, &config).await?;
let gaw_data = gaw_data
.increase(&db, (query.a, query.b, query.c, query.d, query.e))
.add(&db, [query.a, query.b, query.c, query.d, query.e])
.await?;
Ok(ratings_response(gaw_data, promotions))
}
Expand All @@ -166,9 +166,11 @@ async fn get_player_gaw_data(
.ok_or(GAWError::InvalidToken)?;

let (gaw_data, promotions) = try_join!(
GalaxyAtWar::find_or_create(db, player.id, config.galaxy_at_war.decay),
GalaxyAtWar::get(db, player.id),
get_promotions(db, &player, config)
)?;
let gaw_data = gaw_data.apply_decay(db, config.galaxy_at_war.decay).await?;

Ok((gaw_data, promotions))
}

Expand Down
2 changes: 1 addition & 1 deletion src/routes/players.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ pub async fn get_player_gaw(
Extension(db): Extension<DatabaseConnection>,
) -> PlayersRes<GalaxyAtWar> {
let player = find_player(&db, player_id).await?;
let galax_at_war = GalaxyAtWar::find_or_create(&db, player.id, 0.0).await?;
let galax_at_war = GalaxyAtWar::get(&db, player.id).await?;
Ok(Json(galax_at_war))
}

Expand Down

0 comments on commit ae6c4fe

Please sign in to comment.