如何与箱子互动以打开它(Minecraft 1.16.5)

How to Interact with chest to open it (Minecraft 1.16.5)

我目前无法使用客户端在我的服务器上打开一个箱子 mod。我想为我的客户发送数据包,以便与我指定的箱子进行交互。我已经在 1.8 中实现了这个目标,我可以这样做:

BlockPos chestPos; // I got this from somewhere else, not important.

p.sendQueue.addToSendQueue(new C08PacketPlayerBlockPlacement(
        chestPos,(double)chestPos.getY()+0.5D < Minecraft.getMinecraft().thePlayer.posY + 1.7D ? 1:0,
        Minecraft.getMinecraft().thePlayer.getCurrentEquippedItem(),0.0F,0.0F,0.0F));

p.swingItem(); 

这让我的播放器在给定 BlockPos 时模仿与我胸部的互动。

现在我想将其翻译成 1.16.5 代码。我已经开始研究给定的方法,但我只能找到

ClientPlayerEntity player = Minecraft.getInstance().player;
player.swingArm(Hand.MAIN_HAND);

相当于 1.8 代码的最后一行,但这只会触发手臂的动画。

我能找到的替代 sendQueue 的最好的东西是 player.connection,它是 ClientPlayNetHandler 的一个实例。 class 有很多 handleXYZPacket(XYZPacket packet) 方法,但是 none 似乎很有用...

我最终放弃了post,继续我的搜索。不过我确实找到了解决方案,所以就在这里。我还想指出,网络上关于 1.16 包的文档大约为 0,所以我希望这对将来的人有用。

我决定在某个时候调查 net.minecraft.network.play.client 包中定义的所有数据包,并找到当时最接近解决方案的东西。我包含一个名为 CPlayerTryUseItemOnBlockPacket 的 class,这似乎正是我所需要的。但是,起初我能找到的所有用法都需要 ServerPlayerEntity,或者更确切地说是连接。不过最终...

经过一个非常令人沮丧的小时后,我终于让它工作了:

Minecraft.getInstance().player.connection.sendPacket(
new CPlayerTryUseItemOnBlockPacket(Hand.MAIN_HAND, blockRayTraceResult));

以下是我如何获得玩家当前正在查看的方块的 blockRayTraceResult:

public static BlockRayTraceResult getLookingAt() {
        PlayerEntity player = Minecraft.getInstance().player;
        World world = Minecraft.getInstance().world;
        double rayLength = 100d;
        Vector3d playerRotation = player.getLookVec();
        Vector3d rayPath = playerRotation.scale(rayLength);

        Vector3d from = player.getEyePosition(0);
        Vector3d to = from.add(rayPath);

        RayTraceContext rayCtx = new RayTraceContext(from, to, RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.ANY, player);
        return world.rayTraceBlocks(rayCtx);
    }