diff options
Diffstat (limited to 'server/src/commands.rs')
| -rw-r--r-- | server/src/commands.rs | 117 |
1 files changed, 52 insertions, 65 deletions
diff --git a/server/src/commands.rs b/server/src/commands.rs index 36c7ccde..f8ead074 100644 --- a/server/src/commands.rs +++ b/server/src/commands.rs @@ -25,11 +25,10 @@ use hurrycurry_bot::algos::ALGO_CONSTRUCTORS; use hurrycurry_data::build_gamedata; use hurrycurry_locale::{TrError, tre, trm}; use hurrycurry_protocol::{ - Character, Hand, ItemLocation, Menu, Message, PacketC, PlayerClass, PlayerID, + Character, GameConfig, Hand, ItemLocation, Menu, Message, PacketC, PacketS, PlayerClass, + PlayerID, VoteSubject, }; -use std::fmt::Write; -#[cfg(feature = "cheats")] -use std::time::Duration; +use std::{fmt::Write, str::FromStr}; #[derive(Parser)] #[clap(multicall = true)] @@ -39,19 +38,15 @@ enum Command { Start { /// Gamedata specification #[arg(default_value = "junior")] - name: String, - - /// Skip announement and pause at game start - #[arg(short = 's', long)] - skip_announce: bool, + map: String, /// Number of hands per player #[arg(short = 'c', long)] hand_count: Option<usize>, /// Duration in seconds - #[cfg(feature = "cheats")] - timer: Option<u64>, + #[arg(short = 't', long)] + timer: Option<f32>, }, /// Shows the best entries of the scoreboard for this map. #[clap(alias = "top", alias = "top5")] @@ -62,6 +57,8 @@ enum Command { #[arg(short, long)] text: bool, }, + #[clap(alias = "v")] + Vote { agree: YesNo }, #[clap(alias = "mapinfo")] Info { /// Name of the map, default: current @@ -147,64 +144,41 @@ impl Server { ) -> Result<(), TrError> { match command { Command::Start { - name, - #[cfg(feature = "cheats")] - timer, - skip_announce, + map, hand_count, + timer, } => { - if !self.game.lobby { - self.broadcast - .send(PacketC::ServerMessage { - message: trm!( - "s.state.game_aborted", - s = self - .game - .players - .get(&player) - .ok_or(tre!("s.error.no_player"))? - .name - .clone() - ), - error: false, - }) - .ok(); - } - let mut data = build_gamedata(&self.config.data_path, &name, true) - .map_err(|e| TrError::Plain(e.to_string()))?; - - if let Some(hand_count) = hand_count { - data.0.hand_count = hand_count; - } - #[cfg(feature = "cheats")] - self.load(data, timer.map(Duration::from_secs)); - #[cfg(not(feature = "cheats"))] - self.load(data, None); - if skip_announce { - self.announce_state = AnnounceState::Done - } + self.packet_in( + replies, + PacketS::InitiateVote { + player, + subject: VoteSubject::StartGame { + config: GameConfig { + hand_count, + map, + timer, + }, + }, + }, + )?; } Command::End => { - self.broadcast - .send(PacketC::ServerMessage { - message: trm!( - "s.state.game_aborted", - s = self - .game - .players - .get(&player) - .ok_or(tre!("s.error.no_player"))? - .name - .clone() - ), - error: false, - }) - .ok(); - self.load( - build_gamedata(&self.config.data_path, &self.config.lobby, true) - .map_err(|e| TrError::Plain(e.to_string()))?, - None, - ); + self.packet_in( + replies, + PacketS::InitiateVote { + player, + subject: VoteSubject::EndGame, + }, + )?; + } + Command::Vote { agree } => { + self.packet_in( + replies, + PacketS::CastVote { + player, + agree: agree.0, + }, + )?; } Command::Reload => { if self.count_chefs() > 1 { @@ -434,3 +408,16 @@ impl Server { Ok(()) } } + +#[derive(Debug, Clone)] +struct YesNo(bool); +impl FromStr for YesNo { + type Err = &'static str; + fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { + Ok(match s { + "y" | "yes" | "true" | "1" => Self(true), + "n" | "no" | "false" | "0" => Self(false), + _ => return Err("expected y, yes, true, 1 or their opposites"), + }) + } +} |