chan
}
-fn setup_table(chan: &mut ConnForGame, spec: &TableSpec) -> Result<(),AE> {
+fn setup_table(ma: &MainOpts, chan: &mut ConnForGame,
+ spec: &TableSpec) -> Result<(),AE> {
// xxx should delete old players
// create missing players
let mut insns = vec![];
for pspec in &spec.players {
let st = nick2st.entry(pspec.nick.clone()).or_default();
+ if st.new {
+ Err(anyhow!("duplicate player nick {:?} in spec", &pspec.nick))?;
+ }
st.new = true;
if !st.old {
insns.push(MgmtGameInstruction::AddPlayer(PlayerState {
}));
}
}
+
+ 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(st.id));
+ }
+
let mut added_players = HashSet::new();
chan.alter_game(insns, Some(&mut |response| {
- let player = match response {
- &Resp::AddPlayer(player) => player,
- _ => Err(anyhow!("AddPlayer strange answer {:?}",
- &response))?,
+ match response {
+ &Resp::AddPlayer(player) => {
+ added_players.insert(player);
+ },
+ _ => { },
};
- added_players.insert(player);
Ok(())
}))?;
how: MgmtGameUpdateMode::Bulk,
};
- setup_table(&mut chan, &spec)?;
+ setup_table(&ma, &mut chan, &spec)?;
if ma.verbose >= 0 {
eprintln!("create-table successful. game still needs setup.");
Err(e)
})?;
- setup_table(&mut chan, &table_spec)?;
+ setup_table(&ma, &mut chan, &table_spec)?;
}
let mut insns = vec![];
impl InstanceGuard<'_> {
/// caller is responsible for logging; threading it through
/// proves the caller has a log entry.
- #[throws(ServerFailure)]
+ #[throws(MgmtError)]
pub fn player_new(&mut self, newplayer: PlayerState,
logentry: LogEntry) -> (PlayerId, LogEntry) {
// saving is fallible, but we can't attempt to save unless
// we have a thing to serialise with the player in it
+ if self.c.g.gs.players.values().any(|pl| pl.nick == newplayer.nick) {
+ Err(MgmtError::AlreadyExists)?;
+ }
let player = self.c.g.gs.players.insert(newplayer);
self.save_game_now().map_err(|e|{
self.c.g.gs.players.remove(player);