public class BoxScreenHandler extends ScreenHandler { //我们保存从服务器获得的 blockPos 并为其提供一个 getter,以便 BoxScreen 可以读取该信息 private BlockPos pos; private final Inventory inventory; //当服务器(Server)希望它打开 screenHandler 时,在客户端(Cilent)上调用此构造函数, //客户端将使用一个空的 Inventory 调用超级构造函数,并且 screenHandler 将自动将此空库存与服务器上的库存同步。 //新:客户端的构造函数现在获取我们在 BlockEntity 中填充的 PacketByteBuf public BoxScreenHandler(int syncId, PlayerInventory playerInventory, PacketByteBuf buf) { this(syncId, playerInventory, new SimpleInventory(9)); pos = buf.readBlockPos(); } //此构造函数从服务器上的 BlockEntity 调用,服务器知道容器的库存(你可以将它理解为物品栏),因此可以直接将其作为参数提供。 然后,此库存(物品栏)将同步到客户端。 public BoxScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) { //[...] //有关其余代码,请参阅第一个 Screenhandler 教程 //想一想,为什么我们在这里使用 BlockPos.ORIGIN? //This is because the packetByteBuf with our blockPosition is only availible on the Client, so we need a placeholder //value here. This is not a problem however, as the Server version of the ScreenHandler does not really need this //information. //(机翻警告)这是因为带有我们 blockPosition 的 packetByteBuf 仅在 Client 上可用,所以我们这里需要一个占位符值。 然而,这不是问题, //因为 ScreenHandler 的服务器版本并不真正需要此信息。 pos = BlockPos.ORIGIN; [...] } //这个 getter 将被我们的 Screen 类使用 public BlockPos getPos() { return pos; } @Override public boolean canUse(PlayerEntity player) { return this.inventory.canPlayerUse(player); } // 参阅 Screenhandler 教程 // Shift + Player Inv Slot @Override public ItemStack transferSlot(PlayerEntity player, int invSlot); }