【问题标题】:Event when moving itemstack to other inventory将 itemstack 移动到其他库存时的事件
【发布时间】:2015-09-14 15:06:20
【问题描述】:

每次玩家发出特定命令时,都会根据 MySQL 表的内容生成虚拟库存,然后将其显示给玩家。效果很好。

现在,当玩家将物品从这个虚拟物品栏移动到他自己的物品栏中时,它应该检查物品是否仍在数据库中。如果没有,则应取消该活动。当玩家将物品从他的库存移动到虚拟库存时,它们应该被添加到数据库表中。

我对 MySQL 查询没有任何问题,但我不知道应该为事件使用哪个 EventHandler(Player Inv -> Virtual Inv,Virtual Inv -> Player Inv)。 Bukkit Inventory Events

InventoryMoveItemEvent 会很完美,但它只在方块(漏斗、分配器等)移动物品时调用,而不是玩家。

InventoryClickEvent 不是解决方案,因为将物品移动到另一个库存有很多不同的可能性:

  • 按住 Shift 键单击只会调用一次事件
  • 拾起物品并使用光标将其移动到其他物品栏会调用该事件两次。
  • 拿起一个物品堆并将其物品分散到其他库存中会调用InventoryClickEventInventoryDragEvent
  • 等等……

有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 我只有创建库存的代码(这里不需要)。由于我不知道应该使用哪个事件,所以我还没有任何事件代码。
  • 很遗憾,Bukkit 的库存事件有很多问题。您可以改用重复任务,清除插槽以模拟取消。
  • @FrancescoMenzani 使用 MySQL 查询重复任务不会导致服务器延迟,尤其是当一些玩家同时打开库存时?
  • 对,您应该为这些任务使用异步线程。您可以使用 Bukkit 调度程序(推荐)或 Java 内置并发 API,或两者兼而有之。

标签: bukkit inventory


【解决方案1】:

我对此有一个简单的解决方案,使用InventoryCloseEvent,然后在关闭时检查库存内容是否与数据库中的内容相同,如果不是,则使用新库存更新数据库,反之亦然。

【讨论】:

  • 工作,我可以锁定库存以防止在打开时从其他地方进行修改,并在数据库更新时在关闭时解锁它。但是玩家有一种方法可以欺骗无限的物品:玩家可以从物品栏中取出物品并在它仍然打开时退出,因此不会调用 InventoryCloseEvent 并且数据库永远不会更新。所以物品在数据库中在玩家的库存中。除此之外,玩家将无法再次访问库存,因为它仍处于锁定状态。我可以在退出时解锁它,但玩家可以作弊。
  • 您可以处理PlayerQuitEvent,然后只需执行player.closeInventory(),这样它就会强制退出时的InventoryCloseEvent
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
相关资源
最近更新 更多