aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/customer/mod.rs14
-rw-r--r--server/src/game.rs1
-rw-r--r--server/src/main.rs25
-rw-r--r--server/src/protocol.rs3
-rw-r--r--server/src/state.rs33
-rw-r--r--test-client/main.ts5
-rw-r--r--test-client/protocol.ts1
7 files changed, 62 insertions, 20 deletions
diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs
index 92e6e94c..f90b2eb2 100644
--- a/server/src/customer/mod.rs
+++ b/server/src/customer/mod.rs
@@ -165,6 +165,13 @@ impl DemandState {
persist: true,
},
));
+ packets_out.push((
+ id,
+ PacketS::Communicate {
+ message: Some(Message::Effect("angry".to_string())),
+ persist: false,
+ },
+ ));
let path = find_path(
&self.walkable,
p.movement.position.as_ivec2(),
@@ -205,6 +212,13 @@ impl DemandState {
message: None,
},
));
+ packets_out.push((
+ id,
+ PacketS::Communicate {
+ message: Some(Message::Effect("satisfied".to_string())),
+ persist: false,
+ },
+ ));
for edge in [true, false] {
packets_out.push((id, PacketS::Interact { pos, edge }))
}
diff --git a/server/src/game.rs b/server/src/game.rs
index 4f609608..96cfa93a 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -106,6 +106,7 @@ impl Game {
self.unload();
self.data = gamedata.into();
+ self.points = 0;
for (&p, (tile, item)) in &self.data.initial_map {
self.tiles.insert(
diff --git a/server/src/main.rs b/server/src/main.rs
index 5b191365..68927eaa 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -143,18 +143,25 @@ async fn run() -> anyhow::Result<()> {
while let Some(Ok(message)) = read.next().await {
match message {
Message::Text(line) => {
- let Ok(packet): Result<PacketS, _> = serde_json::from_str(&line) else {
- warn!("invalid json over ws");
- break;
+ let packet = match serde_json::from_str(&line) {
+ Ok(p) => p,
+ Err(e) => {
+ warn!("invalid packet: {e}");
+ break;
+ }
};
debug!("<- {id:?} {packet:?}");
- if let Err(e) = state.write().await.packet_in(id, packet).await {
- warn!("client error: {e}");
- let _ = error_tx
- .send(PacketC::Error {
+ let packet_out = match state.write().await.packet_in(id, packet).await {
+ Ok(packets) => packets,
+ Err(e) => {
+ warn!("client error: {e}");
+ vec![PacketC::Error {
message: format!("{e}"),
- })
- .await;
+ }]
+ }
+ };
+ for packet in packet_out {
+ let _ = error_tx.send(packet).await;
}
}
Message::Close(_) => break,
diff --git a/server/src/protocol.rs b/server/src/protocol.rs
index 6ed34a65..39bc0887 100644
--- a/server/src/protocol.rs
+++ b/server/src/protocol.rs
@@ -134,6 +134,9 @@ pub enum PacketC {
message: Option<Message>,
persist: bool,
},
+ ServerMessage {
+ text: String,
+ },
Score {
points: i64,
demands_failed: usize,
diff --git a/server/src/state.rs b/server/src/state.rs
index da05f33a..41ffce20 100644
--- a/server/src/state.rs
+++ b/server/src/state.rs
@@ -45,26 +45,37 @@ impl State {
let _ = self.tx.send(p);
}
}
- pub async fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> {
+ pub async fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<Vec<PacketC>> {
match &packet {
PacketS::Communicate {
message: Some(Message::Text(text)),
persist: false,
} if let Some(command) = text.strip_prefix("/") => {
- self.handle_command(
- player,
- Command::try_parse_from(
- shlex::split(command)
- .ok_or(anyhow!("quoting invalid"))?
- .into_iter(),
- )?,
- )
- .await?;
- return Ok(());
+ match self.handle_command_parse(player, command).await {
+ Ok(()) => return Ok(vec![]),
+ Err(e) => {
+ return Ok(vec![PacketC::ServerMessage {
+ text: format!("{e}"),
+ }]);
+ }
+ }
}
_ => (),
}
self.game.packet_in(player, packet)?;
+ Ok(vec![])
+ }
+
+ async fn handle_command_parse(&mut self, player: PlayerID, command: &str) -> Result<()> {
+ self.handle_command(
+ player,
+ Command::try_parse_from(
+ shlex::split(command)
+ .ok_or(anyhow!("quoting invalid"))?
+ .into_iter(),
+ )?,
+ )
+ .await?;
Ok(())
}
diff --git a/test-client/main.ts b/test-client/main.ts
index e3185c67..38b9e730 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -211,6 +211,11 @@ function packet(p: PacketC) {
global_message_clear = setTimeout(() => global_message = undefined, 4000)
console.warn(p.message)
break;
+ case "server_message":
+ if (global_message_clear) clearTimeout(global_message_clear)
+ global_message = { inner: { text: p.text }, anim_size: 0., anim_position: { x: 0, y: 0 } }
+ global_message_clear = setTimeout(() => global_message = undefined, 4000)
+ break;
case "set_ingame":
console.log(`ingame ${p.state}`);
break;
diff --git a/test-client/protocol.ts b/test-client/protocol.ts
index f9f0dbaf..81a0d1a4 100644
--- a/test-client/protocol.ts
+++ b/test-client/protocol.ts
@@ -48,6 +48,7 @@ export type PacketC =
| { type: "set_active", tile: Vec2, progress?: number, warn: boolean } // A tile is doing something. progress goes from 0 to 1, then null when finished
| { type: "update_map", tile: Vec2, kind: TileIndex | null, neighbors: [TileIndex | null] } // A map tile was changed
| { type: "communicate", player: PlayerID, message?: Message, persist: boolean } // A player wants to communicate something, message is null when cleared
+ | { type: "server_message", text: string } // Text message from the server
| { type: "score", points: number, demands_failed: number, demands_completed: number, } // Supplies information for score OSD
| { type: "set_ingame", state: boolean } // Set to false when entering the game or switching maps
| { type: "error", message: string } // Your client did something wrong.