Enhance money change functionality in EventsWorker: Updated the MoneyChange event effect to include an optional minimum absolute positive value, ensuring that money changes do not result in zero for positive adjustments. Introduced a new SQL query for inserting money history, improving reliability in tracking monetary changes for users.
This commit is contained in:
@@ -16,6 +16,7 @@ use crate::worker::sql::{
|
||||
QUERY_INSERT_NOTIFICATION,
|
||||
QUERY_GET_MONEY,
|
||||
QUERY_UPDATE_MONEY,
|
||||
QUERY_INSERT_MONEY_HISTORY,
|
||||
QUERY_GET_REGION_STOCKS,
|
||||
QUERY_GET_USER_STOCKS,
|
||||
QUERY_UPDATE_STOCK_CAPACITY,
|
||||
@@ -67,8 +68,14 @@ pub enum EventType {
|
||||
/// Mögliche Effekte, die ein Ereignis haben kann
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EventEffect {
|
||||
/// Änderung des Geldes eines Spielers (in Prozent)
|
||||
MoneyChange { probability: f64, min_percent: f64, max_percent: f64 },
|
||||
/// Änderung des Geldes eines Spielers (in Prozent).
|
||||
/// Bei positiver Änderung kann min_absolute_positive einen Mindestbetrag erzwingen (z. B. damit ein „Fund“ nie 0 ist).
|
||||
MoneyChange {
|
||||
probability: f64,
|
||||
min_percent: f64,
|
||||
max_percent: f64,
|
||||
min_absolute_positive: Option<f64>,
|
||||
},
|
||||
/// Änderung der Produktionsqualität in einer Region (in Prozentpunkten)
|
||||
ProductionQualityChange { probability: f64, min_change: i32, max_change: i32 },
|
||||
/// Änderung der Verkaufspreise in einer Region (in Prozent)
|
||||
@@ -169,6 +176,7 @@ impl EventsWorker {
|
||||
probability: 1.0,
|
||||
min_percent: 5.0,
|
||||
max_percent: 15.0,
|
||||
min_absolute_positive: Some(1.0), // Fund ist nie 0
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -183,6 +191,7 @@ impl EventsWorker {
|
||||
probability: 1.0,
|
||||
min_percent: -10.0,
|
||||
max_percent: -5.0,
|
||||
min_absolute_positive: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -511,13 +520,23 @@ impl EventsWorker {
|
||||
probability,
|
||||
min_percent,
|
||||
max_percent,
|
||||
min_absolute_positive,
|
||||
} => {
|
||||
if effect_roll < *probability {
|
||||
let percent_change = rng.gen_range(*min_percent..=*max_percent);
|
||||
let current_money = Self::get_current_money(&mut conn, user_id).unwrap_or(0.0);
|
||||
let computed_change = current_money * (percent_change / 100.0);
|
||||
let absolute_change = Self::apply_money_change(&mut conn, user_id, percent_change)
|
||||
.unwrap_or(computed_change);
|
||||
let effective_change = match min_absolute_positive {
|
||||
Some(min_abs) if percent_change > 0.0 && computed_change < *min_abs => *min_abs,
|
||||
_ => computed_change,
|
||||
};
|
||||
let absolute_change = Self::apply_money_change(
|
||||
&mut conn,
|
||||
user_id,
|
||||
percent_change,
|
||||
Some(effective_change),
|
||||
)
|
||||
.unwrap_or(effective_change);
|
||||
effect_results.push(json!({
|
||||
"type": "money_change",
|
||||
"percent": percent_change,
|
||||
@@ -1030,19 +1049,18 @@ impl EventsWorker {
|
||||
conn: &mut DbConnection,
|
||||
user_id: i32,
|
||||
percent_change: f64,
|
||||
absolute_override: Option<f64>,
|
||||
) -> Result<f64, DbError> {
|
||||
let current_money = Self::get_current_money(conn, user_id)?;
|
||||
let change = current_money * (percent_change / 100.0);
|
||||
let change = absolute_override
|
||||
.unwrap_or_else(|| current_money * (percent_change / 100.0));
|
||||
let action = format!("Zufallsereignis: Geldänderung {:.2}%", percent_change);
|
||||
|
||||
// Verwende parametrisierte Queries für Sicherheit gegen SQL-Injection
|
||||
conn.prepare("update_money_event", QUERY_UPDATE_MONEY)?;
|
||||
let _ = conn.execute("update_money_event", &[&user_id, &change, &action])?;
|
||||
|
||||
// Best-effort money_history insert for UI/history visibility.
|
||||
let money_str = format!("{:.2}", change);
|
||||
fn escape_sql_literal(s: &str) -> String { s.replace('\'', "''") }
|
||||
let escaped_action = escape_sql_literal(&action);
|
||||
// money_history für UI/Verlauf: Betrag und Aktion zuverlässig speichern (parametrisiert).
|
||||
let create_sql = r#"
|
||||
CREATE TABLE IF NOT EXISTS falukant_log.money_history (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
@@ -1054,13 +1072,9 @@ impl EventsWorker {
|
||||
"#;
|
||||
let _ = conn.query(create_sql);
|
||||
|
||||
let history_sql = format!(
|
||||
"INSERT INTO falukant_log.money_history (user_id, change, action, created_at) VALUES ({uid}, {money}::numeric, '{act}', NOW());",
|
||||
uid = user_id,
|
||||
money = money_str,
|
||||
act = escaped_action
|
||||
);
|
||||
if let Err(err) = conn.query(&history_sql) {
|
||||
let money_str = format!("{:.2}", change);
|
||||
let _ = conn.prepare("insert_money_history", QUERY_INSERT_MONEY_HISTORY);
|
||||
if let Err(err) = conn.execute("insert_money_history", &[&user_id, &money_str, &action]) {
|
||||
eprintln!(
|
||||
"[EventsWorker] Warning: inserting money_history failed for user {}: {}",
|
||||
user_id, err
|
||||
|
||||
Reference in New Issue
Block a user