Bukkit - 在YAML中查找玩家的名字

时间:2015-12-12 16:05:09

标签: java bukkit

我有这个插件,基本上玩家可以创建派对。它们的数据存储在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();

                            }
                        }

在esscense中,我被建议使用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)

2 个答案:

答案 0 :(得分:1)

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

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

通过这两项更改,您只需删除一方即可。

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!");
}

请注意,我假设玩家只能拥有一方。如果您希望玩家拥有多个参与者,则需要稍微更改一下您的代码(如果您可以让玩家成为多方的成员并希望循环播放他们所在的聚会,这也可能适用。)< / p>

/**
 * 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,可以(除其他外)迭代通过a 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())即可解决此问题(但如果您曾向玩家显示该名称,则需要将其保留为{ {1}})。

答案 1 :(得分:0)

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

view

如果您从控制台尝试命令“hello”,则会抛出CommandException。你没有显示你的其余代码,但过去我遇到了问题,所以可能是错的。