diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-07 23:03:07 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-07 23:03:07 +0200 |
commit | cd6e8f3886d764847f92ad75d397e2f2f6ad930a (patch) | |
tree | c99e141bc51c2004cdde1b0660ed10b2696f04d8 /server/src | |
parent | fd46def1ebc10d1f2ee4f4447f33e2dfb35986d2 (diff) | |
download | hurrycurry-cd6e8f3886d764847f92ad75d397e2f2f6ad930a.tar hurrycurry-cd6e8f3886d764847f92ad75d397e2f2f6ad930a.tar.bz2 hurrycurry-cd6e8f3886d764847f92ad75d397e2f2f6ad930a.tar.zst |
add option to download map source
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/bin/graph.rs | 3 | ||||
-rw-r--r-- | server/src/data.rs | 48 | ||||
-rw-r--r-- | server/src/main.rs | 2 | ||||
-rw-r--r-- | server/src/state.rs | 40 |
4 files changed, 62 insertions, 31 deletions
diff --git a/server/src/bin/graph.rs b/server/src/bin/graph.rs index 024512c6..766fa851 100644 --- a/server/src/bin/graph.rs +++ b/server/src/bin/graph.rs @@ -16,6 +16,7 @@ */ use anyhow::{anyhow, Result}; +use pollster::FutureExt; use undercooked::{ data::{DataIndex, Demand}, interaction::Recipe, @@ -32,7 +33,7 @@ fn main() -> Result<()> { .nth(1) .ok_or(anyhow!("first arg should be recipe set name"))?; - let data = index.generate(format!("small-default-{rn}"))?; + let data = index.generate(format!("small-default-{rn}")).block_on()?; for i in 0..data.item_names.len() { println!("i{i} [label=\"{}\"]", data.item_name(ItemIndex(i))) diff --git a/server/src/data.rs b/server/src/data.rs index c667e760..258057c0 100644 --- a/server/src/data.rs +++ b/server/src/data.rs @@ -20,7 +20,7 @@ use crate::{ interaction::Recipe, protocol::{DemandIndex, ItemIndex, RecipeIndex, TileIndex}, }; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{anyhow, bail, Result}; use glam::{IVec2, Vec2}; use serde::{Deserialize, Serialize}; use std::{ @@ -30,6 +30,7 @@ use std::{ str::FromStr, sync::{Mutex, RwLock}, }; +use tokio::fs::read_to_string; #[derive(Debug, Deserialize, Serialize, Clone, Copy, Default)] #[serde(rename_all = "snake_case")] @@ -126,35 +127,40 @@ fn data_dir() -> PathBuf { } impl DataIndex { - pub fn reload(&mut self) -> anyhow::Result<()> { + pub fn reload(&mut self) -> Result<()> { *self = serde_yaml::from_reader(File::open(data_dir().join("index.yaml"))?)?; Ok(()) } - pub fn generate(&self, spec: String) -> anyhow::Result<Gamedata> { - let (map, rest) = spec.split_once("-").unwrap_or((spec.as_str(), "default")); - let (demands, recipes) = rest.split_once("-").unwrap_or((rest, "default")); - - if !self.maps.contains(map) { - bail!("unknown map: {map:?}"); + pub async fn read_map(&self, name: &str) -> Result<String> { + if !self.maps.contains(name) { + bail!("unknown map: {name:?}"); } - if !self.demands.contains(demands) { - bail!("unknown demands: {demands:?}"); + let path = data_dir().join(format!("maps/{name}.yaml")); + Ok(read_to_string(path).await?) + } + pub async fn read_demands(&self, name: &str) -> Result<String> { + if !self.demands.contains(name) { + bail!("unknown demands: {name:?}"); } - if !self.recipes.contains(recipes) { - bail!("unknown recipes: {recipes:?}"); + let path = data_dir().join(format!("demands/{name}.yaml")); + Ok(read_to_string(path).await?) + } + pub async fn read_recipes(&self, name: &str) -> Result<String> { + if !self.recipes.contains(name) { + bail!("unknown recipes: {name:?}"); } + let path = data_dir().join(format!("recipes/{name}.yaml")); + Ok(read_to_string(path).await?) + } - let map_path = data_dir().join(format!("maps/{map}.yaml")); - let demands_path = data_dir().join(format!("demands/{demands}.yaml")); - let recipes_path = data_dir().join(format!("recipes/{recipes}.yaml")); + pub async fn generate(&self, spec: String) -> Result<Gamedata> { + let (map, rest) = spec.split_once("-").unwrap_or((spec.as_str(), "default")); + let (demands, recipes) = rest.split_once("-").unwrap_or((rest, "default")); - let map_in = serde_yaml::from_reader(File::open(map_path).context("opening map failed")?)?; - let demands_in = - serde_yaml::from_reader(File::open(demands_path).context("opening demands failed")?)?; - let recipes_in = serde_yaml::from_reader( - File::open(recipes_path).context("opening recipes failed. are they generated yet?")?, - )?; + let map_in = serde_yaml::from_str(&self.read_map(map).await?)?; + let demands_in = serde_yaml::from_str(&self.read_demands(demands).await?)?; + let recipes_in = serde_yaml::from_str(&self.read_recipes(recipes).await?)?; let mut gd = Gamedata::build(map_in, demands_in, recipes_in)?; gd.map_names = self.maps.clone(); diff --git a/server/src/main.rs b/server/src/main.rs index a144c704..d17dedf8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -82,7 +82,7 @@ async fn run() -> anyhow::Result<()> { let (tx, rx) = broadcast::channel::<PacketC>(1024); - let state = Arc::new(RwLock::new(State::new(tx)?)); + let state = Arc::new(RwLock::new(State::new(tx).await?)); { let state = state.clone(); spawn(async move { diff --git a/server/src/state.rs b/server/src/state.rs index cd763b18..8f33b6d4 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -6,7 +6,7 @@ use crate::{ protocol::{Message, PacketC, PacketS, PlayerID}, }; use anyhow::{anyhow, bail, Result}; -use clap::Parser; +use clap::{Parser, ValueEnum}; use log::debug; use tokio::sync::broadcast::Sender; @@ -25,6 +25,11 @@ enum Command { #[arg(default_value = "420")] timer: u64, }, + Download { + #[arg(value_enum)] + r#type: DownloadType, + name: String, + }, List, Effect { name: String, @@ -33,13 +38,20 @@ enum Command { End, } +#[derive(ValueEnum, Clone)] +enum DownloadType { + Map, + Recipes, + Demand, +} + impl State { - pub fn new(tx: Sender<PacketC>) -> Result<Self> { + pub async fn new(tx: Sender<PacketC>) -> Result<Self> { let mut index = DataIndex::default(); index.reload()?; let mut game = Game::new(); - game.load(index.generate("lobby-none-none".to_string())?, None); + game.load(index.generate("lobby-none-none".to_string()).await?, None); Ok(Self { game, index, tx }) } @@ -51,8 +63,10 @@ impl State { text: format!("Game finished. You reached {} points.", self.game.points), }) .ok(); - self.game - .load(self.index.generate("lobby-none-none".to_string())?, None); + self.game.load( + self.index.generate("lobby-none-none".to_string()).await?, + None, + ); } while let Some(p) = self.game.packet_out() { debug!("-> {p:?}"); @@ -97,7 +111,7 @@ impl State { async fn handle_command(&mut self, player: PlayerID, command: Command) -> Result<()> { match command { Command::Start { spec, timer } => { - let data = self.index.generate(spec)?; + let data = self.index.generate(spec).await?; self.game.load(data, Some(Duration::from_secs(timer))); } Command::End => { @@ -113,12 +127,22 @@ impl State { ), }) .ok(); - self.game - .load(self.index.generate("lobby-none-none".to_string())?, None); + self.game.load( + self.index.generate("lobby-none-none".to_string()).await?, + None, + ); } Command::Reload => { self.index.reload()?; } + 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, + DownloadType::Demand => self.index.read_demands(&name).await, + }?; + bail!("{source}"); + } Command::List => { bail!( "Maps: {:?}\nDemands: {:?}\nRecipes: {:?}", |