我是bukkit / spigot的新手,我正在制作一个插件,玩家可以输入命令' / sign'并且将在玩家旁边创建一个附在木块上的标志。该标志将显示' Hello PlayerName '。但是,我收到了错误:org.bukkit.command.CommandException: Unhandled exception executing command 'sign' in plugin
。
以下是我的代码的一部分:
if (cmd.getName().equalsIgnoreCase("sign") && sender instanceof Player){
Player player = (Player) sender;
Location location = player.getLocation();
World someWorld = Bukkit.getServer().getWorld("world");
double playerx = location.getX();
double playery = location.getY();
double playerz = location.getZ();
int px = (int)playerx;
int py = (int)playery;
int pz = (int)playerz;
Location nLoc = new Location(someWorld, px+2, py+1, pz);
Location sLoc = new Location(someWorld, px+1, py+1, pz);
Block block = someWorld.getBlockAt(nLoc);
block.setType(Material.WOOD);
Block block1 = someWorld.getBlockAt(sLoc);
block1.setType(Material.SIGN);
Sign sign = (Sign) block1.getState();
sign.setLine(0, "Hello\n"+player.getName());
}
如何解决此错误?
我在控制台上遇到的完整错误是:
[17:46:00 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'sign' in plugin FirstPlugin v1.0
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at org.bukkit.craftbukkit.v1_9_R1.CraftServer.dispatchCommand(CraftServer.java:645) ~[spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.PlayerConnection.handleCommand(PlayerConnection.java:1350) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.PlayerConnection.a(PlayerConnection.java:1185) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_71]
at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_71]
at net.minecraft.server.v1_9_R1.SystemUtils.a(SourceFile:45) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.MinecraftServer.D(MinecraftServer.java:721) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.DedicatedServer.D(DedicatedServer.java:400) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.MinecraftServer.C(MinecraftServer.java:660) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:559) [spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_71]
Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_9_R1.block.CraftBlockState cannot be cast to org.bukkit.block.Sign
at zak.firstplugin.FirstPlugin.onCommand(FirstPlugin.java:58) ~[?:?]
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.9.jar:git-Spigot-d20369f-7fc5cd8]
... 15 more
答案 0 :(得分:1)
如果将BlockState
的{{1}}强制转换为不是实例的子类,则会抛出此错误(如堆栈跟踪中的错误):Block
。换句话说,您的代码会抛出该错误,因为该块实际上不是org.bukkit.craftbukkit.[version].block.CraftBlockState cannot be cast to org.bukkit.block.[YourState]
,因为它的Sign
不是BlockState
的实例。将来,您始终可以使用Sign
进行检查,以确保可以将超类强制转换为特定的子类:
instanceof
即使您将其素材设置为if (block.getState() instanceof Sign) {
Sign sign = (Sign) block.getState();
// ... Your code
}
,您的块不是标志的原因是Material.SIGN
枚举器实际上是指项符号,而不是块类型,其中实际有两个(Material.SIGN
和Material.SIGN_POST
)。令人困惑的是,当您将Material.WALL_SIGN
的类型设置为项类型时,Bukkit / Spigot不会向您发出警告,而是将Block
的类型或材料设置为空中(因此{抛出{1}}。我猜测,因为你为标志产生了一个坚固的块,你可能想要后一个枚举器或Block
。
另外,为了确保标志上的文字出现,您需要使用ClassCastException
更新BlockState(甚至可能使用Material.WALL_SIGN
强制更新)。
要在下一行写下播放器的名称,您需要使用state.update()
将state.update(true)
添加到第2行(索引1),而不是使用String
换行符,哪个Minecraft标志不能处理。
最后但并非最不重要的是,您的案例中的墙壁标志将面向错误的方式,可以通过更改标志的旋转来修复。这取决于木块相对于标志的位置,因此在您的情况下,标志需要旋转到面向西方。要设置符号的旋转,我们可以对sign.setLine(1, player.getName())
s使用不推荐使用的\n
方法,但如果您想要使用不推荐的,更易读的方法,我们将不得不处理另一个小的quirk:有一个setData(byte data)
接口和一个Block
类。上述org.bukkit.block.Sign
的所有用法均指org.bukkit.material.Sign
接口,该接口是Sign
的子类型。这用于例如设置符号的文本。 org.bukkit.block.Sign
是我们可以使用BlockState
访问的org.bukkit.material.Sign
类的子类型,用于更改符号的方向,因为该类实现了MaterialData
接口(特别是state.getData()
接口)。因此,要设置文本和旋转符号,我们必须同时使用类和接口。以下是一些示例代码:
Directional