Some block state hunks were in the wrong patch (#7308)

This commit is contained in:
Jake Potrebic 2022-01-13 11:31:48 -08:00 committed by GitHub
parent 0c64d401aa
commit 6663747b89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 77 deletions

View File

@ -51,40 +51,28 @@ index 1e416b23a38458f16add472cea09b0ac5ac91869..6f61fd8224fb4094f38a851300ab55f9
return null;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index d8b9a8276204ad8a2f045af9fe94185dbf150bc6..3250559589eb4db7b3df828144cee81a19651842 100644
index c0af4b05b5d77aad99487fa7f8d840e797b6554c..40fc3268e7b662cdd45b569224ccd2abfad0a595 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -317,7 +317,20 @@ public class CraftBlock implements Block {
@Override
public BlockState getState() {
+ // Paper start
+ return this.getState(true);
+ }
+
+ @Override
+ public BlockState getState(boolean useSnapshot) {
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
+ CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ try {
@@ -320,6 +320,13 @@ public class CraftBlock implements Block {
return CraftBlockStates.getBlockState(this);
+ } finally {
+ CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+ }
+ // Paper end
}
+ // Paper start
+ @Override
+ public BlockState getState(boolean useSnapshot) {
+ return CraftBlockStates.getBlockState(this, useSnapshot);
+ }
+ // Paper end
+
@Override
public Biome getBiome() {
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 7629a51ec284cab0db7e9238027d6acfa4f3083c..27f38af1eb71dda5dd175dcabc7a467ed772757a 100644
index 7629a51ec284cab0db7e9238027d6acfa4f3083c..c2c0b4bfab64394e55f2832e37e49bccb7e955ab 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -6,19 +6,30 @@ import org.bukkit.World;
import org.bukkit.block.TileState;
import org.bukkit.persistence.PersistentDataContainer;
-public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState {
+public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert revert
@@ -10,15 +10,26 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
private final T tileEntity;
private final T snapshot;
@ -114,26 +102,40 @@ index 7629a51ec284cab0db7e9238027d6acfa4f3083c..27f38af1eb71dda5dd175dcabc7a467e
public void refreshSnapshot() {
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 51ea68c433c4d530f8404d3174c5a121ce808a96..9d0934656bbd27df4b47b816540d02cfbfc80636 100644
index 51ea68c433c4d530f8404d3174c5a121ce808a96..93a8aeb5545c794ac425c35f8af52a443cd060ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -105,12 +105,10 @@ public final class CraftBlockStates {
private static final BlockStateFactory<?> DEFAULT_FACTORY = new BlockStateFactory<CraftBlockState>(CraftBlockState.class) {
@Override
public CraftBlockState createBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
- // SPIGOT-6754, SPIGOT-6817: Restore previous behaviour for tile entities with removed blocks (loot generation post-destroy)
- if (tileEntity != null) {
- // block with unhandled TileEntity:
- return new CraftBlockEntityState<>(world, tileEntity);
- }
- Preconditions.checkState(tileEntity == null, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
+ // Paper start - revert revert
+ // When a block is being destroyed, the TileEntity may temporarily still exist while the block's type has already been set to AIR. We ignore the TileEntity in this case.
+ Preconditions.checkState(tileEntity == null || CraftMagicNumbers.getMaterial(blockData.getBlock()) == Material.AIR, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
+ // Paper end
return new CraftBlockState(world, blockPosition, blockData);
@@ -324,15 +324,30 @@ public final class CraftBlockStates {
}
};
public static BlockState getBlockState(Block block) {
+ // Paper start
+ return CraftBlockStates.getBlockState(block, true);
+ }
+ public static BlockState getBlockState(Block block, boolean useSnapshot) {
+ // Paper end
Preconditions.checkNotNull(block, "block is null");
CraftBlock craftBlock = (CraftBlock) block;
CraftWorld world = (CraftWorld) block.getWorld();
BlockPos blockPosition = craftBlock.getPosition();
net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
+ // Paper start - block state snapshots
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
+ CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ try {
+ // Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access
return blockState;
+ // Paper start
+ } finally {
+ CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+ }
+ // Paper end
}
public static BlockState getBlockState(Material material, @Nullable CompoundTag blockEntityTag) {
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
index 3fc3907172f12ee24ea70bd6a1ffbbc6084ed971..2c59f09a9261a1690951161fd856a5848d9885b7 100644
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java

View File

@ -49,10 +49,10 @@ index 0000000000000000000000000000000000000000..9a516520d975f52169e346adc4ec6d9d
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 1cbc9288cabc0637c0ad6145e7461fef87bfc830..5284b17b77fb714f1b68b2e1ee15b4bf992bd8e1 100644
index 40fc3268e7b662cdd45b569224ccd2abfad0a595..a9f962819c602e801de2d1a1bd069994283e785c 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -607,4 +607,11 @@ public class CraftBlock implements Block {
@@ -601,4 +601,11 @@ public class CraftBlock implements Block {
return iblockdata.canSurvive(world, this.position);
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Show blockstate location if we failed to read it
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 27f38af1eb71dda5dd175dcabc7a467ed772757a..bae73e3dced68156560997de63db902f6d99a251 100644
index c2c0b4bfab64394e55f2832e37e49bccb7e955ab..d46e3812ef058c119d327cf752e7deaa341736e3 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -18,6 +18,7 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
@@ -18,6 +18,7 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
this.tileEntity = tileEntity;
@ -16,7 +16,7 @@ index 27f38af1eb71dda5dd175dcabc7a467ed772757a..bae73e3dced68156560997de63db902f
// Paper start
this.snapshotDisabled = DISABLE_SNAPSHOT;
if (DISABLE_SNAPSHOT) {
@@ -30,6 +31,14 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
@@ -30,6 +31,14 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
this.load(this.snapshot);
}
// Paper end

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add effect to block break naturally
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 5284b17b77fb714f1b68b2e1ee15b4bf992bd8e1..a3eb8cd92c1c7a40175e3dd637c0fd6b8d0dfc67 100644
index a9f962819c602e801de2d1a1bd069994283e785c..a918813a0faf451977686bdd6ee3aff71853f41f 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -468,6 +468,18 @@ public class CraftBlock implements Block {
@@ -462,6 +462,18 @@ public class CraftBlock implements Block {
@Override
public boolean breakNaturally(ItemStack item) {
@ -27,7 +27,7 @@ index 5284b17b77fb714f1b68b2e1ee15b4bf992bd8e1..a3eb8cd92c1c7a40175e3dd637c0fd6b
// Order matters here, need to drop before setting to air so skulls can get their data
net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS();
net.minecraft.world.level.block.Block block = iblockdata.getBlock();
@@ -477,6 +489,7 @@ public class CraftBlock implements Block {
@@ -471,6 +483,7 @@ public class CraftBlock implements Block {
// Modelled off EntityHuman#hasBlock
if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), position, this.world.getBlockEntity(position), null, nmsItem);

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Add methods to get translation keys
Co-authored-by: MeFisto94 <MeFisto94@users.noreply.github.com>
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index a3eb8cd92c1c7a40175e3dd637c0fd6b8d0dfc67..980f0ec9d343b4186dfeb07b9b08edfde9efeb33 100644
index a918813a0faf451977686bdd6ee3aff71853f41f..8b65d48606ea422c3e53a25c013540a0eb774648 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -626,5 +626,15 @@ public class CraftBlock implements Block {
@@ -620,5 +620,15 @@ public class CraftBlock implements Block {
public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() {
return new com.destroystokyo.paper.block.CraftBlockSoundGroup(getNMS().getBlock().defaultBlockState().getSoundType());
}

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Add Destroy Speed API
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index aa783fb4d77c9edb58c56ff98c604a87d9583767..2144126241450fe2d6e801bd9452d211a03b6f7c 100644
index cdd1b36fa5e856df3eb7d31b3d6a3fbfcbb83be6..90ad83db94e4cfb98470b9a607fe3ddec2e51c6c 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -636,5 +636,26 @@ public class CraftBlock implements Block {
@@ -630,5 +630,26 @@ public class CraftBlock implements Block {
public String translationKey() {
return org.bukkit.Bukkit.getUnsafe().getTranslationKey(this);
}

View File

@ -9,10 +9,10 @@ process to do this in the Bukkit API
Adds API for buildable, replaceable, burnable too.
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 2144126241450fe2d6e801bd9452d211a03b6f7c..fdf342e6059d967746164f18dc041b4e586f1a20 100644
index 90ad83db94e4cfb98470b9a607fe3ddec2e51c6c..23d243c004af58bd8d37c594ff4bcbd314031604 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -456,6 +456,25 @@ public class CraftBlock implements Block {
@@ -450,6 +450,25 @@ public class CraftBlock implements Block {
return this.getNMS().getMaterial().isLiquid();
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add Block#isValidTool
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index fdf342e6059d967746164f18dc041b4e586f1a20..bdabe194a32e922bbbd73a2a33c3d0f54c46be67 100644
index 23d243c004af58bd8d37c594ff4bcbd314031604..7f9ba247b67c1a8ab54b7d70bdc31b847531e725 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -676,5 +676,9 @@ public class CraftBlock implements Block {
@@ -670,5 +670,9 @@ public class CraftBlock implements Block {
}
return speed;
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Fix return value of Block#applyBoneMeal always being false
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index bdabe194a32e922bbbd73a2a33c3d0f54c46be67..991e73e0f397da265b08ce14bb2f92b251eaff48 100644
index 7f9ba247b67c1a8ab54b7d70bdc31b847531e725..b51c4be42842e747c4f4630709ef40a0e39a34d0 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -521,7 +521,7 @@ public class CraftBlock implements Block {
@@ -515,7 +515,7 @@ public class CraftBlock implements Block {
Direction direction = CraftBlock.blockFaceToNotch(face);
UseOnContext context = new UseOnContext(this.getCraftWorld().getHandle(), null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false));

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add isCollidable methods to various places
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 991e73e0f397da265b08ce14bb2f92b251eaff48..89cfa5093d53e1a249efc64aa1b449755c6eecd9 100644
index b51c4be42842e747c4f4630709ef40a0e39a34d0..bf7d216d9307a96005dcca64696af72a84a68716 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -473,6 +473,11 @@ public class CraftBlock implements Block {
@@ -467,6 +467,11 @@ public class CraftBlock implements Block {
public boolean isSolid() {
return getNMS().getMaterial().blocksMotion();
}

View File

@ -22,8 +22,21 @@ index 0e37da7227eaba0d089e5bd136eca088ab2b5eb3..5601d0c2fe635a2a4f073c333531e1a8
org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
if (state instanceof InventoryHolder) return (InventoryHolder) state;
return null;
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index d46e3812ef058c119d327cf752e7deaa341736e3..8c847183a398df386ae5a24467378c5c3b889dc7 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -6,7 +6,7 @@ import org.bukkit.World;
import org.bukkit.block.TileState;
import org.bukkit.persistence.PersistentDataContainer;
-public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState {
+public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes
private final T tileEntity;
private final T snapshot;
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 9d0934656bbd27df4b47b816540d02cfbfc80636..a6b47006760e0711e9f667b733efaae6928d27e1 100644
index 93a8aeb5545c794ac425c35f8af52a443cd060ca..9a4d79973af25853c4173a1df0131830505b623b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -19,6 +19,7 @@ import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
@ -34,13 +47,17 @@ index 9d0934656bbd27df4b47b816540d02cfbfc80636..a6b47006760e0711e9f667b733efaae6
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
@@ -107,184 +108,55 @@ public final class CraftBlockStates {
@@ -105,188 +106,55 @@ public final class CraftBlockStates {
private static final BlockStateFactory<?> DEFAULT_FACTORY = new BlockStateFactory<CraftBlockState>(CraftBlockState.class) {
@Override
public CraftBlockState createBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
// Paper start - revert revert
// When a block is being destroyed, the TileEntity may temporarily still exist while the block's type has already been set to AIR. We ignore the TileEntity in this case.
- Preconditions.checkState(tileEntity == null || CraftMagicNumbers.getMaterial(blockData.getBlock()) == Material.AIR, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
+ Preconditions.checkState(tileEntity == null/* || CraftMagicNumbers.getMaterial(blockData.getBlock()) == Material.AIR*/, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock())); // Paper - don't ignore the TileEntity while its still valid
// Paper end
- // SPIGOT-6754, SPIGOT-6817: Restore previous behaviour for tile entities with removed blocks (loot generation post-destroy)
- if (tileEntity != null) {
- // block with unhandled TileEntity:
- return new CraftBlockEntityState<>(world, tileEntity);
- }
+ // Paper - revert upstream's revert of the block state changes. Block entities that have already had the block type set to AIR are still valid, upstream decided to ignore them
Preconditions.checkState(tileEntity == null, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
return new CraftBlockState(world, blockPosition, blockData);
}
};
@ -262,7 +279,7 @@ index 9d0934656bbd27df4b47b816540d02cfbfc80636..a6b47006760e0711e9f667b733efaae6
}
private static void register(Material blockType, BlockStateFactory<?> factory) {
@@ -292,35 +164,45 @@ public final class CraftBlockStates {
@@ -294,35 +162,45 @@ public final class CraftBlockStates {
}
private static <T extends BlockEntity, B extends CraftBlockEntityState<T>> void register(
@ -321,9 +338,9 @@ index 9d0934656bbd27df4b47b816540d02cfbfc80636..a6b47006760e0711e9f667b733efaae6
+ // Paper end
+
public static BlockState getBlockState(Block block) {
Preconditions.checkNotNull(block, "block is null");
CraftBlock craftBlock = (CraftBlock) block;
@@ -363,7 +245,7 @@ public final class CraftBlockStates {
// Paper start
return CraftBlockStates.getBlockState(block, true);
@@ -380,7 +258,7 @@ public final class CraftBlockStates {
if (world != null && tileEntity == null && CraftBlockStates.isTileEntityOptional(material)) {
factory = CraftBlockStates.DEFAULT_FACTORY;
} else {

View File

@ -7,10 +7,10 @@ Leaves fluid if the block broken was fluid-logged which is what
happens if a player breaks a fluid-logged block
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 89cfa5093d53e1a249efc64aa1b449755c6eecd9..7cf7b845620ab5b118da79f6057c0d80a254585e 100644
index bf7d216d9307a96005dcca64696af72a84a68716..5ea2fdbd2c762e0e632093fc07294327eb061ada 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -508,6 +508,7 @@ public class CraftBlock implements Block {
@@ -502,6 +502,7 @@ public class CraftBlock implements Block {
net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS();
net.minecraft.world.level.block.Block block = iblockdata.getBlock();
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
@ -18,7 +18,7 @@ index 89cfa5093d53e1a249efc64aa1b449755c6eecd9..7cf7b845620ab5b118da79f6057c0d80
boolean result = false;
// Modelled off EntityHuman#hasBlock
@@ -518,7 +519,7 @@ public class CraftBlock implements Block {
@@ -512,7 +513,7 @@ public class CraftBlock implements Block {
}
// SPIGOT-6778: Directly call setBlock instead of setTypeAndData, so that the tile entiy is not removed and custom remove logic is run.