运行 命令时崩溃

Crash when running a command

代码

主类:http://pastebin.com/U99LAQ6z
监听类:http://pastebin.com/ZF5i8mw1

说明

我正在开发我的插件,目前正在开发创建大厅的部分。基本上我所做的是当玩家用位置魔杖左键单击时,他们设置点 1,当他们右键单击时,他们设置点 2。我有一个方块 select 或那个 selects第一个块然后它 selects Y 上的所有块和 Z 上的所有块,然后是 X 上的所有块,直到它们等于 point2。它将这些块中的每一个记录到一个 HashMap 中,这样我就可以在以后需要时调用这些块。我的问题是我认为我有一个无限循环或类似的东西,因为控制台给我一个错误。有时它还会给我更长的堆栈跟踪,我只是对此感到困惑。

所以我想做的是创建一个简单的基础,我将把它用于我未来所有需要定义区域的插件。这应该做的是当玩家 运行 的命令位置时,它会为他们提供一个工具,让他们 select 点。左键单击 selects point1 和右键单击 selects point2。我使用 getPoint1 和 getPoint2 来获取它们,因为我将这些点存储在 HashMap 中。一旦玩家 select 编辑了点,他们 运行 命令 /lobbycreate (lobbyname) 并且当他们 运行 命令时,假设获取并存储给定点内的所有块。为此,我使用了一系列 for 循环。首先,我有变量 blockSelector。我希望 blockSelector 从 getPoint1 开始并转到 getPoint2 selecting 两点之间的所有块。然后我们转到我的第一个 for 循环,其中 blockSelector.getBlockX() != getPoint2X,getPoint2X 是我用来获取 getPoint2 的 X 坐标的变量。这一点是所有这个循环和这个循环中的所有循环都将继续,直到 blockSelector 和 getPoint2X 具有相同的值。在这个循环中,我有另一个循环做同样的事情,除了 Z 坐标,因此它 select 是 Z 坐标上的所有块,但只有在它在其中执行循环之后 select s Y 坐标上的所有块。在完成所有这些之后,我根据 replaceVar 是什么来添加或减去 1,然后重复循环,直到 blockSelector 的所有 3 个坐标都等于 getPoint2,从而保存过程中的所有块。我拥有所有这些 if 语句和 replaceVar 的原因是因为当 selecting 坐标玩家可以 select 负坐标和正坐标并且 getPoint1 可能大于或小于 getPoint2 所以我必须添加或根据2个值减去。

控制台输出

jobisingh issued server command: /lobbycreate gulp
[09:46:50 ERROR]: The server has stopped responding!
[09:46:50 ERROR]: Please report this to http://www.spigotmc.org/
[09:46:50 ERROR]: Be sure to include ALL relevant console errors and Minecraft crash reports
[09:46:50 ERROR]: Spigot version: git-Spigot-b2c2c63-a3cb1bc (MC: 1.8.7)
[09:46:50 ERROR]: ------------------------------
[09:46:50 ERROR]: Server thread dump (Look for plugins here before reporting to Spigot!):
[09:46:50 ERROR]: ------------------------------
[09:46:50 ERROR]: Current Thread: Server thread
[09:46:50 ERROR]:       PID: 17 | Suspended: false | Native: false | State: RUNNABLE
[09:46:50 ERROR]:       Stack:
[09:46:50 ERROR]:               java.util.HashMap.put(Unknown Source)
[09:46:50 ERROR]:                   me.jobisingh.MainClass.onCommand(MainClass.java:223)
[09:46:50 ERROR]:               org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
[09:46:50 ERROR]:               org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141)
[09:46:50 ERROR]:               org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:640)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1149)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:984)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.PlayerConnectionUtils.run(SourceFile:13)
[09:46:50 ERROR]:               java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
[09:46:50 ERROR]:               java.util.concurrent.FutureTask.run(Unknown Source)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.SystemUtils.a(SystemUtils.java:19)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:714)
[09:46:50 ERROR]:                 net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:653)
[09:46:50 ERROR]:               net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:556)
[09:46:50 ERROR]:               java.lang.Thread.run(Unknown Source)
[09:46:50 ERROR]: ------------------------------
[09:46:50 ERROR]: Entire Thread Dump:
[09:46:50 ERROR]: ------------------------------
[09:46:50 ERROR]: Current Thread: Chunk I/O Executor Thread-1
[09:46:50 ERROR]:       PID: 38 | Suspended: false | Native: false | State: WAITING
[09:46:50 ERROR]:       Stack:
> Press any key to continue . . .

我很确定这三个循环是 运行 无限期的:

for(; blockSelector.getBlockX() != getPoint2X; blockSelector.setX(replaceVarX))
{
    for(; blockSelector.getBlockZ() != getPoint2Z; blockSelector.setZ(replaceVarZ) )
    {
        for(; blockSelector.getBlockY() != getPoint2Y; blockSelector.setY(replaceVarY))
        {
            lobbies.put(blockSelector.getBlockY(), blockSelector);
        }
        lobbies.put(blockSelector.getBlockZ(), blockSelector);
    }
    lobbies.put(blockSelector.getBlockZ(), blockSelector);
}

我以 X 为例,但 YZ 完全相同。

你的循环只要 replaceVarX != getPoint2X.
然而,replaceVarX在循环内部永远不会改变,所以有两种可能:

  • replaceVarX == getPoint2X
    循环运行一次。
  • replaceVarX != getPoint2X
    循环无限期地运行。

但是,您要确保第一个永远不会是这种情况:

if(getPoint1X > 0 && getPoint2X > 0 && getPoint1X < getPoint2X)
{
    replaceVarX = blockSelector.getBlockX() + 1;
}
else if(getPoint1X > 0 && getPoint2X > 0 && getPoint1X > getPoint2X)
{
    replaceVarX = blockSelector.getBlockX() - 1;
}
else if (getPoint1X < 0 && getPoint2X < 0 && getPoint1X < getPoint2X)
{
    replaceVarX = blockSelector.getBlockX() + 1;
}
else if (getPoint1X < 0 && getPoint2X < 0 && getPoint1X > getPoint2X)
{
    replaceVarX = blockSelector.getBlockX() - 1;
}
else if (getPoint1X > 0 && getPoint2X < 0)
{
    replaceVarX = blockSelector.getBlockX() - 1;
}
else if (getPoint1X < 0 && getPoint2X > 0)
{
    replaceVarX = blockSelector.getBlockX() + 1;
}
else if (getPoint1Z < 0 && getPoint2Z < 0 && getPoint1Z < getPoint2Z)
{
    replaceVarX = blockSelector.getBlockX() + 1;
}

要解决此问题,您必须将所有 if / else 移动到循环内,以便变量得到相应更新。
不过,您必须在循环中将它们分开,以便 replaceVarX 在外循环中更新, replaceVarZ 在中间循环中更新, replaceVarY 在内部循环中更新,否则你打破外面的两个循环。

一种(可能更有效的)替代方法是用循环外的变量替换 replaceVarX,该变量定义 x、y 和 y 的方向(-1+1) z 每个(我将它们称为 dxdydz),然后将 blockSelector.setX(replaceVarX) 替换为 blockSelector.setX(blockSelector.getBlockX() + dx)
这样你就可以避免在这些循环中大量冗余检查(以及计算时间)。