From e628b73efeaeb6ae015219525db733ed4eaae885 Mon Sep 17 00:00:00 2001 From: Yansunsky <1321833118@qq.com> Date: Tue, 19 May 2026 22:26:24 +0800 Subject: [PATCH 1/3] "Fixed a bug that duplicated items. The bug was: when an item was placed on a Table Cloth, using the Physics Assembler would cause the item to be duplicated. The fix was based on the fact that blocks like Table Cloth are not registered as clearable, so an additional method was written to handle blocks not registered as clearable. The implementation approach is to directly initialize the block's NBT, retaining only its own ID, since it will be removed soon." --- .../sable/api/SubLevelAssemblyHelper.java | 2 ++ .../sable/platform/SableAssemblyPlatform.java | 3 ++ .../platform/SableAssemblyPlatformImpl.java | 33 +++++++++++++++++++ .../platform/SableAssemblyPlatformImpl.java | 33 +++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java b/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java index c95b7400..d7b53922 100644 --- a/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java +++ b/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java @@ -353,6 +353,8 @@ public static void moveBlocks(final ServerLevel level, final AssemblyTransform t } if (blockEntity instanceof final Clearable clearable) { clearable.clearContent(); + }else if (blockEntity != null) { + SableAssemblyPlatform.INSTANCE.clearNonClearableContainerItems(blockEntity); } final LevelChunk chunk = resultingAccelerator.getChunk(SectionPos.blockToSectionCoord(newPos.getX()), SectionPos.blockToSectionCoord(newPos.getZ())); diff --git a/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java b/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java index 9ffa4345..b854f2f6 100644 --- a/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java +++ b/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java @@ -1,6 +1,7 @@ package dev.ryanhcode.sable.platform; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal @@ -8,4 +9,6 @@ public interface SableAssemblyPlatform { SableAssemblyPlatform INSTANCE = SablePlatformUtil.load(SableAssemblyPlatform.class); void setIgnoreOnPlace(final Level level, final boolean ignore); + + void clearNonClearableContainerItems(final BlockEntity blockEntity); } diff --git a/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java b/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java index d9c97a7f..f352cf51 100644 --- a/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java +++ b/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java @@ -2,8 +2,12 @@ import dev.ryanhcode.sable.fabric.mixinterface.LevelExtension; import dev.ryanhcode.sable.platform.SableAssemblyPlatform; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; +import java.util.ArrayList; +import java.util.List; @ApiStatus.Internal public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { @@ -12,4 +16,33 @@ public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { public void setIgnoreOnPlace(final Level level, final boolean ignore) { ((LevelExtension) level).sable$setIgnoreOnPlace(ignore); } + + @Override + public void clearNonClearableContainerItems(final BlockEntity blockEntity) { + if (blockEntity == null) { + return; + } + try { + final Level level = blockEntity.getLevel(); + if (level == null) { + return; + } + final CompoundTag tag = blockEntity.saveWithFullMetadata(level.registryAccess()); + if (tag.isEmpty()) { + return; + } + final List keysToRemove = new ArrayList<>(); + for (final String key : tag.getAllKeys()) { + if (!key.equals("id")) { + keysToRemove.add(key); + } + } + for (final String key : keysToRemove) { + tag.remove(key); + } + blockEntity.loadWithComponents(tag, level.registryAccess()); + } catch (final Exception ignored) { + + } + } } diff --git a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java index 176ccca5..9da43a2e 100644 --- a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java +++ b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java @@ -1,8 +1,12 @@ package dev.ryanhcode.sable.neoforge.platform; import dev.ryanhcode.sable.platform.SableAssemblyPlatform; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; +import java.util.ArrayList; +import java.util.List; @ApiStatus.Internal public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { @@ -11,4 +15,33 @@ public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { public void setIgnoreOnPlace(final Level level, final boolean ignore) { level.captureBlockSnapshots = ignore; } + + @Override + public void clearNonClearableContainerItems(final BlockEntity blockEntity) { + if (blockEntity == null) { + return; + } + try { + final Level level = blockEntity.getLevel(); + if (level == null) { + return; + } + final CompoundTag tag = blockEntity.saveWithFullMetadata(level.registryAccess()); + if (tag.isEmpty()) { + return; + } + final List keysToRemove = new ArrayList<>(); + for (final String key : tag.getAllKeys()) { + if (!key.equals("id")) { + keysToRemove.add(key); + } + } + for (final String key : keysToRemove) { + tag.remove(key); + } + blockEntity.loadWithComponents(tag, level.registryAccess()); + } catch (final Exception ignored) { + + } + } } From c39440fa307e954bf630d3c8f5f019ace6b74490 Mon Sep 17 00:00:00 2001 From: Yansunsky <1321833118@qq.com> Date: Wed, 20 May 2026 14:49:14 +0800 Subject: [PATCH 2/3] A more concise method --- .../platform/SableAssemblyPlatformImpl.java | 32 ++++--------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java index 9da43a2e..41d00aef 100644 --- a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java +++ b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java @@ -5,8 +5,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; -import java.util.ArrayList; -import java.util.List; @ApiStatus.Internal public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { @@ -18,30 +16,14 @@ public void setIgnoreOnPlace(final Level level, final boolean ignore) { @Override public void clearNonClearableContainerItems(final BlockEntity blockEntity) { - if (blockEntity == null) { - return; - } try { final Level level = blockEntity.getLevel(); - if (level == null) { - return; - } - final CompoundTag tag = blockEntity.saveWithFullMetadata(level.registryAccess()); - if (tag.isEmpty()) { - return; - } - final List keysToRemove = new ArrayList<>(); - for (final String key : tag.getAllKeys()) { - if (!key.equals("id")) { - keysToRemove.add(key); - } - } - for (final String key : keysToRemove) { - tag.remove(key); - } - blockEntity.loadWithComponents(tag, level.registryAccess()); - } catch (final Exception ignored) { - - } + if (level == null) return; + final CompoundTag oldTag = blockEntity.saveWithFullMetadata(level.registryAccess()); + final String id = oldTag.getString("id"); + final CompoundTag newTag = new CompoundTag(); + newTag.putString("id", id); + blockEntity.loadWithComponents(newTag, level.registryAccess()); + } catch (final Exception ignored) {} } } From 859d28f313fe7a37053dcb0c8a7509d75c04e4df Mon Sep 17 00:00:00 2001 From: Yansunsky <1321833118@qq.com> Date: Wed, 20 May 2026 14:57:59 +0800 Subject: [PATCH 3/3] A more concise method --- .../sable/api/SubLevelAssemblyHelper.java | 2 +- .../sable/platform/SableAssemblyPlatform.java | 3 +- .../platform/SableAssemblyPlatformImpl.java | 33 ++++--------------- .../platform/SableAssemblyPlatformImpl.java | 5 ++- 4 files changed, 12 insertions(+), 31 deletions(-) diff --git a/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java b/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java index d7b53922..22a2a1d0 100644 --- a/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java +++ b/common/src/main/java/dev/ryanhcode/sable/api/SubLevelAssemblyHelper.java @@ -354,7 +354,7 @@ public static void moveBlocks(final ServerLevel level, final AssemblyTransform t if (blockEntity instanceof final Clearable clearable) { clearable.clearContent(); }else if (blockEntity != null) { - SableAssemblyPlatform.INSTANCE.clearNonClearableContainerItems(blockEntity); + SableAssemblyPlatform.INSTANCE.clearNonClearableContainerItems(blockEntity,tag); } final LevelChunk chunk = resultingAccelerator.getChunk(SectionPos.blockToSectionCoord(newPos.getX()), SectionPos.blockToSectionCoord(newPos.getZ())); diff --git a/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java b/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java index b854f2f6..48efb894 100644 --- a/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java +++ b/common/src/main/java/dev/ryanhcode/sable/platform/SableAssemblyPlatform.java @@ -1,5 +1,6 @@ package dev.ryanhcode.sable.platform; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; @@ -10,5 +11,5 @@ public interface SableAssemblyPlatform { void setIgnoreOnPlace(final Level level, final boolean ignore); - void clearNonClearableContainerItems(final BlockEntity blockEntity); + void clearNonClearableContainerItems(final BlockEntity blockEntity,final CompoundTag tag); } diff --git a/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java b/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java index f352cf51..1e174bdc 100644 --- a/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java +++ b/fabric/src/main/java/dev/ryanhcode/sable/fabric/platform/SableAssemblyPlatformImpl.java @@ -6,8 +6,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.ApiStatus; -import java.util.ArrayList; -import java.util.List; @ApiStatus.Internal public class SableAssemblyPlatformImpl implements SableAssemblyPlatform { @@ -18,31 +16,14 @@ public void setIgnoreOnPlace(final Level level, final boolean ignore) { } @Override - public void clearNonClearableContainerItems(final BlockEntity blockEntity) { - if (blockEntity == null) { - return; - } + public void clearNonClearableContainerItems(final BlockEntity blockEntity,final CompoundTag tag) { try { final Level level = blockEntity.getLevel(); - if (level == null) { - return; - } - final CompoundTag tag = blockEntity.saveWithFullMetadata(level.registryAccess()); - if (tag.isEmpty()) { - return; - } - final List keysToRemove = new ArrayList<>(); - for (final String key : tag.getAllKeys()) { - if (!key.equals("id")) { - keysToRemove.add(key); - } - } - for (final String key : keysToRemove) { - tag.remove(key); - } - blockEntity.loadWithComponents(tag, level.registryAccess()); - } catch (final Exception ignored) { - - } + if (level == null) return; + final String id = tag.getString("id"); + final CompoundTag newTag = new CompoundTag(); + newTag.putString("id", id); + blockEntity.loadWithComponents(newTag, level.registryAccess()); + } catch (final Exception ignored) {} } } diff --git a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java index 41d00aef..1894cbb1 100644 --- a/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java +++ b/neoforge/src/main/java/dev/ryanhcode/sable/neoforge/platform/SableAssemblyPlatformImpl.java @@ -15,12 +15,11 @@ public void setIgnoreOnPlace(final Level level, final boolean ignore) { } @Override - public void clearNonClearableContainerItems(final BlockEntity blockEntity) { + public void clearNonClearableContainerItems(final BlockEntity blockEntity,final CompoundTag tag) { try { final Level level = blockEntity.getLevel(); if (level == null) return; - final CompoundTag oldTag = blockEntity.saveWithFullMetadata(level.registryAccess()); - final String id = oldTag.getString("id"); + final String id = tag.getString("id"); final CompoundTag newTag = new CompoundTag(); newTag.putString("id", id); blockEntity.loadWithComponents(newTag, level.registryAccess());