chiark / gitweb /
wip saving
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 18 Jul 2020 00:20:09 +0000 (01:20 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 18 Jul 2020 00:20:09 +0000 (01:20 +0100)
src/error.rs
src/global.rs
src/http.rs
src/imports.rs

index 0f048895f5217bc373fed3de65e774bcb4016f88..380f5ed697d779403c76f0a17fcaecec08c01986 100644 (file)
@@ -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};
index c2fec9b0ebc0e451326e8aaafd698e671dd3689f..35526835d9033e8398104be2e7c91100d3da9af2 100644 (file)
@@ -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<ClientId,Client>,
   pub updates : SecondarySlotMap<PlayerId, PlayerUpdates>,
@@ -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 {
index 973b15163ecaedb46b78297e35e351324ecbeb62..974bdb742de49f0dc88ac022ac36df7cc95bbd33 100644 (file)
@@ -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,
index 472d02ae83ac9972d648ba2c187f185ea6d37a7c..7c90590eb17b22c9a02de604db02349028ae64a2 100644 (file)
@@ -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};