From 159040ec58dc459a81c4136a28fd31b21f51711e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 18 Jul 2020 01:20:09 +0100 Subject: [PATCH] wip saving --- src/error.rs | 2 ++ src/global.rs | 21 ++++++++++++++++++--- src/http.rs | 1 + src/imports.rs | 6 +++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/error.rs b/src/error.rs index 0f048895..380f5ed6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -26,6 +26,8 @@ pub enum OnlineError { JSONSerializeFailed(#[from] serde_json::error::Error), #[error("SVG processing/generation error {0:?}")] SVGProcessingFailed(#[from] SVGProcessingError), + #[error("IO error in server {0:?}")] + ServerIOError(#[from] io::Error), } pub use OnlineError::{NoClient,NoPlayer}; diff --git a/src/global.rs b/src/global.rs index c2fec9b0..35526835 100644 --- a/src/global.rs +++ b/src/global.rs @@ -2,6 +2,8 @@ use crate::imports::*; use lazy_static::lazy_static; +const SAVE_DIRECTORY : &str = "save"; + // ---------- newtypes and type aliases ---------- visible_slotmap_key!{ ClientId('C') } @@ -13,6 +15,7 @@ pub struct RawToken (pub String); #[derive(Debug)] pub struct Instance { + pub name : String, pub gs : GameState, pub clients : DenseSlotMap, pub updates : SecondarySlotMap, @@ -91,8 +94,9 @@ lazy_static! { impl Instance { #[throws(OE)] - pub fn new(gs: GameState) -> Instance { + pub fn new(gs: GameState, instance_name: String) -> Instance { Instance { + name : instance_name, gs, clients : Default::default(), updates : Default::default(), @@ -152,7 +156,18 @@ impl InstanceGuard<'_> { } #[throws(OE)] - fn save_game_now(&mut self) { eprintln!("xxx would save!"); } + fn save_game_now(&mut self) { + let savefile : String = + iter::once("g-") + .chain( utf8_percent_encode(&self.name, + &percent_encoding::NON_ALPHANUMERIC) ) + .chain( iter::once(".tmp") ) + .collect(); + let mut f = BufWriter::new(fs::File::create(&savefile)?); + rmp_serde::encode::write_named(&mut f, &self.ig.gs); + eprintln!("xxx saved {} to {}!", self.name, &savefile); + } + #[throws(OE)] fn save_access_now(&mut self) { eprintln!("xxx would save!"); } } @@ -222,7 +237,7 @@ const XXX_PLAYERS_TOKENS : &[(&str, &str)] = &[ #[throws(OE)] pub fn xxx_global_setup() { let gs = xxx_gamestate_init(); - let gi = Instance::new(gs)?; + let gi = Instance::new(gs, "dummy".to_string())?; let amu = Arc::new(Mutex::new(gi)); let mut ig = Instance::lock(&amu)?; for (token, nick) in XXX_PLAYERS_TOKENS { diff --git a/src/http.rs b/src/http.rs index 973b1516..974bdb74 100644 --- a/src/http.rs +++ b/src/http.rs @@ -15,6 +15,7 @@ impl<'r> Responder<'r> for OnlineError { use OnlineError::*; let status = match self { GameCorrupted | JSONSerializeFailed(_) | SVGProcessingFailed(_) + | ServerIOError(_) => Status::InternalServerError, NoClient | NoPlayer => Status::NotFound, InvalidZCoord => Status::BadRequest, diff --git a/src/imports.rs b/src/imports.rs index 472d02ae..7c90590e 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -1,6 +1,6 @@ pub use std::io; -pub use std::io::{BufReader,Read,Write}; +pub use std::io::{BufReader,Read,BufWriter,Write}; pub use std::fmt::Write as _; pub use std::fmt::Formatter; pub use std::fmt::{self,Display,Debug}; @@ -20,6 +20,7 @@ pub use std::cmp; pub use std::error::Error; pub use std::marker::PhantomData; pub use std::ops::{Deref,DerefMut}; +pub use std::fs; pub use thiserror::Error; pub use anyhow::{Context,anyhow}; @@ -31,6 +32,9 @@ pub use serde::{Serializer,Deserializer}; pub use rocket_contrib::helmet::*; pub use rocket_contrib::templates::Template; +pub use percent_encoding::utf8_percent_encode; +pub use percent_encoding::NON_ALPHANUMERIC; + pub use rocket::{State,Rocket}; pub use rocket::http::{RawStr,ContentType}; pub use rocket::request::{FromParam,FromRequest,FromFormValue,LenientForm}; -- 2.30.2