Skip to content

Commit 6f0a131

Browse files
committed
doc: update dropperCrashFix
1 parent 2957546 commit 6f0a131

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

README-en.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,27 @@ CommandLogger.json is the config file, type: `/commandlogger reload` to reload t
241241

242242
Fix bug: dropper may cause server crash
243243

244-
Please watch [kygo_life's bilibili video](https://www.bilibili.com/video/BV1HM411z7jz/?spm_id_from=333.999.0.0)
244+
The discoverer of this bug is player `kygo_life`, who [once posted an explanation on bilibili](https://www.bilibili.com/video/BV1HM411z7jz/?spm_id_from=333.999.0.0). However, it was deleted.
245+
246+
The triggering process of this bug is roughly as follows: First, build a structure similar to an item shadowing, but replace the box with a shulker box (which can be empty). At this time, open the trapdoor, destroy the shulker box, and the update suppression will be triggered.
247+
248+
Then place a dropper at the position of the shulker box, and then trigger it with a redstone signal (such as a lever), and boom!
249+
250+
This bug has been tested and available in `1.17.1`, but has not been tested in other versions.
251+
252+
General principle:
253+
254+
- After the shadow box is broken, the update suppression is triggered, so although the shadow box blocks are broken, the shulker box block entity are still exist.
255+
256+
- The dropper block is placed, the block is a dropper, but the block entity remains a shulker box.
257+
258+
- When triggered, the `DropperBlock.dispense (...)` method of that dropper will be called, and that method has the following code: (This line of code is exactly the same in `yarn` 1.17.1, 1.18.2, 1.19.3, 1.20.1)
259+
```
260+
DispenserBlockEntity dispenserBlockEntity = (DispenserBlockEntity)blockPointerImpl.getBlockEntity();
261+
^^^^^^^^^^
262+
class cast here! shulker block entity -> dispenser block entity
263+
```
264+
- So throwing `ClassCastException` during this can cause server crash(
245265

246266
- Default value: `false`
247267
- Acceptable value: `true` `false`

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,23 @@ CommandLogger.json配置文件可以配置白名单、黑名单等,修改配
248248

249249
修复了方块实体替换导致投掷器激活时崩服的bug
250250

251-
详情请看[kygo_life的视频](https://www.bilibili.com/video/BV1HM411z7jz/?spm_id_from=333.999.0.0)
251+
这个bug的发现人是玩家`kygo_life`[他曾经在B站发了一个解释](https://www.bilibili.com/video/BV1HM411z7jz/?spm_id_from=333.999.0.0),不过被删掉了。
252+
253+
这个bug的触发流程大致如下:首先建造一个类似于物品分身的结构,只不过将箱子换成潜影盒(可为空),此时打开活板门,打掉潜影盒,此时更新抑制会被触发,然后在原本
254+
潜影盒的位置上放置一个投掷器,然后用红石信号(如拉杆)触发此投掷器即可崩档。
255+
256+
本bug在`1.17.1`经测试可用,其他版本未测试。
257+
258+
大致原理:
259+
- 有点像方块实体替换,潜影盒被打掉后因为触发了更新抑制,所以虽说潜影盒方块被打掉了,但是方块实体仍保留
260+
- 投掷器方块被放置,方块是投掷器,方块实体仍为潜影盒
261+
- 触发时,那个投掷器的`DropperBlock.dispense(...)`方法会被调用,而那个方法有这样一段代码:(这行代码在`yarn`1.17.1、1.18.2、1.19.3、1.20.1完全相同)
262+
```
263+
DispenserBlockEntity dispenserBlockEntity = (DispenserBlockEntity)blockPointerImpl.getBlockEntity();
264+
^^^^^^^^^^
265+
进行了一次强转
266+
```
267+
- 所以在强转时抛出`ClassCastException`,崩服甚至崩档(
252268

253269
- Default value: `false`
254270
- Acceptable value: `true` `false`

src/main/java/io/github/optijava/opt_carpet_addition/mixins/rule/dropperCrashFix/DropperBlock_Mixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import io.github.optijava.opt_carpet_addition.OptCarpetAddition;
44
import io.github.optijava.opt_carpet_addition.OptCarpetSettings;
55
import net.minecraft.block.DropperBlock;
6-
import net.minecraft.block.entity.DispenserBlockEntity;
6+
import net.minecraft.block.entity.DropperBlockEntity;
77
import net.minecraft.server.world.ServerWorld;
88
import net.minecraft.util.math.BlockPos;
99
import org.spongepowered.asm.mixin.Mixin;
@@ -20,7 +20,7 @@ public class DropperBlock_Mixin {
2020
cancellable = true
2121
)
2222
public void injectDispense(ServerWorld world, BlockPos pos, CallbackInfo ci) {
23-
if (OptCarpetSettings.dropperCrashFix && !(world.getBlockEntity(pos) instanceof DispenserBlockEntity)) {
23+
if (OptCarpetSettings.dropperCrashFix && !(world.getBlockEntity(pos) instanceof DropperBlockEntity)) {
2424
OptCarpetAddition.LOGGER.fatal("[OptCarpetAddition] Detected dropper crash at %s [%s %s %s]".formatted(world.getRegistryKey().getValue().getPath(), pos.getX(), pos.getY(), pos.getZ()));
2525
ci.cancel();
2626
}

0 commit comments

Comments
 (0)