diff options
Diffstat (limited to 'server/src/commands.rs')
-rw-r--r-- | server/src/commands.rs | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/server/src/commands.rs b/server/src/commands.rs index e2d40f05..96d9ab75 100644 --- a/server/src/commands.rs +++ b/server/src/commands.rs @@ -19,8 +19,8 @@ use crate::{entity::bot::BotDriver, server::Server}; use anyhow::{anyhow, bail, Result}; use clap::{Parser, ValueEnum}; use hurrycurry_bot::algos::ALGO_CONSTRUCTORS; -use hurrycurry_protocol::{Message, PacketC, PlayerID}; -use std::time::Duration; +use hurrycurry_protocol::{Menu, Message, PacketC, PlayerID}; +use std::{fmt::Write, time::Duration}; #[derive(Parser)] #[clap(multicall = true)] @@ -34,6 +34,17 @@ enum Command { #[arg(default_value = "420")] timer: u64, }, + /// Shows the best entries of the scoreboard for this map. + #[clap(alias = "top5")] + Top { + /// Name of the map, default: current + map: Option<String>, + }, + #[clap(alias = "mapinfo")] + Info { + /// Name of the map, default: current + map: Option<String>, + }, /// Abort the current game End, /// Download recipe/map's source declaration @@ -57,6 +68,8 @@ enum Command { /// Reload the current map #[clap(alias = "r")] Reload, + /// Shows the recipe book + Book, } #[derive(ValueEnum, Clone)] @@ -66,7 +79,12 @@ enum DownloadType { } impl Server { - pub async fn handle_command_parse(&mut self, player: PlayerID, command: &str) -> Result<()> { + pub async fn handle_command_parse( + &mut self, + player: PlayerID, + command: &str, + ) -> Result<Vec<PacketC>> { + let mut replies = Vec::new(); for line in command.split("\n") { self.handle_command( player, @@ -75,12 +93,18 @@ impl Server { .ok_or(anyhow!("quoting invalid"))? .into_iter(), )?, + &mut replies, ) .await?; } - Ok(()) + Ok(replies) } - async fn handle_command(&mut self, player: PlayerID, command: Command) -> Result<()> { + async fn handle_command( + &mut self, + player: PlayerID, + command: Command, + replies: &mut Vec<PacketC>, + ) -> Result<()> { match command { Command::Start { spec, timer } => { let data = self.index.generate(&spec).await?; @@ -113,6 +137,7 @@ impl Server { Command::ReloadIndex => { self.index.reload().await?; } + Command::Book => replies.push(PacketC::Menu(Menu::Book)), Command::Download { r#type, name } => { let source = match r#type { DownloadType::Map => self.index.read_map(&name).await, @@ -162,6 +187,36 @@ impl Server { algo, ))); } + Command::Top { map } => { + let mapname = map.as_ref().unwrap_or(&self.game.data.current_map); + if let Some(board) = self.scoreboard.get(mapname) { + let mut o = format!("Scoreboard for {}:\n", mapname); + for (i, entry) in board.best.iter().take(5).enumerate() { + writeln!( + o, + " {i}. {} points by {}", + entry.score.points, + entry.players.clone().join(", ") + ) + .unwrap(); + } + bail!("{o}"); + } + } + Command::Info { map } => { + let mapname = map.as_ref().unwrap_or(&self.game.data.current_map); + let info = self + .index + .maps + .get(mapname) + .ok_or(anyhow!("no information available"))?; + bail!( + "{:?}\nRecommended player count: {}\nDifficulty: {}", + info.name, + info.difficulty, + info.players + ) + } } Ok(()) } |