无法编辑符号 - Bukkit:org.bukkit.command.CommandException:插件 X 中执行命令 'sign' 时未处理的异常
Cannot edit sign - Bukkit: org.bukkit.command.CommandException: Unhandled exception executing command 'sign' in plugin X
我是 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.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
如果您将 Block
的 BlockState
转换为它不是其实例的子 class,则会抛出此错误(就像在您的堆栈跟踪中一样):org.bukkit.craftbukkit.[version].block.CraftBlockState cannot be cast to org.bukkit.block.[YourState]
。换句话说,您的代码会抛出该错误,因为该块实际上不是 Sign
,因为它的 BlockState
不是 Sign
的实例。将来,您可以随时检查使用 instanceof
以确保 superclass 可以转换为特定的 subclass:
if (block.getState() instanceof Sign) {
Sign sign = (Sign) block.getState();
// ... Your code
}
即使您将其 material 设置为 Material.SIGN
,您的方块也不是符号的原因是 Material.SIGN
枚举器实际上指的是符号 item 类型,不是块类型,实际上有两种(Material.SIGN_POST
和Material.WALL_SIGN
)。令人困惑的是,当您将 Block
的类型设置为项目类型时,Bukkit/Spigot 不会警告您,而是将 Block
的类型或 material 设置为空气(因此 ClassCastException
被抛出)。我猜既然你正在为标志生成一个实心块,你可能想要后者的枚举器或 Material.WALL_SIGN
.
此外,为了确保标牌上的文字出现,您需要使用 state.update()
更新 BlockState(甚至可能使用 state.update(true)
强制更新)。
要在下一行写下玩家的名字,您需要使用 sign.setLine(1, player.getName())
将 String
添加到第 2 行(索引 1),而不是使用 \n
换行符Minecraft 标志无法处理的角色。
最后但并非最不重要的一点是,您案例中的墙上标志将面向错误的方向,可以通过更改标志的旋转来解决。这当然取决于木块相对于标志的放置位置,因此在您的情况下,标志需要旋转面向西。要设置标志的旋转,我们可以对 Block
s 使用已弃用的 setData(byte data)
方法,但如果您想使用未弃用的、更易于阅读的方法,我们将不得不处理另一个小问题怪癖:有一个org.bukkit.block.Sign
接口,还有一个org.bukkit.material.Sign
class。 Sign
的所有用法都指的是 org.bukkit.block.Sign
接口,它是 BlockState
的子类型。这用于例如设置标志的文本。 org.bukkit.material.Sign
是 MaterialData
class 的子类型,我们可以使用 state.getData()
访问它并用于更改符号的方向,因为 class 实现了 Directional
接口(特别是 Attachable
接口)。因此,要设置文本 和 旋转符号,我们必须同时使用 class 和界面。这是一些示例代码:
Block sign = world.getBlockAt(signLoc); // Get the block
sign.setType(Material.WALL_SIGN); // Set the type to "WALL_SIGN", now it's BlockState is an instance of "Sign"
BlockState signState = sign.getState(); // Get the general state
if (signState instanceof org.bukkit.block.Sign) { // Make sure the sign block really does have the "Sign" BlockState (this isn't really necessary, more of a double check)
org.bukkit.block.Sign signBlock = (org.bukkit.block.Sign) signState; // Note that this is the org.bukkit.block.Sign interface
signBlock.setLine(0, "Hello"); // Set the first line
signBlock.setLine(1, player.getName()); // Set the second line
if (signState.getData() instanceof org.bukkit.material.Sign) { // Now get the "MaterialData" from the BlockState...
org.bukkit.material.Sign signMaterialData = (org.bukkit.material.Sign) signState.getData(); // And cast it to org.bukkit.material.Sign
signMaterialData.setFacingDirection(BlockFace.WEST); // Use this to change the direction of the sign, in this case WEST (sign is placed + X direction of player)
}
signBlock.update(); // Update the sign's state
}
我是 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.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
如果您将 Block
的 BlockState
转换为它不是其实例的子 class,则会抛出此错误(就像在您的堆栈跟踪中一样):org.bukkit.craftbukkit.[version].block.CraftBlockState cannot be cast to org.bukkit.block.[YourState]
。换句话说,您的代码会抛出该错误,因为该块实际上不是 Sign
,因为它的 BlockState
不是 Sign
的实例。将来,您可以随时检查使用 instanceof
以确保 superclass 可以转换为特定的 subclass:
if (block.getState() instanceof Sign) {
Sign sign = (Sign) block.getState();
// ... Your code
}
即使您将其 material 设置为 Material.SIGN
,您的方块也不是符号的原因是 Material.SIGN
枚举器实际上指的是符号 item 类型,不是块类型,实际上有两种(Material.SIGN_POST
和Material.WALL_SIGN
)。令人困惑的是,当您将 Block
的类型设置为项目类型时,Bukkit/Spigot 不会警告您,而是将 Block
的类型或 material 设置为空气(因此 ClassCastException
被抛出)。我猜既然你正在为标志生成一个实心块,你可能想要后者的枚举器或 Material.WALL_SIGN
.
此外,为了确保标牌上的文字出现,您需要使用 state.update()
更新 BlockState(甚至可能使用 state.update(true)
强制更新)。
要在下一行写下玩家的名字,您需要使用 sign.setLine(1, player.getName())
将 String
添加到第 2 行(索引 1),而不是使用 \n
换行符Minecraft 标志无法处理的角色。
最后但并非最不重要的一点是,您案例中的墙上标志将面向错误的方向,可以通过更改标志的旋转来解决。这当然取决于木块相对于标志的放置位置,因此在您的情况下,标志需要旋转面向西。要设置标志的旋转,我们可以对 Block
s 使用已弃用的 setData(byte data)
方法,但如果您想使用未弃用的、更易于阅读的方法,我们将不得不处理另一个小问题怪癖:有一个org.bukkit.block.Sign
接口,还有一个org.bukkit.material.Sign
class。 Sign
的所有用法都指的是 org.bukkit.block.Sign
接口,它是 BlockState
的子类型。这用于例如设置标志的文本。 org.bukkit.material.Sign
是 MaterialData
class 的子类型,我们可以使用 state.getData()
访问它并用于更改符号的方向,因为 class 实现了 Directional
接口(特别是 Attachable
接口)。因此,要设置文本 和 旋转符号,我们必须同时使用 class 和界面。这是一些示例代码:
Block sign = world.getBlockAt(signLoc); // Get the block
sign.setType(Material.WALL_SIGN); // Set the type to "WALL_SIGN", now it's BlockState is an instance of "Sign"
BlockState signState = sign.getState(); // Get the general state
if (signState instanceof org.bukkit.block.Sign) { // Make sure the sign block really does have the "Sign" BlockState (this isn't really necessary, more of a double check)
org.bukkit.block.Sign signBlock = (org.bukkit.block.Sign) signState; // Note that this is the org.bukkit.block.Sign interface
signBlock.setLine(0, "Hello"); // Set the first line
signBlock.setLine(1, player.getName()); // Set the second line
if (signState.getData() instanceof org.bukkit.material.Sign) { // Now get the "MaterialData" from the BlockState...
org.bukkit.material.Sign signMaterialData = (org.bukkit.material.Sign) signState.getData(); // And cast it to org.bukkit.material.Sign
signMaterialData.setFacingDirection(BlockFace.WEST); // Use this to change the direction of the sign, in this case WEST (sign is placed + X direction of player)
}
signBlock.update(); // Update the sign's state
}