diff --git a/client/client.lua b/client/client.lua index fa2f95c..52c2b20 100644 --- a/client/client.lua +++ b/client/client.lua @@ -73,7 +73,11 @@ local function namefront() if not front or not front.shutdown then return false end - return front.getLabel() + return { ["Name"] = { string = front.getLabel() } } +end + +local function name() + return { ["Name"] = os.computerLabel() } end local function inventoryinfo() @@ -151,7 +155,7 @@ local commands = { ["CycleFront"] = restartfront, ["Poweroff"] = os.shutdown, ["GetFuelLimit"] = turtle.getFuelLimit, - ["Name"] = os.computerLabel, + ["Name"] = name, ["NameFront"] = namefront, }; diff --git a/server/src/mine.rs b/server/src/mine.rs index bc56de5..ed73483 100644 --- a/server/src/mine.rs +++ b/server/src/mine.rs @@ -97,16 +97,20 @@ async fn devore(turtle: &TurtleCommander) { loop { // cancel the task of the turtle ahead so that it doesn't go wild in the depot if let TurtleCommandResponse::Name(name) = turtle.execute(NameFront).await.ret { + let name = name.string; + info!("rebirth: {name}"); match Name::from_str(&name) { Ok(name) => { let mut scheduler = turtle.scheduler().await; scheduler.cancel(name).await; + info!("rebirth: canceled existing"); scheduler.do_on(move |turtle| tokio::spawn(async move { depot::dump(&turtle).await; depot::refuel(&turtle).await; // *teleports behind you* turtle.goto(Position::new(staging - position.dir.unit(), position.dir)).await; }).abort_handle(), name).unwrap(); + info!("rebirth: launched move"); break; }, Err(_) => error!("bad turtle name: {name}"), diff --git a/server/src/tasks.rs b/server/src/tasks.rs index 30751d3..4d6a390 100644 --- a/server/src/tasks.rs +++ b/server/src/tasks.rs @@ -125,14 +125,12 @@ impl Scheduler { where T: FnMut(TurtleCommander) -> AbortHandle { let turtle = self.turtles.iter_mut().filter(|t| t.0.name() == turtle).next()?; - match turtle.1 { - Some(_) => None, - None => { - trace!("new adhoc task on {}", turtle.0.name().to_str()); - turtle.1 = Some(task(turtle.0.clone())); - Some(()) - }, + if let Some(task) = turtle.1.take() { // this may be unsound + task.abort(); } + trace!("new adhoc task on {}", turtle.0.name().to_str()); + turtle.1 = Some(task(turtle.0.clone())); + Some(()) } pub fn task_on(&mut self, mut task: Box, turtle: Name) -> Option<()> { diff --git a/server/src/turtle.rs b/server/src/turtle.rs index 213a0a9..3e62859 100644 --- a/server/src/turtle.rs +++ b/server/src/turtle.rs @@ -388,7 +388,7 @@ impl TurtleCommander { let steps: Vec = route.iter().map_windows(|[from,to]| from.difference(**to).unwrap()).collect(); 'route: for (next_position, command) in route.into_iter().skip(1).zip(steps) { - if world.occupied(next_position.pos).await { + if recent.pos != next_position.pos && world.occupied(next_position.pos).await { if world.garbage(next_position.pos).await { let command = recent.dig(next_position.pos); match command { @@ -399,7 +399,7 @@ impl TurtleCommander { }, }; } else { - warn!("non destructible block on route"); + warn!("non destructible block on route: {} at {:?}", world.get(next_position.pos).await.unwrap().name, next_position); break 'route; } } @@ -480,7 +480,7 @@ pub(crate) async fn process_turtle_update( } if let Some(send) = turtle.callback.take() { - send.send(info).unwrap(); + send.send(info).unwrap_or_else(|_| warn!("task cancelled")); } if let Some(recv) = turtle.receiver.as_mut() { @@ -544,6 +544,12 @@ pub(crate) struct InventorySlot { pub(crate) count: u32, } +// bodge +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct TurtleString { + pub string: String, +} + #[derive(Serialize, Deserialize, Clone, Debug)] pub(crate) enum TurtleCommandResponse { None, @@ -551,7 +557,7 @@ pub(crate) enum TurtleCommandResponse { Failure, Item(InventorySlot), Inventory(Vec), - Name(String), + Name(TurtleString), } impl TurtleCommand {