【问题标题】:Bukkit - Finding the Player's Name in the YAMLBukkit - 在 YAML 中查找玩家的名字
【发布时间】:2015-12-12 16:05:08
【问题描述】:

我有这个插件,基本上玩家可以创建派对。它们的数据存储在 YAML 文件中。

parties:
  mynewparteh:
    name: MyNewParteh
    leader: Dr_Derek
    balance: 0
    policies:
    - Default policy
    members:
    - Dr_Derek

我想这样做,例如,当党领袖运行“/party delete”时,它会首先检查他们是哪个党的成员,以及他们是否是领袖。

问题是,我不知道如何在不指定队伍本身的情况下检查一个玩家的名字是否属于一个队伍的成员列表?

                        int partyListLength = config.getConfigurationSection("parties").getKeys(false).size();
                        String[] partyList = config.getConfigurationSection("parties").getKeys(false).toArray(new String[partyListLength]);
                        for (int i = 0; i < partyListLength; i++)
                        {
                            if (config.getString("parties."+partyList[i]+".leader") == player.getName())
                            {
                                    player.sendMessage(ChatColor.GREEN + "Party deleted!");
                                    config.set("parties."+partyList[i], null);
                                    saveConfig();

                            }
                        }

本质上,有人建议我使用 getConfigurationSection(),然后我尝试将集合转换为数组,然后使用 for 循环遍历所有数据并检查玩家的姓名。问题出在控制台中,我得到 ArrayIndexOutOfBoundsException,所以显然将集合转换为数组存在问题,我需要一个数组才能使用索引。我该如何解决这个问题?

从控制台:

[20:50:03] [Server thread/ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'party' in plugin Parties v1.0
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:181) ~[craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServer.java:642) ~[craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.PlayerConnection.handleCommand(PlayerConnection.java:1105) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:940) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(PacketPlayInChat.java:26) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(PacketPlayInChat.java:53) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_40]
    at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_40]
    at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:683) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:316) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:623) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:526) [craftbukkit.jar:git-Spigot-b8f6402-a646500]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_40]
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
    at me.penghst.Parties.Main.onCommand(Main.java:212) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)

【问题讨论】:

  • 您能否在edit 您的帖子中包含出现在控制台中的 ArrayIndexOutOfBoundsException 的完整堆栈跟踪?
  • 好的...我看不出该异常会如何在您发布的代码的 sn-p 中引发。阅读this information on what a stack trace is,然后编辑您的问题以包含您的代码的那部分 - 我确实在您发布的 sn-p 中看到了一个错误,但只是更正它似乎并不能解决您的主要问题。

标签: java bukkit


【解决方案1】:

您的代码中的一个主要问题是您尝试使用== - that doesn't do what you might expect in java 比较领导者的姓名。相反,您应该使用.equals

此外,您不需要数组来搜索它(虽然数组可以工作,但它不是必需的)。相反,您可以使用for each loop,写作for (type name : collection)。这直接使用 getKeys 返回的 Set

通过这两项更改,您可以这样做来简单地删除一个派对。

for (String partyName : config.getConfigurationSection("parties").getKeys(false))
{
    if (config.getString("parties." + partyName + ".leader").equals(player.getName()))
    {
        player.sendMessage(ChatColor.GREEN + "Party " + partyName + " deleted!");
        config.set("parties." + partyName, null);
        saveConfig();
    }
}

但是,对于更一般的情况,这是一个获取玩家拥有的派对名称的方法:

/**
 * Gets the name of the party owned by the given player.
 * 
 * @returns The name of the party owned by the given player, or null if they don't own a party.
 */
public String getPartyOwnedByPlayer(Player player) {
    // If you've got a Configuration as a local variable, you can remove this line.
    Configuration config = getConfig();

    // Iterate through all of the party names using a for each loop.
    for (String partyName : config.getConfigurationSection("parties").getKeys(false))
    {
        // Check if the owner of the given party is the player.
        if (config.getString("parties." + partyName + ".leader").equals(player.getName()))
        {
            // Return the name of that party.
            return partyName;
        }
    }

    // The player didn't own a party.
    return null;
}

要使用该方法删除聚会,您需要执行以下操作:

String ownedPartyName = getPartyOwnedByPlayer(player);
if (ownedPartyName != null) {
    player.sendMessage(ChatColor.GREEN + "Party " + partyName + " deleted!");
    config.set("parties." + ownedPartyName, null);
} else {
    player.sendMessage(ChatColor.RED + "You don't own a party!");
}

请注意,我假设玩家只能拥有一个派对。如果您希望玩家拥有多个派对,则需要稍微更改您的代码(如果您可以让玩家成为多个派对的成员并且想要循环他们所在的派对,这也可能适用)。

/**
 * Gets the names of all parties owned by the given player.
 * 
 * @returns A list of names of the parties owned by the given player, or an empty if they don't own any parties.
 */
public List<String> getPartiesOwnedByPlayer(Player player) {
    // If you've got a Configuration as a local variable, you can remove this line.
    Configuration config = getConfig();

    // Create a new list - make sure you have imported java.util.List and java.util.ArrayList
    List<String> ownedParties = new ArrayList<String>();

    // Iterate through all of the party names using a for each loop.
    for (String partyName : config.getConfigurationSection("parties").getKeys(false))
    {
        // Check if the owner of the given party is the player.
        if (config.getString("parties." + partyName + ".leader").equals(player.getName()))
        {
            // Add that party name to the list.
            ownedParties.add(partyName);
        }
    }

    // Return the list of parties owned by that player.
    return ownedParties;
}

这会返回一个List,可以(除其他外)使用 for each 循环进行迭代。

要使用该方法的修改版本来删除玩家拥有的所有方,您可以执行以下操作:

List<String> ownedParties = getPartiesOwnedByPlayer(player);
if (ownedParties.isEmpty()) {
    player.sendMessage(ChatColor.RED + "You don't own any parties!");
} else {
    for (String partyName : ownedParties) {
        player.sendMessage(ChatColor.GREEN + "Party " + partyName + " deleted!");
        config.set("parties." + ownedPartyName, null);
    }
}

最后一点,如果您想处理用户名更改,则在存储他们时应该使用玩家的唯一 ID 而不是他们的名字。只需将调用 player.getName() 更改为 player.getUniqueId().toString()(使用 getUniqueId())即可解决此问题(但如果您曾经向玩家显示名称,则需要将其保留为 player.getName())。

【讨论】:

    【解决方案2】:

    您可能会收到此错误的另一个地方是,如果您从控制台发送命令,该命令会假定您是玩家,而无需检查。例如:

    public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
        String cmd = command.getName();
        if (cmd.equalsIgnoreCase("hello") {
            Player p = (Player) sender;
            p.sendMessage("Hi!");
        }
        return true;
    }
    

    如果您尝试从控制台执行命令“hello”,这将引发 CommandException。您没有显示其余代码,但我过去曾遇到过问题,因此可能是问题所在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多