diff --git a/src/main/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParser.java b/src/main/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParser.java index 721198b..df3df40 100644 --- a/src/main/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParser.java +++ b/src/main/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParser.java @@ -849,13 +849,19 @@ public final class DataDrivenItemParser { return null; } String s = elem.getAsString(); - // Strict RL parsing : animations MUST carry an explicit namespace - // (e.g. "mymod:foo"). ResourceLocation.tryParse defaults bare paths - // to the "minecraft" namespace, which silently masks modder typos — - // we reject strings without ':' here. - if (s.isEmpty() || s.indexOf(':') < 0) { + // Strict RL parsing : animations MUST carry an explicit namespace AND + // path (e.g. "mymod:foo"). ResourceLocation.tryParse would silently + // accept ":path" as "minecraft:path", "mod:" with an empty path, or + // ":" altogether — masking modder typos. Reject all of these here : + // - isEmpty() rejects "" + // - colonIdx <= 0 rejects "noNamespace" (-1) and ":path" (0) + // - colonIdx >= length - 1 rejects "mod:" (colon at end) + // The bare ":" is rejected by colonIdx == 0. + int colonIdx = s.indexOf(':'); + if (s.isEmpty() || colonIdx <= 0 || colonIdx >= s.length() - 1) { LOGGER.warn( - "[DataDrivenItemParser] Malformed ResourceLocation '{}' for {} in item {}, skipping.", + "[DataDrivenItemParser] Malformed ResourceLocation '{}' for {} in item {} " + + "(expected 'namespace:path'), skipping.", s, context, itemId @@ -865,7 +871,8 @@ public final class DataDrivenItemParser { ResourceLocation rl = ResourceLocation.tryParse(s); if (rl == null) { LOGGER.warn( - "[DataDrivenItemParser] Malformed ResourceLocation '{}' for {} in item {}, skipping.", + "[DataDrivenItemParser] Malformed ResourceLocation '{}' for {} in item {} " + + "(invalid characters), skipping.", s, context, itemId diff --git a/src/main/java/com/tiedup/remake/v2/client/BondageStateHelpers.java b/src/main/java/com/tiedup/remake/v2/client/BondageStateHelpers.java index 7e0e213..cb39406 100644 --- a/src/main/java/com/tiedup/remake/v2/client/BondageStateHelpers.java +++ b/src/main/java/com/tiedup/remake/v2/client/BondageStateHelpers.java @@ -39,10 +39,11 @@ import net.minecraft.world.item.ItemStack; * {@code PacketSyncStruggleState}). * * - *
Thread-safety : toutes les lectures backing sont - * déjà thread-safe (volatile / ConcurrentHashMap / EntityData). Ces - * helpers peuvent être appelés depuis les threads MC usuels (client - * tick, render thread) sans synchronisation additionnelle.
+ *Thread-safety : les APIs backing (V2EquipmentHelper, + * PlayerBindState) suivent le pattern MC standard — écriture serveur main + * thread, lecture client main thread après packet sync via + * {@code Context.enqueueWork}. Pas de lock externe requis tant que + * l'appelant est sur le main thread approprié.
* *Note sur {@code @OnlyIn(Dist.CLIENT)} : ces helpers * fonctionnent aussi server-side par construction (ils lisent les mêmes diff --git a/src/test/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParserAnimationsTest.java b/src/test/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParserAnimationsTest.java index 9d7dcdb..583111b 100644 --- a/src/test/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParserAnimationsTest.java +++ b/src/test/java/com/tiedup/remake/v2/bondage/datadriven/DataDrivenItemParserAnimationsTest.java @@ -32,7 +32,7 @@ import com.tiedup.remake.rig.anim.TiedUpLivingMotions; *