From: Ian Jackson Date: Sun, 19 Jul 2020 00:55:19 +0000 (+0100) Subject: wip decode X-Git-Tag: otter-0.2.0~1289 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=b94214fad85dea6aa722435dae7f8b2c6a4791bf;p=otter.git wip decode --- diff --git a/src/error.rs b/src/error.rs index aed9e296..3d1ca073 100644 --- a/src/error.rs +++ b/src/error.rs @@ -30,6 +30,8 @@ pub enum OnlineError { ServerIOError(#[from] io::Error), #[error("Server MessagePack encoding error {0:?}")] ServerMessagePackEncodeFail(#[from] rmp_serde::encode::Error), + #[error("Server MessagePack decoding error (game load failed) {0:?}")] + ServerMessagePackDecodeFail(#[from] rmp_serde::decode::Error), } pub use OnlineError::{NoClient,NoPlayer}; diff --git a/src/global.rs b/src/global.rs index 2d34cbfd..22988a39 100644 --- a/src/global.rs +++ b/src/global.rs @@ -50,9 +50,8 @@ pub struct TokenRegistry { } #[derive(Debug,Serialize,Deserialize)] -struct InstanceSaveAccesses<'r> { - #[serde(borrow)] - tokens_players : Vec<(&'r str, PlayerId)>, +struct InstanceSaveAccesses { + tokens_players : Vec<(RawTokenStr, PlayerId)>, } // ---------- API ---------- @@ -162,9 +161,9 @@ impl InstanceGuard<'_> { for t in tokens.tr.drain() { global.remove(&t); } } - fn savefile(&self, prefix: &str, suffix: &str) -> String { + fn savefile(name: &str, prefix: &str, suffix: &str) -> String { iter::once(prefix) - .chain( utf8_percent_encode(&self.name, + .chain( utf8_percent_encode(name, &percent_encoding::NON_ALPHANUMERIC) ) .chain( iter::once(suffix) ) .collect() @@ -175,14 +174,14 @@ impl InstanceGuard<'_> { w: fn(s: &Self, w: &mut BufWriter) -> Result<(),rmp_serde::encode::Error> ) { - let tmp = self.savefile(prefix,".tmp"); + let tmp = Self::savefile(&self.name, prefix,".tmp"); let mut f = BufWriter::new(fs::File::create(&tmp)?); w(self, &mut f)?; f.flush()?; drop( f.into_inner().map_err(|e| { let e : io::Error = e.into(); e })? ); - let out = self.savefile(prefix,""); + let out = Self::savefile(&self.name, prefix,""); fs::rename(&tmp, &out)?; - eprintln!("xxx saved {} to {}!", self.name, &out); + eprintln!("saved to {}", &out); } #[throws(OE)] @@ -193,7 +192,33 @@ impl InstanceGuard<'_> { } #[throws(OE)] - fn save_access_now(&mut self) { eprintln!("xxx would save!"); } + fn save_access_now(&mut self) { + self.save_something("a-", |s,w| { + let global_players = GLOBAL.players.read().unwrap(); + let tokens_players : Vec<(&str, PlayerId)> = + s.ig.tokens_players.tr + .iter() + .map(|token| + global_players.get(token) + .map(|player| (token.0.as_str(), player.ident))) + .flatten() + .collect(); + let isa = InstanceSaveAccesses { tokens_players }; + rmp_serde::encode::write_named(w, &isa) + })?; + } + + #[throws(OE)] + fn load_something(name: &str, prefix: &str) -> T { + let inp = Self::savefile(name, prefix, ""); + let mut f = BufReader::new(fs::File::open(&inp)?); + rmp_serde::decode::from_read(&mut f)? + } +/* + pub fn load(instance_name: String) -> Arc> { + let gs = Self::savefile(&instance_name,"g-"); + + }*/ } // ---------- Lookup and token API ---------- diff --git a/src/http.rs b/src/http.rs index d03ef869..9a4efc5e 100644 --- a/src/http.rs +++ b/src/http.rs @@ -15,7 +15,9 @@ impl<'r> Responder<'r> for OnlineError { use OnlineError::*; let status = match self { GameCorrupted | JSONSerializeFailed(_) | SVGProcessingFailed(_) - | ServerIOError(_) | ServerMessagePackEncodeFail(_) + | ServerIOError(_) + | ServerMessagePackEncodeFail(_) + | ServerMessagePackDecodeFail(_) => Status::InternalServerError, NoClient | NoPlayer => Status::NotFound, InvalidZCoord => Status::BadRequest, diff --git a/src/imports.rs b/src/imports.rs index 8948593d..a249c9c4 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -26,7 +26,7 @@ pub use thiserror::Error; pub use anyhow::{Context,anyhow}; pub use fehler::{throws,throw}; -pub use serde::{Serialize,Deserialize}; +pub use serde::{Serialize,Deserialize,de::DeserializeOwned}; pub use serde::{Serializer,Deserializer}; pub use rocket_contrib::helmet::*;