diff options
author | metamuffin <metamuffin@disroot.org> | 2024-12-25 23:13:12 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-12-25 23:13:12 +0100 |
commit | 6ca4b3377a08fa30a13835d59f9558419f7f5cd1 (patch) | |
tree | 711c5fd11a86a2f228f2f14912357f46ad7d7b73 /server/editor/src/main.rs | |
parent | 31507963a05dffb3327b62dd54629420061d6c4d (diff) | |
download | hurrycurry-6ca4b3377a08fa30a13835d59f9558419f7f5cd1.tar hurrycurry-6ca4b3377a08fa30a13835d59f9558419f7f5cd1.tar.bz2 hurrycurry-6ca4b3377a08fa30a13835d59f9558419f7f5cd1.tar.zst |
editor save and play features
Diffstat (limited to 'server/editor/src/main.rs')
-rw-r--r-- | server/editor/src/main.rs | 108 |
1 files changed, 94 insertions, 14 deletions
diff --git a/server/editor/src/main.rs b/server/editor/src/main.rs index 1ae4c81e..c5b6f61d 100644 --- a/server/editor/src/main.rs +++ b/server/editor/src/main.rs @@ -1,16 +1,23 @@ +pub mod save; + use anyhow::{Result, anyhow}; use clap::Parser; use futures_util::{SinkExt, StreamExt}; +use hurrycurry_client_lib::network::sync::Network; use hurrycurry_protocol::{ Gamedata, Hand, Message, PacketC, PacketS, PlayerClass, PlayerID, TileIndex, VERSION, glam::{IVec2, Vec2, ivec2}, movement::MovementBase, }; use log::{debug, info, warn}; +use save::export_state; use std::{ collections::{HashMap, HashSet}, + fs::File, + io::Write, net::SocketAddr, - time::Instant, + thread::{sleep, spawn}, + time::{Duration, Instant}, }; use tokio::net::{TcpListener, TcpStream}; @@ -24,8 +31,9 @@ struct Args { #[derive(Parser)] #[clap(multicall = true)] -enum Command { +pub enum Command { Play, + Save, } #[tokio::main] @@ -41,15 +49,17 @@ async fn main() -> Result<()> { } } -const TILES: &[&str] = &[ - "grass", - "floor", - "counter", - "oven", - "stove", - "cuttingboard", - "chair", - "table", +const TILES: &[(&str, char, u8)] = &[ + ("grass", 'a', 1), + ("floor", 'b', 1), + ("counter", 'c', 0), + ("oven", 'd', 0), + ("stove", 'e', 0), + ("cuttingboard", 'f', 0), + ("chair", 'g', 1), + ("table", 'h', 0), + ("wall", 'h', 2), + ("counter-window", 'h', 0), ]; #[allow(unused_assignments)] @@ -65,6 +75,8 @@ async fn handle_conn(sock: TcpStream, addr: SocketAddr) -> Result<()> { movement: MovementBase::new(Vec2::ZERO), last_movement: Instant::now(), tile: TileIndex(0), + chef_spawn: ivec2(0, 0), + customer_spawn: ivec2(0, 0), }; state.out.push(PacketC::Version { @@ -76,7 +88,7 @@ async fn handle_conn(sock: TcpStream, addr: SocketAddr) -> Result<()> { data: Gamedata { tile_collide: TILES.iter().map(|_| false).collect(), tile_interact: TILES.iter().map(|_| true).collect(), - tile_names: TILES.iter().map(|s| s.to_string()).collect(), + tile_names: TILES.iter().map(|(name, _, _)| name.to_string()).collect(), current_map: "editor".to_owned(), ..Default::default() }, @@ -128,7 +140,7 @@ async fn handle_conn(sock: TcpStream, addr: SocketAddr) -> Result<()> { Ok(()) } -struct State { +pub struct State { tiles: HashMap<IVec2, TileIndex>, walkable: HashSet<IVec2>, out: Vec<PacketC>, @@ -136,6 +148,9 @@ struct State { movement: MovementBase, last_movement: Instant, tile: TileIndex, + + customer_spawn: IVec2, + chef_spawn: IVec2, } impl State { @@ -222,6 +237,7 @@ impl State { message: Some(Message::Text(t)), .. } => { + let t = t.strip_prefix("/").unwrap_or(&t); self.handle_command( Command::try_parse_from( shlex::split(&t) @@ -239,7 +255,7 @@ impl State { self.tile.0 += 1; self.tile.0 %= TILES.len(); self.out.push(PacketC::ServerMessage { - message: Message::Text(format!("tile brush: {}", TILES[self.tile.0])), + message: Message::Text(format!("tile brush: {}", TILES[self.tile.0].0)), error: false, }); } @@ -262,14 +278,78 @@ impl State { Ok(()) } + pub fn save(&mut self) -> Result<()> { + let e = export_state(&self); + File::create("data/maps/editor.yaml")?.write_all(e.as_bytes())?; + self.out.push(PacketC::ServerMessage { + message: Message::Text(format!("Map saved.")), + error: false, + }); + Ok(()) + } + pub fn handle_command(&mut self, command: Command) -> Result<()> { match command { Command::Play => { + self.save()?; + spawn(move || { + if let Err(e) = start_map_bot("ws://127.0.0.1:27032", "editor") { + warn!("editor bot: {e}") + } + }); self.out.push(PacketC::Redirect { uri: vec!["ws://127.0.0.1:27032".to_string()], }); } + Command::Save => { + self.save()?; + } } Ok(()) } } + +fn start_map_bot(address: &str, mapname: &str) -> Result<()> { + let mut network = Network::connect(address)?; + + network.queue_out.push_back(PacketS::Join { + name: "editor-bot".to_owned(), + character: 0, + class: PlayerClass::Bot, + id: None, + }); + + let mut timer = 10.; + loop { + let dt = 1. / 50.; + + network.poll()?; + + while let Some(packet) = network.queue_in.pop_front() { + match &packet { + PacketC::Joined { id } => { + network.queue_out.push_back(PacketS::Communicate { + player: *id, + message: Some(Message::Text(format!("/start {mapname}"))), + timeout: None, + pin: None, + }); + } + PacketC::ServerMessage { + message, + error: true, + } => { + warn!("server error message: {message:?}"); + } + _ => (), + } + } + + timer -= dt; + if timer < 0. { + break; + } + sleep(Duration::from_secs_f32(dt)); + } + Ok(()) +} |