chiark / gitweb /
wip moving token reset to server
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Nov 2020 17:37:37 +0000 (17:37 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Nov 2020 17:37:37 +0000 (17:37 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/otter.rs
src/commands.rs
src/spec.rs

index fec6938e92ebb1a4ca448adb5120cb16a551e5a7..49a9412ff6491628ac1e7539da64a4154526efdb 100644 (file)
@@ -356,104 +356,64 @@ fn connect(ma: &MainOpts) -> Conn {
 
 fn setup_table(ma: &MainOpts, chan: &mut ConnForGame,
                spec: &TableSpec) -> Result<(),AE> {
-  // create missing players and delete old players
-  let (added_players,) = {
-    let (_, nick2id) = chan.get_info()?;
-
-    #[derive(Default)]
-    struct St { id: PlayerId, old: bool, new: bool };
-
-    let mut nick2st : HashMap<_,_> = {nick2id}
-      .drain()
-      .map(|(nick,id)| (nick, St { id, old: true, new: false }))
-      .collect();
-
-    let mut insns = vec![];
-    for pspec in &spec.players {
-      let nick = pspec.nick.unwrap_or_else(|| pspec.account.default_nick());
-      let st = nick2st.entry(nick.clone()).or_default();
-      if st.new {
-        Err(anyhow!("duplicate player nick {:?} in spec", &nick))?;
-      }
-      st.new = true;
-      let timezone = pspec.timezone.as_ref().or(
-        spec.timezone.as_ref()
-      ).cloned();
-      // ^ todo use client program timezone?
-      if !st.old {
-        insns.push(MgmtGameInstruction::AddPlayer {
-          account: pspec.account.clone(),
-          details: MgmtPlayerDetails {
-            nick: Some(nick),
-            timezone,
-          },
-        });
-      }
+  let (_, nick2id) = chan.get_info()?;
+
+  #[derive(Default)]
+  struct St { id: PlayerId, old: bool, new: bool };
+
+  let mut nick2st : HashMap<_,_> = {nick2id}
+  .drain()
+    .map(|(nick,id)| (nick, St { id, old: true, new: false }))
+    .collect();
+
+  let mut insns = vec![];
+  for pspec in &spec.players {
+    let nick = pspec.nick.unwrap_or_else(|| pspec.account.default_nick());
+    let st = nick2st.entry(nick.clone()).or_default();
+    if st.new {
+      Err(anyhow!("duplicate player nick {:?} in spec", &nick))?;
     }
-
-    for (nick, st) in nick2st {
-      if st.new { continue }
-      if !st.old { continue }
-      if ma.verbose >= 1 {
-        eprintln!("removing old player {:?}", &nick);
-      }
-      insns.push(Insn::RemovePlayer { player: st.id });
+    st.new = true;
+    let timezone = pspec.timezone.as_ref().or(
+      spec.timezone.as_ref()
+    ).cloned();
+    // ^ todo use client program timezone?
+    if !st.old {
+      insns.push(MgmtGameInstruction::AddPlayer {
+        account: pspec.account.clone(),
+        details: MgmtPlayerDetails {
+          nick: Some(nick),
+          timezone,
+        },
+      });
     }
+  }
 
-    let mut added_players = vec![];
-    chan.alter_game(insns, Some(&mut |response| {
-      match response {
-        &Resp::AddPlayer { player, nick, token, .. } => {
-          added_players.push((player, nick, token));
-        },
-        _ => { },
-      };
-      Ok(())
-    }))?;
+  for (nick, st) in nick2st {
+    if st.new { continue }
+    if !st.old { continue }
+    if ma.verbose >= 1 {
+      eprintln!("removing old player {:?}", &nick);
+    }
+    insns.push(Insn::RemovePlayer { player: st.id });
+  }
 
-    (added_players,)
-  };
+  let mut added_players = vec![];
+  chan.alter_game(insns, Some(&mut |response| {
+    match response {
+      &Resp::AddPlayer { info, player, token } => {
+        added_players.push((info.clone(), token.clone()));
+      },
+      _ => { },
+    };
+    Ok(())
+  }))?;
 
   // report any new access tokens
-  {
-    let (_, nick2id) = chan.get_info()?;
-    let mut insns = vec![];
-    let mut resetreport = vec![];
-    let mut resetspecs = vec![];
-    for pspec in &spec.players {
-      let player = *nick2id.get(&pspec.nick)
-        .ok_or_else(||anyhow!("player {:?} vanished or renamed!",
-                              &pspec.nick))?;
-      if let Some(access) = &pspec.access {
-        match access.token_mgi(player) {
-          Some(insn) => insns.push(insn),
-          None if added_players.contains(&player) => {
-            resetreport.push(player);
-            resetspecs.push((pspec, access));
-          },
-          None => (),
-        }
-      };
-    }
-    insns.push(MgmtGameInstruction::ResetPlayerAccesses {
-      players: resetreport.clone(),
-    });
-    let mut got_tokens = None;
-    chan.alter_game(insns, Some(&mut |response| {
-      if let MgmtGameResponse::PlayerAccessTokens(tokens) = response {
-        got_tokens = Some(tokens.clone());
-      }
-      Ok(())
-    }))?;
-    let got_tokens = match got_tokens {
-      Some(t) if t.len() == resetreport.len() => t,
-      wat => Err(anyhow!("Did not get expected ReportPlayerAccesses! {:?}",
-                         &wat))?,
-    };
-    for ((pspec, access), ptokens)
-      in resetspecs.iter().zip(got_tokens.iter()) {
-      access.deliver_tokens(&pspec, &ptokens)
-          .with_context(||format!("deliver tokens for nick={:?}",
+  for (info, token) in added_players {
+    
+  access.deliver_tokens(&pspec, &ptokens)
+        .with_context(||format!("deliver tokens for nick={:?}",
                                   &pspec.nick))?;
     }
   }
index e494ade2370f87a8b9a6ffa298429d6b3aba4803..66b9b4bc6e055c21ea01be0cb693208b6aa0ca8d 100644 (file)
@@ -99,7 +99,7 @@ pub enum MgmtGameResponse {
   Pieces(Vec<MgmtGamePieceInfo>),
 
   AddPlayer {
-    account: AccountName, nick: String,
+    #[serede(flatten)] info: MgmtPlayerInfo,
     player: PlayerId, token: Option<AccessTokenReport>,
   },
   PlayerAccessToken(Option<AccessTokenReport>),
index 539e07f33c40cafbf96830c727e1e3393b6286b6..39d7c075ea5692b80943aa9e44075fb70fe25c48 100644 (file)
@@ -66,10 +66,12 @@ pub struct TableSpec {
 }
 
 #[derive(Debug,Serialize,Deserialize)]
-pub struct TablePlayerSpec {
-  pub account: AccountName,
-  pub nick: Option<String>,
-  pub timezone: Option<String>,
+#[serde(rename_all="snake_case")]
+pub enum TablePlayerSpec {
+  Account(String),
+  AccountGlob(String),
+  Local(String),
+  AllLocal,
 }
 
 type RawAcl<Perm> = Vec<AclEntry<Perm>>;