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(())
}