diff --git a/src/level.rs b/src/level.rs index 3b809a4..5c8a953 100644 --- a/src/level.rs +++ b/src/level.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use std::{collections::BTreeSet, path::Path}; use bincode::{Decode, Encode}; @@ -90,6 +90,26 @@ impl Level { packets } + + pub async fn save

(&self, path: P) + where + P: AsRef, + { + let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::best()); + bincode::encode_into_std_write(self, &mut encoder, bincode::config::standard()).unwrap(); + tokio::fs::write(path, encoder.finish().unwrap()) + .await + .unwrap(); + } + + pub async fn load

(path: P) -> Self + where + P: AsRef, + { + let data = tokio::fs::read(path).await.unwrap(); + let mut decoder = flate2::read::GzDecoder::new(data.as_slice()); + bincode::decode_from_std_read(&mut decoder, bincode::config::standard()).unwrap() + } } /// struct describing a block update for the level to handle diff --git a/src/server.rs b/src/server.rs index a7cf90d..f90c269 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,7 +1,7 @@ pub mod config; mod network; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::{net::TcpListener, sync::RwLock}; @@ -19,6 +19,7 @@ use crate::{ use self::config::ServerConfig; const TICK_DURATION: std::time::Duration = std::time::Duration::from_millis(50); +const LEVEL_PATH: &str = "level.clw"; /// the server #[derive(Debug)] @@ -49,15 +50,21 @@ pub struct ServerData { impl Server { /// creates a new server with a generated level pub async fn new(config: ServerConfig) -> std::io::Result { - println!("generating level"); - let mut rng = rand::thread_rng(); - let mut level = Level::new( - config.level_size.x, - config.level_size.y, - config.level_size.z, - ); - config.generation.generate(&mut level, &mut rng); - println!("done!"); + let level_path = PathBuf::from(LEVEL_PATH); + let level = if level_path.exists() { + Level::load(level_path).await + } else { + println!("generating level"); + let mut rng = rand::thread_rng(); + let mut level = Level::new( + config.level_size.x, + config.level_size.y, + config.level_size.z, + ); + config.generation.generate(&mut level, &mut rng); + println!("done!"); + level + }; Self::new_with_level(config, level).await } @@ -100,13 +107,7 @@ impl Server { // TODO: cancel pending tasks/send out "Server is stopping" messages *here* instead of elsewhere // rn the message isn't guaranteed to actually go out........ - let data = self.data.read().await; - let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::best()); - bincode::encode_into_std_write(&data.level, &mut encoder, bincode::config::standard()) - .unwrap(); - tokio::fs::write("level.clw", encoder.finish().unwrap()) - .await - .unwrap(); + self.data.read().await.level.save(LEVEL_PATH).await; Ok(()) }