diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-01 20:09:06 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-01 20:09:06 +0200 |
commit | eb7fa5392997ac5c165d1ae011e57a1b7fcac084 (patch) | |
tree | dedaf078a8817a976ead6568dbf93bf79f3f395b | |
parent | 4ad82d4944bc8ea00fcfe324c8004b079ec48c18 (diff) | |
download | hurrycurry-eb7fa5392997ac5c165d1ae011e57a1b7fcac084.tar hurrycurry-eb7fa5392997ac5c165d1ae011e57a1b7fcac084.tar.bz2 hurrycurry-eb7fa5392997ac5c165d1ae011e57a1b7fcac084.tar.zst |
server support for nested map directory
-rw-r--r-- | data/index.yaml | 2 | ||||
-rw-r--r-- | data/makefile | 2 | ||||
-rw-r--r-- | data/maps/campaign/01.yaml | 70 | ||||
-rw-r--r-- | data/maps/campaign/lobby.yaml | 59 | ||||
-rw-r--r-- | server/src/bin/graph.rs | 9 | ||||
-rw-r--r-- | server/src/bin/graph_summary.rs | 8 | ||||
-rw-r--r-- | server/src/data/mod.rs | 38 | ||||
-rw-r--r-- | server/src/server.rs | 2 | ||||
-rw-r--r-- | server/src/state.rs | 18 |
9 files changed, 160 insertions, 48 deletions
diff --git a/data/index.yaml b/data/index.yaml index 2073fd5d..199ed423 100644 --- a/data/index.yaml +++ b/data/index.yaml @@ -29,7 +29,6 @@ demands: # 5 Unplayable maps: - lobby: { name: "Lobby", players: 0, difficulty: 1 } sophomore: { name: "Sophomore", players: 1, difficulty: 1 } junior: { name: "Junior", players: 3, difficulty: 1 } senior: { name: "Senior", players: 4, difficulty: 1 } @@ -51,7 +50,6 @@ maps: 5star: { name: "5 Star", players: 4, difficulty: 3 } auto_sushi: { name: "AutoSushi", players: 2, difficulty: 2 } factory: { name: "Factory", players: 3, difficulty: 4 } - debug: { name: "DEBUG", players: 0, difficulty: 5 } recipes: - none diff --git a/data/makefile b/data/makefile index 95dc953a..23956869 100644 --- a/data/makefile +++ b/data/makefile @@ -14,7 +14,7 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # all: $(patsubst %.ts,%.yaml,$(wildcard recipes/*.ts)) -graphs: $(patsubst %.ts,%.svg,$(wildcard recipes/*.ts)) +graphs: recipes/default.svg recipes/%.yaml: recipes/%.ts DENO_NO_UPDATE_CHECK=1 deno run $< > $@ diff --git a/data/maps/campaign/01.yaml b/data/maps/campaign/01.yaml new file mode 100644 index 00000000..8fe64c5b --- /dev/null +++ b/data/maps/campaign/01.yaml @@ -0,0 +1,70 @@ +# Hurry Curry! - a game about cooking +# Copyright 2024 metamuffin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +score_baseline: 100 +map: + - "*''''*'''*'''''*'''" + - "'''*''''*'*'*'''*'*" + - "''████▒█████▒███'*" + - "*'█tc....█..~.s█''" + - "''▒c.ctc.d....⌷█'*" + - "'*█tc.c..█....C█'*" + - "''█c.....█XTppp█''" + - "*'████dd████████''" + - "'*''''__'''''''''''" + - "'''*''____________!" + - "'*'''''''''''''''''" + +tiles: + "⌷": counter + "p": counter + "t": table + "w": counter-window + "s": sink + "C": cuttingboard + "T": tomato-crate + "X": trash + + "c": chair + "~": floor + ".": floor + "'": grass + "*": tree + "!": path + "_": path + "d": door + "▒": wall-window + "█": wall + +items: + "p": plate + +entities: + - !customers + +chef_spawn: "~" +customer_spawn: "!" + +walkable: + - door + - floor + - chair + - grass + - path + +collider: + - wall + - wall-window + - tree diff --git a/data/maps/campaign/lobby.yaml b/data/maps/campaign/lobby.yaml new file mode 100644 index 00000000..6090d96a --- /dev/null +++ b/data/maps/campaign/lobby.yaml @@ -0,0 +1,59 @@ +# Hurry Curry! - a game about cooking +# Copyright 2024 metamuffin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +score_baseline: 0 +map: + - "'*''''''''''''*'" + - "*'''''*'''*'''''" + - "'*''*''''*'*'*'*" + - "*''''''''''''*''" + - "*''''''''''''**'" + - "''''''''''''''''" + - "''*''''''''''*'*" + - "'*'''''~''''''''" + - "''''''''''''''*'" + - "'*'''''''''''*''" + - "''*'''''''''''*'" + - "'''''''''''''*''" + - "'*'''''''''''*''" + - "''*'''*'''*''*''" + - "'*''*''**'''**''" + - "*'''''''''*''''*" + +tiles: + "t": table + "T": table + "s": sink + "c": chair + "~": floor + ".": floor + "b": book + "'": grass + "*": tree + "█": wall + +items: + "t": tomato-soup-plate + "T": bread-slice-plate + +chef_spawn: "~" +customer_spawn: "!" + +walkable: + - floor + - chair + - grass +collider: + - wall diff --git a/server/src/bin/graph.rs b/server/src/bin/graph.rs index 7019de9c..0bc3702f 100644 --- a/server/src/bin/graph.rs +++ b/server/src/bin/graph.rs @@ -15,7 +15,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -use anyhow::{anyhow, Result}; +use anyhow::Result; use hurrycurry_protocol::{Demand, ItemIndex, Recipe, RecipeIndex}; use hurrycurry_server::data::DataIndex; @@ -26,12 +26,7 @@ async fn main() -> Result<()> { println!("digraph {{"); - let rn = std::env::args() - .nth(1) - .ok_or(anyhow!("first arg should be recipe set name"))?; - - let (data, _, _) = index.generate(format!("5star-{rn}")).await?; - + let (data, _, _) = index.generate("5star").await?; for i in 0..data.item_names.len() { println!("i{i} [label=\"{}\"]", data.item_name(ItemIndex(i))) } diff --git a/server/src/bin/graph_summary.rs b/server/src/bin/graph_summary.rs index 12df0b1a..2c97799a 100644 --- a/server/src/bin/graph_summary.rs +++ b/server/src/bin/graph_summary.rs @@ -15,7 +15,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -use anyhow::{anyhow, Result}; +use anyhow::Result; use hurrycurry_protocol::{ItemIndex, Recipe, TileIndex}; use hurrycurry_server::data::DataIndex; use std::collections::HashSet; @@ -27,11 +27,7 @@ async fn main() -> Result<()> { println!("digraph {{"); - let rn = std::env::args() - .nth(1) - .ok_or(anyhow!("first arg should be recipe set name"))?; - - let (data, sdata, _) = index.generate(format!("5star-{rn}")).await?; + let (data, sdata, _) = index.generate("5star").await?; struct Node { inputs: Vec<ItemIndex>, diff --git a/server/src/data/mod.rs b/server/src/data/mod.rs index dd916a93..7ec0707d 100644 --- a/server/src/data/mod.rs +++ b/server/src/data/mod.rs @@ -69,6 +69,8 @@ pub struct RecipeDecl { #[derive(Debug, Clone, Deserialize)] pub struct MapDecl { + #[serde(default)] + recipes: Option<String>, map: Vec<String>, tiles: HashMap<char, String>, #[serde(default)] @@ -96,7 +98,6 @@ pub struct DemandDecl { #[derive(Debug,Clone, Default)] #[rustfmt::skip] pub struct Serverdata { - pub spec: String, pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>, pub chef_spawn: Vec2, pub customer_spawn: Vec2, @@ -125,8 +126,9 @@ impl DataIndex { } pub async fn read_map(&self, name: &str) -> Result<String> { - if !self.maps.contains_key(name) { - bail!("unknown map: {name:?}"); + // Scary! + if name.contains("..") || name.starts_with("/") || name.contains("//") { + bail!("illegal map path"); } let path = data_dir().join(format!("maps/{name}.yaml")); Ok(read_to_string(path).await?) @@ -138,26 +140,25 @@ impl DataIndex { let path = data_dir().join(format!("recipes/{name}.yaml")); Ok(read_to_string(path).await?) } - - pub async fn generate(&self, spec: String) -> Result<(Gamedata, Serverdata, Entities)> { - let (map, recipes) = spec.split_once("-").unwrap_or((spec.as_str(), "default")); - - let map_in = serde_yml::from_str(&self.read_map(map).await?)?; - let recipes_in = serde_yml::from_str(&self.read_recipes(recipes).await?)?; - - Ok(build_data( - &self.maps, - spec.clone(), - map.to_string(), - map_in, - recipes_in, - )?) + pub async fn generate(&self, map: &str) -> Result<(Gamedata, Serverdata, Entities)> { + let map_in: MapDecl = serde_yml::from_str(&self.read_map(map).await?)?; + let recipes_in = serde_yml::from_str( + &self + .read_recipes( + map_in + .recipes + .as_ref() + .map(|a| a.as_str()) + .unwrap_or("default"), + ) + .await?, + )?; + Ok(build_data(&self.maps, map.to_string(), map_in, recipes_in)?) } } pub fn build_data( maps: &HashMap<String, MapMetadata>, - spec: String, map_name: String, map_in: MapDecl, recipes_in: Vec<RecipeDecl>, @@ -301,7 +302,6 @@ pub fn build_data( tile_names, }, Serverdata { - spec, initial_map, chef_spawn, customer_spawn, diff --git a/server/src/server.rs b/server/src/server.rs index 75ecede1..cce99266 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -252,7 +252,6 @@ impl Server<'_> { packet_out: &mut VecDeque<PacketC>, ) { self.game.load(gamedata, &serverdata, timer, packet_out); - self.state.data = serverdata.into(); for mut e in self.state.entities.drain(..) { e.destructor(EntityContext { game: self.game, @@ -262,6 +261,7 @@ impl Server<'_> { dt: 0., }); } + self.state.data = serverdata.into(); self.state.entities = entities; } diff --git a/server/src/state.rs b/server/src/state.rs index 20a57b9d..4be0fb5a 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -99,11 +99,7 @@ impl State { game: &mut game, state: &mut server, } - .load( - index.generate("lobby-none".to_string()).await?, - None, - &mut packet_out, - ); + .load(index.generate("lobby").await?, None, &mut packet_out); } Ok(Self { @@ -123,7 +119,7 @@ impl State { }; if server.tick(dt, &mut self.packet_out) { server.load( - self.index.generate("lobby-none".to_string()).await?, + self.index.generate("lobby").await?, None, &mut self.packet_out, ); @@ -192,7 +188,7 @@ impl State { }) .ok(); server.load( - self.index.generate("lobby-none".to_string()).await?, + self.index.generate("lobby").await?, None, &mut self.packet_out, ); @@ -231,7 +227,7 @@ impl State { }; match command { Command::Start { spec, timer } => { - let data = self.index.generate(spec).await?; + let data = self.index.generate(&spec).await?; server.load(data, Some(Duration::from_secs(timer)), &mut self.packet_out); } Command::End => { @@ -249,7 +245,7 @@ impl State { }) .ok(); server.load( - self.index.generate("lobby-none".to_string()).await?, + self.index.generate("lobby").await?, None, &mut self.packet_out, ); @@ -259,9 +255,7 @@ impl State { bail!("must be at most one player to reload"); } server.load( - self.index - .generate(server.state.data.spec.to_string()) - .await?, + self.index.generate(&server.game.data.current_map).await?, None, &mut self.packet_out, ); |