如何与箱子互动以打开它(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);
}
我目前无法使用客户端在我的服务器上打开一个箱子 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);
}