load level on server start if it exists, implementing #1

This commit is contained in:
Zoey 2024-04-23 09:30:32 -07:00
parent d179e10f53
commit bcb77ca194
No known key found for this signature in database
GPG key ID: 8611B896D1AAFAF2
2 changed files with 39 additions and 18 deletions

View file

@ -1,4 +1,4 @@
use std::collections::BTreeSet; use std::{collections::BTreeSet, path::Path};
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
@ -90,6 +90,26 @@ impl Level {
packets packets
} }
pub async fn save<P>(&self, path: P)
where
P: AsRef<Path>,
{
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<P>(path: P) -> Self
where
P: AsRef<Path>,
{
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 /// struct describing a block update for the level to handle

View file

@ -1,7 +1,7 @@
pub mod config; pub mod config;
mod network; mod network;
use std::sync::Arc; use std::{path::PathBuf, sync::Arc};
use tokio::{net::TcpListener, sync::RwLock}; use tokio::{net::TcpListener, sync::RwLock};
@ -19,6 +19,7 @@ use crate::{
use self::config::ServerConfig; use self::config::ServerConfig;
const TICK_DURATION: std::time::Duration = std::time::Duration::from_millis(50); const TICK_DURATION: std::time::Duration = std::time::Duration::from_millis(50);
const LEVEL_PATH: &str = "level.clw";
/// the server /// the server
#[derive(Debug)] #[derive(Debug)]
@ -49,6 +50,10 @@ pub struct ServerData {
impl Server { impl Server {
/// creates a new server with a generated level /// creates a new server with a generated level
pub async fn new(config: ServerConfig) -> std::io::Result<Self> { pub async fn new(config: ServerConfig) -> std::io::Result<Self> {
let level_path = PathBuf::from(LEVEL_PATH);
let level = if level_path.exists() {
Level::load(level_path).await
} else {
println!("generating level"); println!("generating level");
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let mut level = Level::new( let mut level = Level::new(
@ -58,6 +63,8 @@ impl Server {
); );
config.generation.generate(&mut level, &mut rng); config.generation.generate(&mut level, &mut rng);
println!("done!"); println!("done!");
level
};
Self::new_with_level(config, level).await 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 // TODO: cancel pending tasks/send out "Server is stopping" messages *here* instead of elsewhere
// rn the message isn't guaranteed to actually go out........ // rn the message isn't guaranteed to actually go out........
let data = self.data.read().await; self.data.read().await.level.save(LEVEL_PATH).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();
Ok(()) Ok(())
} }