1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
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 {
#[arg(default_value = "small-default-default")]
spec: String,
},
End,
}
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("lobby-none-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 } => {
let data = self.index.generate(spec)?;
self.game.load(data);
}
Command::End => {
self.game
.load(self.index.generate("lobby-none-none".to_string())?);
}
}
Ok(())
}
}
|