Write stats to the DB when a player disconnects from the server.

This commit is contained in:
Shane Handley 2020-05-13 22:08:26 +10:00
parent e852e0cfab
commit fa8c6418f6
3 changed files with 34 additions and 19 deletions

View File

@ -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::<Player>().get(entity),
state.read_storage::<comp::Stats>().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);

View File

@ -4,22 +4,24 @@ use super::{establish_connection, models::StatsUpdate, schema};
use crate::comp;
use diesel::prelude::*;
pub fn update<'a>(updates: impl Iterator<Item = (i32, &'a comp::Stats)>) {
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<Item = (i32, &'a comp::Stats)>) {
let connection = &establish_connection();
updates.for_each(|(character_id, stats)| update(character_id, stats, Some(connection)));
}

View File

@ -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))),