aboutsummaryrefslogtreecommitdiff
path: root/server/src/commands.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/commands.rs')
-rw-r--r--server/src/commands.rs117
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"),
+ })
+ }
+}