diff --git a/server/src/events/player.rs b/server/src/events/player.rs index b4836a7505..770666b246 100644 --- a/server/src/events/player.rs +++ b/server/src/events/player.rs @@ -1,5 +1,7 @@ use super::Event; -use crate::{auth_provider::AuthProvider, client::Client, state_ext::StateExt, Server}; +use crate::{ + auth_provider::AuthProvider, client::Client, persistence, state_ext::StateExt, Server, +}; use common::{ comp, comp::Player, @@ -68,6 +70,17 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event } } } + + // Sync the player's character data to the database + if let (Some(player), Some(stats)) = ( + state.read_storage::().get(entity), + state.read_storage::().get(entity), + ) { + if let Some(character_id) = player.character_id { + persistence::stats::update(character_id, stats, None); + } + } + // Delete client entity if let Err(err) = state.delete_entity_recorded(entity) { error!("Failed to delete disconnected client: {:?}", err); diff --git a/server/src/persistence/stats.rs b/server/src/persistence/stats.rs index ee87315962..3faa77b7f5 100644 --- a/server/src/persistence/stats.rs +++ b/server/src/persistence/stats.rs @@ -4,22 +4,24 @@ use super::{establish_connection, models::StatsUpdate, schema}; use crate::comp; use diesel::prelude::*; -pub fn update<'a>(updates: impl Iterator) { - use schema::stats; +pub fn update(character_id: i32, stats: &comp::Stats, conn: Option<&SqliteConnection>) { + log::warn!("stats persisting..."); - let connection = establish_connection(); - - updates.for_each(|(character_id, stats)| { - if let Err(error) = - diesel::update(stats::table.filter(schema::stats::character_id.eq(character_id))) - .set(&StatsUpdate::from(stats)) - .execute(&connection) - { - log::warn!( - "Failed to update stats for character: {:?}: {:?}", - character_id, - error - ) - } - }); + if let Err(error) = + diesel::update(schema::stats::table.filter(schema::stats::character_id.eq(character_id))) + .set(&StatsUpdate::from(stats)) + .execute(conn.unwrap_or(&establish_connection())) + { + log::warn!( + "Failed to update stats for character: {:?}: {:?}", + character_id, + error + ) + } +} + +pub fn batch_update<'a>(updates: impl Iterator) { + let connection = &establish_connection(); + + updates.for_each(|(character_id, stats)| update(character_id, stats, Some(connection))); } diff --git a/server/src/sys/persistence/stats.rs b/server/src/sys/persistence/stats.rs index 9f0d9ce3c0..0c633bedfd 100644 --- a/server/src/sys/persistence/stats.rs +++ b/server/src/sys/persistence/stats.rs @@ -19,7 +19,7 @@ impl<'a> System<'a> for Sys { if scheduler.should_run() { timer.start(); - stats::update( + stats::batch_update( (&players, &player_stats) .join() .filter_map(|(player, stats)| player.character_id.map(|id| (id, stats))),