From 41c0e5a6f2ee9ca137b84abe2bd3245167da7b71 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Sat, 6 Jun 2026 13:26:45 +0200 Subject: [PATCH] code fixes --- Cargo.lock | 2 +- src/worker/character_creation.rs | 21 +++++--------- src/worker/director.rs | 4 +-- src/worker/events.rs | 42 +++++++++++++-------------- src/worker/falukant_family.rs | 16 +++++----- src/worker/falukant_transport_raid.rs | 14 ++++----- src/worker/stockage_manager.rs | 10 ++----- src/worker/underground.rs | 29 +++++++++--------- src/worker/user_character.rs | 21 +++++--------- 9 files changed, 71 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fa1494..54941cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ "futures-util", "libsystemd", "postgres", - "rand 0.8.5", + "rand 0.9.2", "rustls-pemfile", "serde", "serde_json", diff --git a/src/worker/character_creation.rs b/src/worker/character_creation.rs index 4ec99e2..b9ebb64 100644 --- a/src/worker/character_creation.rs +++ b/src/worker/character_creation.rs @@ -1,8 +1,7 @@ use crate::db::{ConnectionPool, DbError, Rows}; use crate::message_broker::MessageBroker; -use rand::distributions::{Distribution, Uniform}; use rand::rngs::StdRng; -use rand::{thread_rng, Rng, SeedableRng}; +use rand::{Rng, SeedableRng}; use std::collections::{HashMap, HashSet}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -29,7 +28,6 @@ use crate::worker::sql::{ pub struct CharacterCreationWorker { pub(crate) base: BaseWorker, rng: StdRng, - dist: Uniform, first_name_cache: HashMap>, last_name_cache: HashSet, death_check_running: Arc, @@ -46,8 +44,8 @@ impl CharacterCreationWorker { /// Interner Konstruktor, der optional den NPC-Todes-Monitor startet. fn new_internal(pool: ConnectionPool, broker: MessageBroker, start_death_thread: bool) -> Self { let base = BaseWorker::new("CharacterCreationWorker", pool.clone(), broker.clone()); - let rng = StdRng::from_entropy(); - let dist = Uniform::from(2..=3); + let mut base_rng = rand::rng(); + let rng = StdRng::from_rng(&mut base_rng); let death_check_running = Arc::new(AtomicBool::new(start_death_thread)); let death_thread = if start_death_thread { @@ -80,7 +78,6 @@ impl CharacterCreationWorker { Self { base, rng, - dist, first_name_cache: HashMap::new(), last_name_cache: HashSet::new(), death_check_running, @@ -139,7 +136,7 @@ impl CharacterCreationWorker { for &nobility in &nobility_stands { for &gender in &genders { - let num_chars = self.rng.sample(self.dist); + let num_chars = self.rng.random_range(2..=3); for _ in 0..num_chars { self.create_character(region_id, gender, nobility); } @@ -248,8 +245,8 @@ impl CharacterCreationWorker { if set.is_empty() { return -1; } - let mut rng = thread_rng(); - let idx = rng.gen_range(0..set.len()); + let mut rng = rand::rng(); + let idx = rng.random_range(0..set.len()); *set.iter().nth(idx).unwrap_or(&-1) } @@ -390,9 +387,8 @@ impl CharacterCreationWorker { let death_probability = base_probability + increase_per_year * (age.saturating_sub(60) as f64); - let mut rng = thread_rng(); - let dist = Uniform::from(0.0..1.0); - let roll: f64 = dist.sample(&mut rng); + let mut rng = rand::rng(); + let roll: f64 = rng.random_range(0.0..1.0); roll < death_probability } @@ -537,4 +533,3 @@ impl CharacterCreationWorker { } } - diff --git a/src/worker/director.rs b/src/worker/director.rs index 2ae5e5d..21f8e96 100644 --- a/src/worker/director.rs +++ b/src/worker/director.rs @@ -193,7 +193,7 @@ impl DirectorWorker { .filter_map(Self::map_row_to_resignation_candidate) .collect(); - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); for candidate in candidates { let sat = candidate.satisfaction.clamp(0, 100) as f64; let resignation_probability = 1.0 - (sat / 100.0); @@ -214,7 +214,7 @@ impl DirectorWorker { ); let _ = conn.execute("insert_notification", &[&candidate.employer_user_id, &payload]); } - let roll: f64 = rng.gen_range(0.0..1.0); + let roll: f64 = rng.random_range(0.0..1.0); if roll >= resignation_probability { continue; } diff --git a/src/worker/events.rs b/src/worker/events.rs index 82eae98..d217e30 100644 --- a/src/worker/events.rs +++ b/src/worker/events.rs @@ -1,7 +1,7 @@ use crate::db::{ConnectionPool, DbConnection, DbError}; use crate::message_broker::MessageBroker; use rand::Rng; -use rand::seq::SliceRandom; +use rand::prelude::SliceRandom; use serde_json::json; use std::sync::atomic::Ordering; use std::sync::Arc; @@ -447,7 +447,7 @@ impl EventsWorker { fn run_loop(pool: ConnectionPool, broker: MessageBroker, state: Arc) { let mut last_event_check = None; - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); let events = Self::initialize_events(); loop { @@ -502,7 +502,7 @@ impl EventsWorker { // Prüfe jedes mögliche Ereignis for event in events { // Zufällige Prüfung basierend auf Wahrscheinlichkeit - let roll = rng.gen_range(0.0..=1.0); + let roll = rng.random_range(0.0..=1.0); let effective_prob = event.probability_per_minute * Self::EVENT_RATE_SCALE; if roll < effective_prob { eprintln!( @@ -560,7 +560,7 @@ impl EventsWorker { // Wende Effekte an let mut effect_results = Vec::new(); for effect in &event.effects { - let effect_roll = rng.gen_range(0.0..=1.0); + let effect_roll = rng.random_range(0.0..=1.0); match effect { EventEffect::MoneyChange { probability, @@ -750,7 +750,7 @@ impl EventsWorker { // Wende Effekte an (in diesem Fall nur CharacterDeath) let mut effect_results = Vec::new(); for effect in &event.effects { - let effect_roll = rng.gen_range(0.0..=1.0); + let effect_roll = rng.random_range(0.0..=1.0); match effect { EventEffect::CharacterDeath { probability } => { if effect_roll < *probability @@ -835,7 +835,7 @@ impl EventsWorker { let mut price_change_note: Option = None; let mut production_quality_note: Option = None; for effect in &event.effects { - let effect_roll = rng.gen_range(0.0..=1.0); + let effect_roll = rng.random_range(0.0..=1.0); match effect { EventEffect::WeatherChange { probability } => { if effect_roll < *probability { @@ -851,7 +851,7 @@ impl EventsWorker { max_change, } => { if effect_roll < *probability { - let change = rng.gen_range(*min_change..=*max_change); + let change = rng.random_range(*min_change..=*max_change); Self::apply_production_quality_change(&mut conn, region_id, change)?; effect_results.push(json!({ "type": "production_quality_change", @@ -879,7 +879,7 @@ impl EventsWorker { max_percent, } => { if effect_roll < *probability { - let percent_change = rng.gen_range(*min_percent..=*max_percent); + let percent_change = rng.random_range(*min_percent..=*max_percent); Self::apply_price_change(&mut conn, region_id, percent_change)?; effect_results.push(json!({ "type": "price_change", @@ -907,7 +907,7 @@ impl EventsWorker { max_percent, } => { if effect_roll < *probability { - let percent_change = rng.gen_range(*min_percent..=*max_percent); + let percent_change = rng.random_range(*min_percent..=*max_percent); Self::apply_transport_speed_change(&mut conn, region_id, percent_change)?; effect_results.push(json!({ "type": "transport_speed_change", @@ -1218,7 +1218,7 @@ impl EventsWorker { } // Berechne die prozentuale Änderung - let percent_change = rng.gen_range(min_percent..=max_percent); + let percent_change = rng.random_range(min_percent..=max_percent); // Reduziere die Kapazität aller Stocks conn.prepare("update_stock_capacity_regional", QUERY_UPDATE_STOCK_CAPACITY_REGIONAL)?; @@ -1283,7 +1283,7 @@ impl EventsWorker { } // Berechne die Änderung - let quality_change = rng.gen_range(min_change..=max_change); + let quality_change = rng.random_range(min_change..=max_change); // Reduziere die Qualität aller Häuser conn.prepare("update_house_quality", QUERY_UPDATE_HOUSE_QUALITY)?; @@ -1393,7 +1393,7 @@ impl EventsWorker { // Spezialfall: Unerwarteter Geldsegen -> absoluter Zufallsbetrag 1..500 if event.id == "windfall" { - let absolute_change: f64 = rng.gen_range(1.0..=500.0); + let absolute_change: f64 = rng.random_range(1.0..=500.0); let percent_change = if current_money > 0.0 { (absolute_change / current_money) * 100.0 } else { @@ -1430,7 +1430,7 @@ impl EventsWorker { return Ok(None); } - let loss: f64 = rng.gen_range(1.0..=max_loss); + let loss: f64 = rng.random_range(1.0..=max_loss); let percent_change = -(loss / current_money) * 100.0; let absolute_change = -loss; @@ -1456,7 +1456,7 @@ impl EventsWorker { } // Standardfall: prozentuale Änderung, optional mit Mindestbetrag für positive Änderungen - let percent_change = rng.gen_range(min_percent..=max_percent); + let percent_change = rng.random_range(min_percent..=max_percent); let computed_change = current_money * (percent_change / 100.0); let effective_change = match min_absolute_positive { Some(min_abs) if percent_change > 0.0 && computed_change < *min_abs => *min_abs, @@ -1491,7 +1491,7 @@ impl EventsWorker { return Ok(None); } - let percent_change = rng.gen_range(min_percent..=max_percent); + let percent_change = rng.random_range(min_percent..=max_percent); Self::apply_storage_capacity_change(conn, user_id, percent_change)?; Ok(Some(json!({ @@ -1744,7 +1744,7 @@ impl EventsWorker { .and_then(|v| v.parse::().ok()) .unwrap_or(100); - let health_change = rng.gen_range(min_change..=max_change); + let health_change = rng.random_range(min_change..=max_change); // Durch Unfälle/Krankheiten soll Gesundheit von Spieler-Charakteren nicht auf 0 fallen let new_health = (current_health + health_change).clamp(1, 100); @@ -1816,7 +1816,7 @@ impl EventsWorker { .and_then(|v| v.parse::().ok()) .unwrap_or(100); - let health_change = rng.gen_range(min_change..=max_change); + let health_change = rng.random_range(min_change..=max_change); let user_id: Option = row .get("user_id") .and_then(|v| v.parse::().ok()); @@ -2235,9 +2235,9 @@ impl EventsWorker { // 3. Berechne Schäden let inventory_damage_percent = - rng.gen_range(params.inventory_damage_min_percent..=params.inventory_damage_max_percent); + rng.random_range(params.inventory_damage_min_percent..=params.inventory_damage_max_percent); let storage_destruction_percent = - rng.gen_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent); + rng.random_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent); let total_stocks = stock_rows.len(); let stocks_to_destroy_requested = ((total_stocks as f64 * storage_destruction_percent / 100.0) @@ -2455,9 +2455,9 @@ impl EventsWorker { // 3. Berechne Schäden let inventory_damage_percent = - rng.gen_range(params.inventory_damage_min_percent..=params.inventory_damage_max_percent); + rng.random_range(params.inventory_damage_min_percent..=params.inventory_damage_max_percent); let storage_destruction_percent = - rng.gen_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent); + rng.random_range(params.storage_destruction_min_percent..=params.storage_destruction_max_percent); let total_stocks = stock_rows.len(); let stocks_to_destroy_requested = ((total_stocks as f64 * storage_destruction_percent / 100.0) diff --git a/src/worker/falukant_family.rs b/src/worker/falukant_family.rs index 87f4cff..dfa8f80 100644 --- a/src/worker/falukant_family.rs +++ b/src/worker/falukant_family.rs @@ -12,9 +12,8 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::{Duration, Instant}; -use rand::distributions::{Distribution, Uniform}; use rand::rngs::StdRng; -use rand::SeedableRng; +use rand::{Rng, SeedableRng}; use super::base::{BaseWorker, Worker, WorkerState}; use super::sql::{ @@ -46,7 +45,6 @@ const GAME_MONTH_SLICE_INTERVAL: Duration = Duration::from_secs(2 * 3600); pub struct FalukantFamilyWorker { base: BaseWorker, rng: StdRng, - dist: Uniform, last_daily: Option, last_monthly: Option, /// Gemeinsamer Tick für Liebschafts-Raten + Dienerschaft (Monatstick ≈ 2 h). @@ -63,8 +61,10 @@ impl FalukantFamilyWorker { pub fn new(pool: ConnectionPool, broker: MessageBroker) -> Self { Self { base: BaseWorker::new("FalukantFamilyWorker", pool, broker), - rng: StdRng::from_entropy(), - dist: Uniform::from(0.0..1.0), + rng: { + let mut base_rng = rand::rng(); + StdRng::from_rng(&mut base_rng) + }, last_daily: None, last_monthly: None, last_game_month_slice: None, @@ -361,7 +361,7 @@ impl FalukantFamilyWorker { } } } - if breakup_risk_pct > 0.0 && self.dist.sample(&mut self.rng) * 100.0 < breakup_risk_pct { + if breakup_risk_pct > 0.0 && self.rng.random_range(0.0..1.0) * 100.0 < breakup_risk_pct { conn.execute("deactivate_lover", &[&l.rel_id])?; ended_rel_ids.insert(l.rel_id); push_user_id(&mut breakup_socket_users, l.user1_id); @@ -676,7 +676,7 @@ impl FalukantFamilyWorker { p -= 2.0; } p = p.clamp(0.0, 25.0); - if self.dist.sample(&mut self.rng) * 100.0 < p { + if self.rng.random_range(0.0..1.0) * 100.0 < p { self.base.broker.publish(format!( r#"{{"event":"falukant_family_scandal_hint","relationship_id":{}}}"#, l.rel_id @@ -709,7 +709,7 @@ impl FalukantFamilyWorker { } let mut rng_malus_cids: Vec = Vec::new(); for cid in unique_cids.iter().copied() { - let r = self.dist.sample(&mut self.rng) * 100.0; + let r = self.rng.random_range(0.0..1.0) * 100.0; let malus = if r < 1.0 { -5.0 } else if r < 3.0 { diff --git a/src/worker/falukant_transport_raid.rs b/src/worker/falukant_transport_raid.rs index 4be6dc5..37eb90e 100644 --- a/src/worker/falukant_transport_raid.rs +++ b/src/worker/falukant_transport_raid.rs @@ -177,19 +177,19 @@ fn try_resolve_one_raid( return Ok(()); } - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); // Begegnung (Bande + Sichtbarkeit großer Ladung) let visibility_penalty = ((transport_size as f64 / vehicle_cap as f64).min(2.0) - 1.0) * 0.04; let encounter_p = (0.08_f64 + band_size as f64 * 0.012 + visibility_penalty).clamp(0.05, 0.45); - if !rng.gen_bool(encounter_p) { + if !rng.random_bool(encounter_p) { return Ok(()); } // Kampf - let raid_power = band_size + rng.gen_range(0..=band_size); + let raid_power = band_size + rng.random_range(0..=band_size); let gmax = guard_count.max(1); - let guard_power = guard_count + rng.gen_range(0..=gmax); + let guard_power = guard_count + rng.random_range(0..=gmax); let outcome = if raid_power > (guard_power as f64 * 1.25) as i32 { "major_success" @@ -218,15 +218,15 @@ fn try_resolve_one_raid( // Beuteanteil (nie Totalverlust) let base_loot = match outcome { - "major_success" => rng.gen_range(0.35..0.60), - _ => rng.gen_range(0.15..0.45), + "major_success" => rng.random_range(0.35..0.60), + _ => rng.random_range(0.15..0.45), }; let guard_mul = (1.0_f64 - 0.05_f64 * (guard_count.min(12) as f64)).max(0.35); let loot_share = (base_loot * guard_mul).clamp(0.05, 0.55); let mut stolen = ((transport_size as f64) * loot_share).floor() as i32; stolen = stolen.clamp(1, transport_size - 1); - let carry_loss = rng.gen_range(0.65..0.90); + let carry_loss = rng.random_range(0.65..0.90); let mut to_store = (stolen as f64 * carry_loss).floor() as i32; to_store = to_store.max(0).min(stolen); diff --git a/src/worker/stockage_manager.rs b/src/worker/stockage_manager.rs index 9677c05..927fc39 100644 --- a/src/worker/stockage_manager.rs +++ b/src/worker/stockage_manager.rs @@ -1,8 +1,6 @@ use crate::db::{ConnectionPool, DbError}; use crate::message_broker::MessageBroker; -use rand::distributions::{Distribution, Uniform}; -use rand::rngs::StdRng; -use rand::SeedableRng; +use rand::Rng; use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::{Duration, Instant}; @@ -64,8 +62,7 @@ impl StockageManager { } fn add_local_stocks(pool: &ConnectionPool, broker: &MessageBroker) -> Result<(), DbError> { - let mut rng = StdRng::from_entropy(); - let dist = Uniform::from(0.0..1.0); + let mut rng = rand::rng(); let town_ids = Self::get_town_ids(pool)?; eprintln!("[StockageManager] Prüfe {} Städte auf neue Lager", town_ids.len()); @@ -76,7 +73,7 @@ impl StockageManager { // Das bedeutet: 2/217 ≈ 0.92% pro Stadt pro Durchlauf // Pro Tag (1440 Durchläufe): ~73% Chance pro Stadt // Erhöht von 2/2161 (0.0926%) auf 2/217 (0.92%) = 10x höher - let roll: f64 = dist.sample(&mut rng) * 216.0_f64; + let roll: f64 = rng.random_range(0.0..1.0) * 216.0_f64; let chance = roll.round(); if chance <= 1.0 { eprintln!("[StockageManager] Erstelle Lager für Stadt {}", town_id); @@ -185,4 +182,3 @@ impl Worker for StockageManager { } } - diff --git a/src/worker/underground.rs b/src/worker/underground.rs index 07c6e8b..e394c37 100644 --- a/src/worker/underground.rs +++ b/src/worker/underground.rs @@ -1,7 +1,6 @@ use crate::db::{ConnectionPool, DbError, Row, Rows}; use crate::message_broker::MessageBroker; -use rand::distributions::{Distribution, Uniform}; -use rand::seq::SliceRandom; +use rand::prelude::{IndexedRandom, SliceRandom}; use rand::Rng; use serde_json::json; use serde_json::Value as Json; @@ -388,9 +387,8 @@ impl UndergroundWorker { } let current = parse_i32(&rows[0], "health", 0); - let mut rng = rand::thread_rng(); - let dist = Uniform::from(0..=current.max(0)); - let new_health = dist.sample(&mut rng); + let mut rng = rand::rng(); + let new_health = rng.random_range(0..=current.max(0)); conn.execute("ug_update_char_health", &[&victim_id, &new_health])?; @@ -705,7 +703,7 @@ impl UndergroundWorker { })); } - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); let mut to_remove = random_ll(1, cap); rows.shuffle(&mut rng); @@ -867,7 +865,7 @@ impl UndergroundWorker { let cap = max(1_i64, total / 2); let mut to_remove = random_ll(1, cap); - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); rows.shuffle(&mut rng); let mut affected = Vec::new(); @@ -1107,7 +1105,7 @@ impl UndergroundWorker { } let pick = *best_indices .as_slice() - .choose(&mut rand::thread_rng()) + .choose(&mut rand::rng()) .unwrap_or(&scored[0].1); let target = &lover_rows[pick]; @@ -1542,18 +1540,18 @@ fn parse_opt_i32(row: &Row, key: &str) -> Option { // Hilfsfunktionen für Zufall und Parsing fn random_int(lo: i32, hi: i32) -> i32 { - let mut rng = rand::thread_rng(); - rng.gen_range(lo..=hi) + let mut rng = rand::rng(); + rng.random_range(lo..=hi) } fn random_ll(lo: i64, hi: i64) -> i64 { - let mut rng = rand::thread_rng(); - rng.gen_range(lo..=hi) + let mut rng = rand::rng(); + rng.random_range(lo..=hi) } fn random_indices(n: usize, k: usize) -> Vec { let mut idx: Vec = (0..n).collect(); - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); idx.shuffle(&mut rng); if k < idx.len() { idx.truncate(k); @@ -1562,8 +1560,8 @@ fn random_indices(n: usize, k: usize) -> Vec { } fn random_double(lo: f64, hi: f64) -> f64 { - let mut rng = rand::thread_rng(); - rng.gen_range(lo..hi) + let mut rng = rand::rng(); + rng.random_range(lo..hi) } fn parse_i32(row: &Row, key: &str, default: i32) -> i32 { @@ -1620,4 +1618,3 @@ fn change_falukant_user_money( Ok(()) } - diff --git a/src/worker/user_character.rs b/src/worker/user_character.rs index 0dd78f5..e7d18f3 100644 --- a/src/worker/user_character.rs +++ b/src/worker/user_character.rs @@ -1,9 +1,8 @@ use crate::db::{ConnectionPool, DbError, Rows}; use crate::message_broker::MessageBroker; use chrono::{Local, NaiveDate}; -use rand::distributions::{Distribution, Uniform}; use rand::rngs::StdRng; -use rand::SeedableRng; +use rand::{Rng, SeedableRng}; use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::{Duration, Instant}; @@ -68,7 +67,6 @@ struct Character { pub struct UserCharacterWorker { base: BaseWorker, rng: StdRng, - dist: Uniform, last_hourly_run: Option, last_pregnancy_run: Option, /// Letzter Kalendertag, an dem Ehe-Konzeption (oder Legacy-Instant) gelaufen ist — höchstens 1×/Tag. @@ -86,13 +84,12 @@ pub struct UserCharacterWorker { impl UserCharacterWorker { pub fn new(pool: ConnectionPool, broker: MessageBroker) -> Self { let base = BaseWorker::new("UserCharacterWorker", pool, broker); - let rng = StdRng::from_entropy(); - let dist = Uniform::from(0.0..1.0); + let mut base_rng = rand::rng(); + let rng = StdRng::from_rng(&mut base_rng); Self { base, rng, - dist, last_hourly_run: None, last_pregnancy_run: None, last_marriage_fertility_date: None, @@ -301,15 +298,14 @@ impl UserCharacterWorker { if age >= 45 { let probability = (0.1 + (age - 45) as f64 * 0.02).min(1.0); - if self.dist.sample(&mut self.rng) < probability { - let damage_dist = Uniform::from(1..=10); - return -damage_dist.sample(&mut self.rng); + if self.rng.random_range(0.0..1.0) < probability { + return -self.rng.random_range(1..=10); } return 0; } let probability = (age - 30) as f64 / 30.0; - if self.dist.sample(&mut self.rng) < probability { + if self.rng.random_range(0.0..1.0) < probability { -1 } else { 0 @@ -686,7 +682,7 @@ impl UserCharacterWorker { .filter(|s| !s.is_empty()) .unwrap_or("marriage"); - let gender = if self.dist.sample(&mut self.rng) < 0.5 { + let gender = if self.rng.random_range(0.0..1.0) < 0.5 { "male" } else { "female" @@ -741,7 +737,7 @@ impl UserCharacterWorker { return Ok(()); } - let gender = if self.dist.sample(&mut self.rng) < 0.5 { + let gender = if self.rng.random_range(0.0..1.0) < 0.5 { "male" } else { "female" @@ -1263,4 +1259,3 @@ impl Worker for UserCharacterWorker { } } -