IzzelAliz / Arclight

A Bukkit(1.19/1.20) server implementation in modding environment using Mixin. ⚡
GNU General Public License v3.0
1.58k stars 230 forks source link

BlockBreakEvent执行过程中再次触发BlockBreakEvent时导致popResource产生的掉落物丢失 #674

Closed yanang007 closed 2 years ago

yanang007 commented 2 years ago

请确认您已完成以下几件事

Arclight 版本

arclight-1.18.2-1.0.7-SNAPSHOT-621c9499

Java 版本 | 操作系统

openjdk 17 | Windows 10

相关 Mod/插件 的名称及版本

plugins: 无
forge mods:
veinmining-forge-1.18.2-0.19.jar

错误描述

连锁挖矿附魔的实现包含两个要素:

  1. 监听 BlockBreakEvent ,触发时从当前方块A出发需要连锁挖掉的方块,在代码里手动触发挖矿会触发的事件,包括对被连锁的方块使用 onBlockBreakEvent 触发 BlockBreakEvent ,即在上一个 BlockBreakEvent 触发中途再次触发 BlockBreakEvent 。参考VeinMiningLogic.java。这会导致 ArclightCaptures#blockDrops 被意外地清理掉。 https://github.com/IzzelAliz/Arclight/blob/6a6a573a7d38b4bce2332b008dbe39def7d42f47/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightCaptures.java#L42-L46
  2. 手动触发完事件后,通过 popResource 把被连锁挖掉的方块掉落物加到当前掉落物中,但是由于每处理一个被连锁的方块 ArclightCaptures#blockDrops 都会被清理掉一次,最终的掉落物列表只会包含最后被处理的方块和最开始的方块A的掉落物,因此最终只会有两份掉落物。

forge的处理逻辑是在 popResource 时直接以实体加入到了世界中,因此不会受到影响。

感觉没必要存二次触发的事件,只要防止上下文捕获被意外清掉就好。 我有一个workaround是改用栈来存储事件,下面涉及捕获和重置的代码对应修改,在一次事件链中不重置 ArclightCaptures#blockDrops 来规避,但是我不是很清楚这会不会影响bukkit相关的逻辑,所以就不直接提pr了。 以下是部分workaround代码:

public class ArclightCaptures {
    // ...

    private static final Stack<BlockBreakEvent> blockBreakEvents = new Stack<>();
    // ...

    public static void captureBlockBreakPlayer(BlockBreakEvent event) {
        if (blockBreakEvents.size() == 0) {
            blockDrops = new ArrayList<>();
        }
        blockBreakEvents.push(event);
        blockBreakPlayerState = event.getBlock().getState();
    }
    // ...

复现步骤

  1. 安装连锁挖矿(veinmining-forge-1.18.2-0.19.jar
  2. 进入游戏,使用连锁挖矿附魔一个钻石镐
  3. 并排放置三个金矿石
  4. 使用附魔镐挖掘,三个金矿石都被破坏,但只掉落两个金矿石原矿

期望:掉落三个金矿石原矿

报错信息

无报错信息 https://paste.ubuntu.com/p/fb33nXmnzv/

复现用压缩包下载链接(可选)

No response

timi137137 commented 2 years ago

等你Pr(狗头) ps: pr就对了,有啥我们会提出的(点头)

yanang007 commented 2 years ago

你们是住在github吗.jpg(狗头)

timi137137 commented 2 years ago

没有,因为有hook,第一时间会收到信息(戳手指

heipiao233 commented 2 years ago

额,我用的是电子邮箱(

timi137137 commented 2 years ago

额,我用的是电子邮箱(

我说的是仓库的webhook