From: Ian Jackson Date: Thu, 29 Apr 2021 00:43:38 +0000 (+0100) Subject: Move game spec parsing from client to server X-Git-Tag: otter-0.6.0~497 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=d8bac290293841c2f05b191e5cd08ee8613e53c9;p=otter.git Move game spec parsing from client to server Signed-off-by: Ian Jackson --- diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 92bc1f6e..baa99474 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -451,6 +451,35 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>( no_updates(ig, MGR::Fine) }, + MGI::ResetFromGameSpec { spec_toml: spec } => { + let ig = cs.check_acl(&ag, ig, PCH::Instance, &[TP::ChangePieces])?.0; + let spec: toml::Value = spec.parse() + .map_err(|e: toml::de::Error| ME::TomlSyntaxError(e.to_string()))?; + let GameSpec { + pieces, table_size, table_colour, pcaliases, + } = toml_de::from_value(&spec) + .map_err(|e: toml_de::Error| ME::TomlStructureError(e.to_string()))?; + let mut insns = vec![]; + for piece in ig.gs.pieces.keys() { + insns.push(MGI::DeletePiece(piece)); + } + for (alias, target) in pcaliases.into_iter() { + insns.push(MGI::DefinePieceAlias{ alias, target }); + } + insns.push(MGI::ClearLog); + insns.push(MGI::SetTableSize(table_size)); + insns.push(MGI::SetTableColour(table_colour)); + for pspec in pieces.into_iter() { + insns.push(MGI::AddPieces(pspec)); + } + let html = hformat!("{} reset the game", &who); + (U{ pcs: vec![], + log: vec![ LogEntry { html } ], + raw: None }, + MGR::InsnExpanded, + None, insns, ig) + } + MGI::InsnMark(token) => { let (ig, _) = cs.check_acl(&ag,ig,PCH::Instance, &[TP::TestExistence])?; no_updates(ig, MGR::InsnMark(token)) diff --git a/src/bin/otter.rs b/src/bin/otter.rs index 91cae8bb..e10ee880 100644 --- a/src/bin/otter.rs +++ b/src/bin/otter.rs @@ -575,7 +575,6 @@ impl SpecParse for SpecParseToml { } } impl SpecParseToml { pub fn new() -> Self { Self(default()) } } -#[allow(dead_code)] struct SpecRaw(pub PhantomData); impl SpecParse for SpecRaw { type T = String; @@ -583,7 +582,6 @@ impl SpecParse for SpecRaw { #[throws(AE)] fn parse(buf: String) -> String { buf } } -#[allow(dead_code)] impl SpecRaw { pub fn new() -> Self { Self(default()) } } #[throws(AE)] @@ -696,12 +694,8 @@ mod reset_game { instance_name.clone(), MgmtGameUpdateMode::Bulk, ); - let GameSpec { - table_size, - pieces, - table_colour, - pcaliases, - } = read_spec(&ma, &args.game_file, SpecParseToml::new())?; + let spec_toml = read_spec(&ma, &args.game_file, + SpecRaw::::new())?; let mut insns = vec![]; @@ -721,25 +715,7 @@ mod reset_game { insns.extend(setup_table(&ma, &instance_name, &table_spec)?); } - let (pcs, aliases) = chan.list_pieces()?; - for p in pcs { - insns.push(MgmtGameInstruction::DeletePiece(p.piece)); - } - for p in aliases { - insns.push(MgmtGameInstruction::DeletePieceAlias(p)); - } - - for (alias, target) in pcaliases.into_iter() { - insns.push(MGI::DefinePieceAlias{ alias, target }); - } - - insns.push(MGI::ClearLog); - insns.push(MGI::SetTableSize(table_size)); - insns.push(MGI::SetTableColour(table_colour)); - - for pspec in pieces.into_iter() { - insns.push(MGI::AddPieces(pspec)); - } + insns.push(MGI::ResetFromGameSpec { spec_toml }); chan.alter_game(insns, None)?; diff --git a/src/commands.rs b/src/commands.rs index 92fcdfe9..1618b27d 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -95,6 +95,8 @@ pub enum MgmtGameInstruction { DeletePieceAlias(String), DefinePieceAlias { alias: String, target: Box }, + ResetFromGameSpec { spec_toml: String }, + ResetPlayerAccess(PlayerId), RedeliverPlayerAccess(PlayerId), @@ -203,6 +205,8 @@ pub enum MgmtError { BadSpec(#[from] SpecError), TokenDeliveryFailed(#[from] TokenDeliveryError), CoordinateOverflow(#[from] CoordinateOverflow), + TomlSyntaxError(String), + TomlStructureError(String), RngIsReal, } impl Display for MgmtError {