- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
打开PlayerInventory或更改内容时,我需要一个被调用的事件。
InventoryOpenEvent仅适用于箱子,炉子等,而不适用于PlayerInventory。
我正在将Java 1.6 SDK与Craftbukkit 1.7 API配合使用。
我的Minecraft TheWalls服务器上安装了插件ProWalls。现在,我正在编写一个自己的插件,应该扩展此插件。我的插件仅允许用户在游戏开始之前选择一个工具包,当游戏开始并且所有玩家被传送到其开始位置时,我的插件应添加之前选择的工具包的工具包项目。
现在的问题是,我需要片刻将玩家传送到生成点。
我首先用PlayerTeleportEvent尝试过,但这还为时过早。在ProWalls清除库存并添加自己的物料之前,将添加物料。
现在,我想用一个称为Event的事件进行尝试,将事件添加到播放器的清单中。然后,我可以检查添加的项目是否是ProWalls在游戏开始时添加的项目,如果属实,我将添加自己的项目。
ProWalls在开始时调用方法initGameSettings()来保存清单,清除清单并添加自己的物品。因此,另一种可能的解决方案是,在插件ProWalls调用自己的方法initGameSettings()时使事件被调用。但是我不知道这是否可行。
使用我当前的代码,我会在库存中稍后看到从套件中添加的物品,但几毫秒后,这些物品将被移除。如果没有其他解决方案,则可能需要使用计时器,计时器要等待几毫秒,然后添加项目。但是,正如我所发现的,这是没有好的解决方案...
为了更好地理解这里的顺序:
玩家加入TheWalls游戏,ProWalls插件调用initGameSettings(),插件清除玩家库存并添加自己的物品,现在我的插件应添加套件的物品。
最佳答案
主要编辑:在原始帖子下方包含NMS / OBC,以显示如何使用反射进行操作。Player
库存是通过选择Mojang缓存在客户端的。它在打开时不需要询问任何数据,因此除了服务器连接的初始请求外,它不会向服务器发送任何请求。没有方法只能在进行修改时测试库存何时打开。
我不太确定为什么除了某些按键触发之外还需要该事件。除非调用InvetoryClickEvent
,否则清单永远不会改变,因此,当玩家加入/进入需要跟踪其清单的状态时,只需扫描其清单一次,然后听InventoryClickEvent
即可处理更改。
编辑:存储不正确,因为服务器处理更改,缓存是一个更好的术语。
使用NMS / OBC:
使用反射和CraftBukkit / NMS类是可能的,但是这样做经常会发生变化,除非您将来需要对反射进行验证,否则插件将中断每次更新(有关此问题的教程非常丰富)。
当前问题:
Bukkit不允许您侦听来自Give命令或直接代码清单操纵的清单变化。因此,我们需要添加一种方法来侦听这些更改。最好的方法是覆盖更改库存的方法,并添加事件以简化将来的更改,或者在那里进行计算。我将解释后者,因为它更易于处理,并且还存在各种自定义事件教程。
设置环境:
使用NMS / OBC时,您需要导入CraftBukkit以获取所需的类。下载CraftBukkit jar,然后将其导入到您的项目中,但是通常这样做。如果您收到一些方法签名方法,请确保Bukkit的导入优先级更高。同样,教程也向您展示了如何在大多数IDE上修复该错误。
覆盖玩家库存:
我们需要做的第一件事是创建玩家清单类的子类。查看CraftPlayer
内部对象,我们看到它存储了一个CraftInventoryPlayer
类,而不是PlayerInventory
,因此,这是我们必须扩展的类。创建扩展CraftInventoryPlayer
的新类。确保它具有接受net.minecraft.server.VERSION.PlayerInventory
的构造函数。应该用当前的NMS / OBC版本字符串替换VERSION。当前版本为1.7.10,版本为v1_7_R4
。几乎每一次Minecraft版本更改都会改变这种情况,这是大多数版本错误的根源。通过扩展类和构造函数调用超级构造函数,您有了基本的自定义清单。现在,我们必须确定要覆盖的方法。
覆盖addAll
方法:
假设Essentials
和其他插件使用addAll
方法,这是我们需要监视的方法。我们要做的是重写addAll
方法,并将其功能包装在我们要进行的检查周围。在您的自定义清单类中,我们执行以下操作。
public HashMap<Integer, ItemStack> addItem(ItemStack... items) {
HashMap<Integer, ItemStack> leftovers = super.addItem(items);
//Examination code
return leftovers;
}
addItem
方法,但允许您检查返回值并检查实际添加到播放器清单中的内容。通过检查
items
和
leftovers
的差异,您可以准确地分辨出哪些项目以及向清单中添加了哪些项目,并在发生重要事件时调用自己的事件和方法。由于我不确定您要完成的工作,我将让您编写考试代码。
PlayerJoinEvent
和
PlayerQuitEvent
进行这些更改。
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
CraftPlayer craftPlayer = (CraftPlayer) event.getPlayer();
//I am not actually typing this code in an IDE, so feel free to change
//the try-catch block to only catch what is needed
try {
Field field = CraftHumanEntity.class.getDeclaredField("inventory");
field.setAccessible(true);
CraftInventoryPlayer originalInventory = (CraftInventoryPlayer) field.get(craftPlayer);
//Store inventory here, I will use a Map that would be declared above.
originalInventories.put(craftPlayer, originalInventory);
field.set(craftPlayer, new CustomInventory(craftPlayer.getHandle().inventory));
} catch (Exception e) {
Bukkit.getLogger.log(Level.SEVERE, "Error creating custom player inventory", e);
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
CraftPlayer craftPlayer = (CraftPlayer) event.getPlayer();
//I am not actually typing this code in an IDE, so feel free to change
//the try-catch block to only catch what is needed
try {
Field field = CraftHumanEntity.class.getDeclaredField("inventory");
field.setAccessible(true);
CraftInventoryPlayer originalInventory = originalInventories.get(craftPlayer);
//Store inventory here, I will use a Map that would be declared above.
field.set(craftPlayer, originalInventory);
} catch (Exception e) {
Bukkit.getLogger.log(Level.SEVERE, "Error replacing player inventory with original", e);
}
}
Bukkit
接口在
CraftBukkit
中都有相应的实现,该实现在接口名称前加上“ Craft”。有时单词顺序也会更改。在
PlayerJoinEvent
侦听器中,我们得到
CraftHumanEntity
类,并得到它的
inventory
字段。这是存储玩家库存的字段。它是私有的,因此我们使用
getDeclaredField
方法而不是
getField
方法,并且必须提供声明它的确切类。然后,我们使该字段可访问并处理其数据。对于玩家加入,我们
get
存储在该字段中的当前
CraftInventoryPlayer
,然后将其存储在其他位置以供以后检索。然后,将该字段
set
放入我们的自定义清单对象。请注意,构造函数接受
net.minecraft.server.PlayerInventory
,因此我们将清单提供给构造函数。我们终于捕获了这里可能发生的所有各种异常,并且我们已经成功覆盖了玩家的库存。在
PlayerQuitEvent
中,我们进行相反的操作,将自定义库存替换为原始库存,因为我们不再需要对其进行管理。
关于java - 用于打开PlayerInventory的Minecraft Bukkit API事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24962864/
我不知道为什么当我从南边或东边看时我的纹理按预期渲染,但从北边或西边看时却隐藏了它们后面的对象。 我有一个不可见的 block ,它在其中渲染多个项目,并且在处理具有半透明纹理的 block 时遇到问
我想写一个 Minecraft 模组来增加一种新型的生物。那可能吗?我看到,在 Bukkit, EntityType is a predefined enum ,这让我相信可能没有办法添加新类型的实体
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我一直在尝试使用 MCP 将 Minecraft 源代码反编译到 eclipse 工作区。我正在使用 mcp940 反编译 Minecraft 1.12。当我运行 BATCH 文件 decompile
我正在尝试制作模组,但遇到了这个问题。当我尝试创建工艺配方时,它使我的游戏崩溃。我真的不知道为什么。我尝试使用Items.COOKED_BEEF 还尝试了 Item.cooked_beef。我导入了我
我最近正在开发 Minecraft mod,在处理函数的返回语句时,我发现它需要一个 INBT 实例作为返回类型。我有一个自定义对象,需要将其转换为 INBT 类型的 NBT?这是函数: public
我已经开始制作模组,它没有注册为元素。当我键入 /give Fidojj222 fcm:fuel_canister 时,它应该给我该项目,除非它说它不存在!我正在使用 eclipse 作为我的 IDE
我用 Python 为 Minecraft 1.12.2 编写了一个启动器,它只是准备一个命令并使用子进程运行它。 这是在 Linux Ubuntu 上形成的命令: #!/usr/bin/env ba
我想创建一个应用程序服务器可以联系的 Web 服务,以将自身添加到实现该应用程序的服务器列表中。然后,客户端可以联系该服务以获取服务器列表。类似于 minecraft's heartbeats wor
我在带有 OpenJDK 的 headless Linux 服务器上运行 Minecraft。我已经添加了太多的 mods 和它的滞后(即使在我的本地网络上)而没有使用太多的 CPU 或内存(例如它滞
我正在尝试制作一个插件来消除 Minecraft 中的饥饿感。但是,我找不到它的事件! 是否有玩家失去饥饿感时调用的事件? 类似 PlayerHungerChangeEvent 的东西? 最佳答案 我
我熟悉的唯一模型是漫射照明,但这看起来比那复杂得多。 最佳答案 每个方块的亮度级别从 15 到 0。每个级别都比它上面的级别低 20%。如果一个正方形包含一个光源,它会得到那个光源的光度,否则它会比最
我在学习东西的过程中对我的世界插件开发非常陌生。我正在开发一个 jail 插件,并创建了一种方法,可以让玩家知道他们的库存是否已满。它不起作用,我不明白为什么。代码: public void
我在启动我的世界服务器时遇到错误。我用于插件的外部库是推荐的构建 craftbukkit-1.6.4-R2.0。我使用 craftbukkit-1.6.4-R2.0 来启动服务器并作为 eclipse
我想用 launchProjectile 编写我自己的武器系统,我使用的是 Arrow。但是我怎样才能在不增加传播的情况下增加箭头速度呢?代码如下: @Override public void sho
我正在为 Android 编写 Minecraft 红石模拟器。我正在使用 Dijkstra 的一些变体进行模拟,但我听说,真正的模拟器会做一些不同的事情,并在每个红石滴答声中更新每个红石 block
我在尝试获取 Minecraft 插件中的标志线值时遇到问题。这是我的代码: package pl.maccraft.regssal; import org.bukkit.plugin.java.Ja
我需要找到一种方法来检查我的世界用户名和密码是否有效。 我发现这个文档讲述了很多有关 Minecraft 身份验证的事情:http://wiki.vg/Authentication 看起来它需要一个
对于一个 Minecraft 项目,我想让玩家逐渐面对 (0, 60, 0)。到目前为止,当玩家围绕 (0, 60, 0) 移动超过 720° 时,我尝试的一切似乎都失败了。 有人知道如何让相机无缝移
尝试编写 Minecraft 插件代码时,当我在游戏中运行/fakeop 时出现外部错误。/fakeop (playername) 虽然有效 public class CortexTroll exte
我是一名优秀的程序员,十分优秀!