From 1b1a31bb6d59ad7fc10f122a2763115ffd955c31 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 23 Oct 2025 19:30:07 +0200 Subject: Recursive bot driver despawn in customers entity and added missing packet processing on entity deletion; fixes #488 --- server/src/entity/customers.rs | 20 ++++++++------------ server/src/entity/mod.rs | 15 +++++++++++++++ server/src/server.rs | 6 ++++++ 3 files changed, 29 insertions(+), 12 deletions(-) (limited to 'server') diff --git a/server/src/entity/customers.rs b/server/src/entity/customers.rs index e527580c..193fc2a3 100644 --- a/server/src/entity/customers.rs +++ b/server/src/entity/customers.rs @@ -42,7 +42,7 @@ impl Customers { } impl Entity for Customers { - fn tick(&mut self, c: EntityContext) -> Result<(), TrError> { + fn tick(&mut self, mut c: EntityContext) -> Result<(), TrError> { let chairs = *self.chair_count.get_or_insert_with(|| { c.game .tiles @@ -69,19 +69,15 @@ impl Entity for Customers { self.customers.push(bot) } for bot in &mut self.customers { - bot.tick(EntityContext { - game: c.game, - serverdata: c.serverdata, - packet_out: c.packet_out, - packet_in: c.packet_in, - score_changed: c.score_changed, - dt: c.dt, - scoreboard: c.scoreboard, - load_map: c.load_map, - replies: None, - })?; + bot.tick(c.dup())?; } self.customers.retain(|c| !c.finished()); Ok(()) } + + fn destructor(&mut self, mut c: EntityContext<'_>) { + for mut e in self.customers.drain(..) { + e.destructor(c.dup()); + } + } } diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 2e235c95..2c46a017 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -64,6 +64,21 @@ pub struct EntityContext<'a> { pub replies: Option<&'a mut Vec>, pub dt: f32, } +impl EntityContext<'_> { + pub fn dup<'a>(&'a mut self) -> EntityContext<'a> { + EntityContext { + game: self.game, + serverdata: self.serverdata, + packet_out: self.packet_out, + packet_in: self.packet_in, + score_changed: self.score_changed, + dt: self.dt, + scoreboard: self.scoreboard, + load_map: self.load_map, + replies: None, + } + } +} pub trait Entity: Any { fn tick(&mut self, _c: EntityContext<'_>) -> Result<(), TrError> { diff --git a/server/src/server.rs b/server/src/server.rs index ae4e82d8..dc63f1b5 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -353,6 +353,12 @@ impl Server { load_map: &mut None, }); } + // Need to process loopback packets for entity despawn + while let Some(p) = self.packet_loopback.pop_front() { + if let Err(e) = self.packet_in(None, p, &mut vec![]) { + warn!("Internal entity destructor packet errored: {e}"); + } + } self.game.load( gamedata, &serverdata, -- cgit v1.3