use crate::{ data::DataIndex, game::Game, protocol::{Message, PacketC, PacketS, PlayerID}, }; use anyhow::{anyhow, Result}; use clap::Parser; use log::debug; use tokio::sync::broadcast::Sender; pub struct State { index: DataIndex, tx: Sender, pub game: Game, } #[derive(Parser)] #[clap(multicall = true)] enum Command { Start { spec: String }, } impl State { pub fn new(tx: Sender) -> Result { let mut index = DataIndex::default(); index.reload()?; let mut game = Game::new(); game.load(index.generate("none-lobby-none".to_string())?); Ok(Self { game, index, tx }) } pub async fn tick(&mut self, dt: f32) { self.game.tick(dt); while let Some(p) = self.game.packet_out() { debug!("-> {p:?}"); let _ = self.tx.send(p); } } pub async fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> { match &packet { PacketS::Communicate { message: Some(Message::Text(message)), } if let Some(command) = message.strip_prefix("/") => { self.handle_command(Command::try_parse_from( shlex::split(command) .ok_or(anyhow!("quoting invalid"))? .into_iter(), )?) .await?; return Ok(()); } _ => (), } self.game.packet_in(player, packet)?; Ok(()) } async fn handle_command(&mut self, command: Command) -> Result<()> { match command { Command::Start { spec } => { self.game.load(self.index.generate(spec)?); } } Ok(()) } }