MapStore(|s| Ok(Some(
FixedToken { token: RawToken(s.to_string()) }.into()
))),
- "use fixed game access token TOKEN (for administrators, with --super, only; only \`reset', not \`redelivery', of tokens is possible)"
+ "use fixed game access token TOKEN (for administrators, with --super, only; only `reset', not `redelivery', of tokens is possible)"
);
access.add_option(&["--no-access-token"],
StoreConst(Some(PlayerAccessUnset.into())),
}
responses
}
+
+ #[throws(AE)]
+ fn we_are_player(&mut self, ma: &MainOpts)
+ -> Option<(PlayerId, MgmtPlayerInfo)>
+ {
+ let players = {
+ let resp = self.alter_game(vec![MGI::Info], None)?;
+ match resp.as_slice() {
+ [MGR::Info(MgmtGameResponseGameInfo { players, .. })] => players,
+ x => throw!(anyhow!("unexpected response to game Info: {:?}", &x)),
+ }.clone()
+ };
+
+ players.into_iter().filter(
+ |(_,mpi)| &mpi.account == &ma.account
+ ).next()
+ }
/*
fn get_info(&mut self) -> Result<
(MgmtGameResponseGameInfo, HashMap<String,PlayerId>
let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
let mut chan = access_game(&ma, &args.table_name)?;
- let players = {
- let resp = chan.alter_game(vec![MGI::Info], None)?;
- match resp.as_slice() {
- [MGR::Info(MgmtGameResponseGameInfo { players, .. })] => players,
- x => throw!(anyhow!("unexpected response to game Info: {:?}", &x)),
- }.clone()
- };
-
let mut insns = vec![];
- match players.iter().filter(
- |(_,mpi)| &mpi.account == &ma.account
- ).next() {
+ match chan.we_are_player(&ma)? {
None => {
let nick = ma.nick.clone()
.unwrap_or_else(|| ma.account.default_nick());
player.0.get_idx_version().0, &mpi.nick);
let MgmtPlayerInfo { nick, account:_ } = mpi;
if let Some(new_nick) = &ma.nick {
- if nick != new_nick {
+ if &nick != new_nick {
println!("changing nick to {:?}", &new_nick);
let details = MgmtPlayerDetails { nick: ma.nick.clone() };
insns.push(MGI::UpdatePlayer { player, details });
)}
}
+//---------- leave-game ----------
+
+mod leave_game {
+ use super::*;
+
+ #[derive(Default,Debug)]
+ struct Args {
+ table_name: String,
+ }
+
+ fn subargs(sa: &mut Args) -> ArgumentParser {
+ use argparse::*;
+ let mut ap = ArgumentParser::new();
+ ap.refer(&mut sa.table_name).required()
+ .add_argument("TABLE-NAME",Store,"table name");
+ ap
+ }
+
+ fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) ->Result<(),AE> {
+ let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
+ let mut chan = access_game(&ma, &args.table_name)?;
+
+ let player = match chan.we_are_player(&ma)? {
+ None => {
+ println!("this account is not a player in that game");
+ exit(EXIT_NOTFOUND);
+ },
+ Some((player, _)) => player,
+ };
+
+ chan.alter_game(vec![MGI::LeaveGame(player)], None)?;
+
+ Ok(())
+ }
+
+ inventory::submit!{Subcommand(
+ "leave-game",
+ "Leave a game",
+ call,
+ )}
+}
+
//---------- library-list ----------
#[derive(Debug)]
use MgmtCommand::*;
use MgmtResponse::*;
-use MgmtError::*;
type ME = MgmtError;
from_instance_lock_error!{MgmtError}
PlayerAccessToken(token), ig)
},
+ LeaveGame(player) => {
+ let account = &cs.current_account()?.notional_account;
+ let (ig, _auth) = cs.check_acl_manip_player_access
+ (ag, ig, player, TP::ModifyOtherPlayer)?;
+
+ let got = ig.players_remove(&[player].iter().cloned().collect())?;
+
+ let (gpl, ipl) = got.into_iter().next()
+ .ok_or(PlayerNotFound)?;
+
+ let html = Html(
+ format!("{} [{}] left the game [{}]"
+ ,
+ (|| Some(gpl?.nick))()
+ .unwrap_or("<partial data!>".into())
+ ,
+ (||{
+ let (record, _) = ag.lookup(ipl?.acctid).ok()?;
+ Some(record.account.to_string())
+ })()
+ .unwrap_or("<account deleted>".into())
+ ,
+ &account
+ )
+ );
+
+ (U{ pcs: vec![],
+ log: vec![ LogEntry { html }],
+ raw: None },
+ Fine, ig)
+ },
+
DeletePiece(piece) => {
let (ig, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
let p = ig.ipieces.as_mut(modperm)
let ig = &mut **ig_g;
let gs = &mut ig.gs;
let count = count.unwrap_or(1);
- if count > CREATE_PIECES_MAX { throw!(LimitExceeded) }
+ if count > CREATE_PIECES_MAX { throw!(ME::LimitExceeded) }
let posd = posd.unwrap_or(DEFAULT_POS_DELTA);
let mut updates = Vec::with_capacity(count as usize);
},
Err(EOF) => break,
Err(IO(e)) => Err(e).context("read command stream")?,
- Err(Parse(s)) => MgmtResponse::Error { error : ParseFailed(s) },
+ Err(Parse(s)) => MgmtResponse::Error { error : ME::ParseFailed(s) },
};
self.chan.write(&resp).context("swrite command stream")?;
}