diff options
author | metamuffin <metamuffin@disroot.org> | 2024-10-02 14:47:41 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-10-02 14:47:51 +0200 |
commit | a702fa55eda5fbb48fd2ea5ecea89d030ea2305a (patch) | |
tree | f8391ff21c33ce2aa2a83f6c11a693e182796119 /server/src | |
parent | ebf93598d76fbc172e9f23cde2a20a3194459e34 (diff) | |
download | hurrycurry-a702fa55eda5fbb48fd2ea5ecea89d030ea2305a.tar hurrycurry-a702fa55eda5fbb48fd2ea5ecea89d030ea2305a.tar.bz2 hurrycurry-a702fa55eda5fbb48fd2ea5ecea89d030ea2305a.tar.zst |
translate command errors
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/commands.rs | 91 | ||||
-rw-r--r-- | server/src/message.rs | 25 | ||||
-rw-r--r-- | server/src/state.rs | 2 |
3 files changed, 77 insertions, 41 deletions
diff --git a/server/src/commands.rs b/server/src/commands.rs index 478d88e3..feb6ab65 100644 --- a/server/src/commands.rs +++ b/server/src/commands.rs @@ -17,10 +17,11 @@ */ use crate::{ entity::{bot::BotDriver, tutorial::Tutorial}, + message::TrError, server::Server, - trm, + tre, trm, }; -use anyhow::{anyhow, bail, Result}; +use anyhow::Result; use clap::{Parser, ValueEnum}; use hurrycurry_bot::algos::ALGO_CONSTRUCTORS; use hurrycurry_protocol::{Menu, Message, PacketC, PlayerClass, PlayerID}; @@ -103,16 +104,17 @@ impl Server { &mut self, player: PlayerID, command: &str, - ) -> Result<Vec<PacketC>> { + ) -> Result<Vec<PacketC>, TrError> { let mut replies = Vec::new(); for line in command.split("\n") { self.handle_command( player, Command::try_parse_from( shlex::split(line) - .ok_or(anyhow!("quoting invalid"))? + .ok_or(tre!("s.error.quoting_invalid"))? .into_iter(), - )?, + ) + .map_err(|e| TrError::Plain(e.to_string()))?, &mut replies, ) .await?; @@ -124,7 +126,7 @@ impl Server { player: PlayerID, command: Command, replies: &mut Vec<PacketC>, - ) -> Result<()> { + ) -> Result<(), TrError> { match command { Command::Start { spec, timer } => { if !self.game.lobby { @@ -136,7 +138,7 @@ impl Server { .game .players .get(&player) - .ok_or(anyhow!("player missing"))? + .ok_or(tre!("s.error.no_player"))? .name .clone() ), @@ -144,7 +146,11 @@ impl Server { }) .ok(); } - let data = self.index.generate(&spec).await?; + let data = self + .index + .generate(&spec) + .await + .map_err(|e| TrError::Plain(e.to_string()))?; self.load(data, timer.map(Duration::from_secs)); } Command::End => { @@ -156,42 +162,59 @@ impl Server { .game .players .get(&player) - .ok_or(anyhow!("player missing"))? + .ok_or(tre!("s.error.no_player"))? .name .clone() ), error: false, }) .ok(); - self.load(self.index.generate("lobby").await?, None); + self.load( + self.index + .generate("lobby") + .await + .map_err(|e| TrError::Plain(e.to_string()))?, + None, + ); } Command::Reload => { if self.count_chefs() > 1 { - bail!("must be at most one player to reload"); + return Err(tre!("s.error.must_be_alone")); } self.load( - self.index.generate(&self.game.data.current_map).await?, + self.index + .generate(&self.game.data.current_map) + .await + .map_err(|e| TrError::Plain(e.to_string()))?, None, ); } Command::ReloadIndex => { - self.index.reload().await?; + self.index + .reload() + .await + .map_err(|e| TrError::Plain(e.to_string()))?; } 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, DownloadType::Recipes => self.index.read_recipes(&name).await, - }?; - bail!("{source}"); + } + .map_err(|e| TrError::Plain(e.to_string()))?; + replies.push(PacketC::ServerMessage { + message: Message::Text(source), + error: false, + }); } - Command::List => { - bail!( + Command::List => replies.push(PacketC::ServerMessage { + message: Message::Text(format!( "Maps: {:?}\nRecipes: {:?}", self.index.maps.keys().collect::<Vec<_>>(), self.index.recipes - ) - } + )), + error: false, + }), Command::Effect { name } => { self.tx.send(PacketC::Effect { name, player }).ok(); } @@ -200,7 +223,7 @@ impl Server { .game .data .get_item_by_name(&name) - .ok_or(anyhow!("unknown item"))?; + .ok_or(tre!("s.error.item_not_found", s = name))?; self.tx .send(PacketC::Communicate { player, @@ -213,7 +236,7 @@ impl Server { let (aname, cons) = ALGO_CONSTRUCTORS .iter() .find(|(name, _)| *name == algo.as_str()) - .ok_or(anyhow!("algo name unknown"))?; + .ok_or(tre!("s.error.algo_not_found", s = algo))?; let algo = cons(); self.entities.push(Box::new(BotDriver::new( format!("{}-bot", name.unwrap_or((*aname).to_owned())), @@ -235,7 +258,10 @@ impl Server { ) .unwrap(); } - bail!("{o}"); + replies.push(PacketC::ServerMessage { + message: Message::Text(o), + error: false, + }); } } Command::Info { map } => { @@ -244,20 +270,21 @@ impl Server { .index .maps .get(mapname) - .ok_or(anyhow!("no information available"))?; - bail!( - "{:?}\nRecommended player count: {}\nDifficulty: {}", - info.name, - info.difficulty, - info.players - ) + .ok_or(tre!("s.error.no_info"))?; + replies.push(PacketC::ServerMessage { + message: Message::Text(format!( + "{:?}\nRecommended player count: {}\nDifficulty: {}", + info.name, info.difficulty, info.players + )), + error: false, + }); } Command::StartTutorial { item } => { let item = self .game .data .get_item_by_name(&item) - .ok_or(anyhow!("unknown item"))?; + .ok_or(tre!("s.error.item_not_found", s = item))?; #[cfg(not(test))] // TODO rust-analyser does not undestand trait upcasting if self .entities @@ -268,7 +295,7 @@ impl Server { }) .is_some() { - bail!("Tutorial already running") + return Err(tre!("s.error.tutorial_already_running")); } self.entities.push(Box::new(Tutorial::new(player, item))); } @@ -281,7 +308,7 @@ impl Server { { tutorial.ended = true; } else { - bail!("No tutorial running") + return Err(tre!("s.error.tutorial_no_running")); } } Command::TranslateMessage { diff --git a/server/src/message.rs b/server/src/message.rs index c248fff8..79c004a2 100644 --- a/server/src/message.rs +++ b/server/src/message.rs @@ -46,28 +46,37 @@ macro_rules! trm_param { }; } -pub struct TrError { - pub id: &'static str, - pub params: Vec<Message>, +pub enum TrError { + Tr { + id: &'static str, + params: Vec<Message>, + }, + Plain(String), } impl From<TrError> for Message { fn from(value: TrError) -> Self { - Self::Translation { - id: value.id.to_owned(), - params: value.params, + match value { + TrError::Tr { id, params } => Self::Translation { + id: id.to_owned(), + params, + }, + TrError::Plain(s) => Self::Text(s), } } } impl Debug for TrError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} {:?}", tr(self.id), self.params) + match self { + TrError::Tr { id, params } => write!(f, "{} {:?}", tr(id), params), + TrError::Plain(s) => write!(f, "{s}"), + } } } #[macro_export] macro_rules! tre { ($id:literal $(, $typ:ident = $param:expr)*) => { - crate::message::TrError { + crate::message::TrError::Tr { id: $id, params: vec![$(crate::tre_param!($typ, $param)),*] } diff --git a/server/src/state.rs b/server/src/state.rs index 068b45a8..20e2bf80 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -59,7 +59,7 @@ impl Server { Ok(packets) => return Ok(packets), Err(e) => { return Ok(vec![PacketC::ServerMessage { - message: Message::Text(format!("{e}")), // TODO localize + message: e.into(), error: true, }]); } |