From 164d1c7c88a75d39909adb3885aae4b62363b336 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Fri, 7 Nov 2025 00:27:28 +0200 Subject: [PATCH] Avoid panicking when `Signature` inserted during replication --- CHANGELOG.md | 1 + src/shared/replication/signature.rs | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b981b17..00a403ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Avoid sending despawn for entities that weren't sent. +- Avoid panicking when `Signature` inserted during replication. ### Removed diff --git a/src/shared/replication/signature.rs b/src/shared/replication/signature.rs index d3afa5bc..3442ed3b 100644 --- a/src/shared/replication/signature.rs +++ b/src/shared/replication/signature.rs @@ -307,14 +307,22 @@ fn register_hash(mut world: DeferredWorld, ctx: HookContext) { let mut signature = entity.get_mut::().unwrap(); signature.hash = hash; - world - .resource_mut::() - .insert(ctx.entity, hash); + if let Some(mut map) = world.get_resource_mut::() { + map.insert(ctx.entity, hash); + } else { + // Can't be handled manually like with unregistering below. + // However, when it's inserted during replication, entities + // don't need to be mapped. For example, the signature could + // be a required component to map local player entities, + // but ignored for remote ones. + debug!("ignoring hash 0x{hash:016x} for `{}`", ctx.entity); + } } fn unregister_hash(mut world: DeferredWorld, ctx: HookContext) { // The map will be unavailable during replication because the - // resource will be temporarily removed from the world. + // resource will be temporarily removed from the world, + // so it's handled manually there. if let Some(mut map) = world.get_resource_mut::() { map.remove(ctx.entity); } @@ -395,6 +403,12 @@ variadics_please::all_tuples!(impl_signature_components, 0, 6, C); mod tests { use super::*; + #[test] + fn no_panic_without_map() { + let mut world = World::new(); + world.spawn(Signature::from(0)).despawn(); + } + #[test] fn single_component() { let mut world = World::new();