aboutsummaryrefslogtreecommitdiff
path: root/server/src/state.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-25 23:34:10 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-25 23:34:10 +0200
commit4dc15a1e86ef1ae985fdf36f1a84d07b1de99ea7 (patch)
tree6a262cd2be9abee480adda3e367c7f8abf8845d6 /server/src/state.rs
parent84c90e84a1e0d6cd2eae36fd8888354b4e23c354 (diff)
downloadhurrycurry-4dc15a1e86ef1ae985fdf36f1a84d07b1de99ea7.tar
hurrycurry-4dc15a1e86ef1ae985fdf36f1a84d07b1de99ea7.tar.bz2
hurrycurry-4dc15a1e86ef1ae985fdf36f1a84d07b1de99ea7.tar.zst
server can change map at runtime
Diffstat (limited to 'server/src/state.rs')
-rw-r--r--server/src/state.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/server/src/state.rs b/server/src/state.rs
new file mode 100644
index 00000000..98f92a24
--- /dev/null
+++ b/server/src/state.rs
@@ -0,0 +1,68 @@
+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<PacketC>,
+ pub game: Game,
+}
+
+#[derive(Parser)]
+#[clap(multicall = true)]
+enum Command {
+ Start { spec: String },
+}
+
+impl State {
+ pub fn new(tx: Sender<PacketC>) -> Result<Self> {
+ 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(())
+ }
+}