{"id":174,"date":"2025-08-29T11:13:17","date_gmt":"2025-08-29T03:13:17","guid":{"rendered":"http:\/\/154.9.252.233\/?p=174"},"modified":"2025-08-29T11:41:44","modified_gmt":"2025-08-29T03:41:44","slug":"%e6%88%91%e7%9a%84%e4%b8%96%e7%95%8c%e7%89%a9%e5%93%81%e6%94%b6%e9%9b%86%e6%ba%90%e7%a0%81%e6%8f%92%e4%bb%b6","status":"publish","type":"post","link":"https:\/\/web.mcfrys.cn\/index.php\/2025\/08\/29\/%e6%88%91%e7%9a%84%e4%b8%96%e7%95%8c%e7%89%a9%e5%93%81%e6%94%b6%e9%9b%86%e6%ba%90%e7%a0%81%e6%8f%92%e4%bb%b6\/","title":{"rendered":"\u6211\u7684\u4e16\u754c\u7269\u54c1\u6536\u96c6\u6e90\u7801\u63d2\u4ef6"},"content":{"rendered":"\n<p>\u6e90\u4ee3\u7801<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.example.sjrplugin;\n\nimport org.bukkit.Bukkit;\nimport org.bukkit.ChatColor;\nimport org.bukkit.Material;\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.configuration.file.FileConfiguration;\nimport org.bukkit.configuration.file.YamlConfiguration;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.block.Action;\nimport org.bukkit.event.player.PlayerInteractEvent;\nimport org.bukkit.inventory.EquipmentSlot;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.inventory.meta.ItemMeta;\nimport org.bukkit.plugin.java.JavaPlugin;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.logging.Level;\n\npublic class SJRPlugin extends JavaPlugin implements Listener {\nprivate FileConfiguration tasksConfig;\nprivate FileConfiguration materialsConfig;\nprivate File tasksFile;\nprivate File materialsFile;\n\n@Override\npublic void onEnable() {\n    \/\/ \u521b\u5efa\/\u52a0\u8f7d\u914d\u7f6e\u6587\u4ef6\n    if (!getDataFolder().exists()) {\n        getDataFolder().mkdir();\n    }\n\n    tasksFile = new File(getDataFolder(), \"tasks.yml\");\n    materialsFile = new File(getDataFolder(), \"materials.yml\");\n\n    if (!tasksFile.exists()) {\n        try {\n            tasksFile.createNewFile();\n        } catch (IOException e) {\n            getLogger().log(Level.SEVERE, \"\u65e0\u6cd5\u521b\u5efa\u4efb\u52a1\u914d\u7f6e\u6587\u4ef6\", e);\n        }\n    }\n\n    if (!materialsFile.exists()) {\n        try {\n            materialsFile.createNewFile();\n        } catch (IOException e) {\n            getLogger().log(Level.SEVERE, \"\u65e0\u6cd5\u521b\u5efa\u6750\u6599\u914d\u7f6e\u6587\u4ef6\", e);\n        }\n    }\n\n    tasksConfig = YamlConfiguration.loadConfiguration(tasksFile);\n    materialsConfig = YamlConfiguration.loadConfiguration(materialsFile);\n\n    \/\/ \u6ce8\u518c\u4e8b\u4ef6\u76d1\u542c\u5668\n    getServer().getPluginManager().registerEvents(this, this);\n\n    getLogger().info(\"\u7269\u54c1\u6536\u96c6\u4efb\u52a1\u63d2\u4ef6\u5df2\u542f\u7528!\");\n}\n\n@Override\npublic void onDisable() {\n    saveConfigs();\n    getLogger().info(\"\u7269\u54c1\u6536\u96c6\u4efb\u52a1\u63d2\u4ef6\u5df2\u7981\u7528!\");\n}\n\nprivate void saveConfigs() {\n    try {\n        tasksConfig.save(tasksFile);\n        materialsConfig.save(materialsFile);\n    } catch (IOException e) {\n        getLogger().log(Level.SEVERE, \"\u4fdd\u5b58\u914d\u7f6e\u6587\u4ef6\u65f6\u51fa\u9519\", e);\n    }\n}\n\n@Override\npublic boolean onCommand(CommandSender sender, Command command, String label, String&#91;] args) {\n    if (args.length == 0) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr &lt;create|delete|bind|rw|sj|setrw&gt; ...\");\n        return true;\n    }\n\n    String subCommand = args&#91;0].toLowerCase();\n\n    switch (subCommand) {\n        case \"create\":\n            return handleCreate(sender, args);\n        case \"delete\":\n            return handleDelete(sender, args);\n        case \"bind\":\n            return handleBind(sender, args);\n        case \"rw\":\n            return handleRW(sender, args);\n        case \"sj\":\n            return handleSJ(sender, args);\n        case \"setrw\":\n            return handleSetRW(sender, args);\n        default:\n            sender.sendMessage(ChatColor.RED + \"\u672a\u77e5\u547d\u4ee4\u3002\u7528\u6cd5: \/sjr &lt;create|delete|bind|rw|sj|setrw&gt; ...\");\n            return true;\n    }\n}\n\nprivate boolean handleCreate(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 3) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr create &lt;rw|cl&gt; &lt;\u540d\u79f0&gt;\");\n        return true;\n    }\n\n    String type = args&#91;1].toLowerCase();\n    String name = args&#91;2];\n\n    if (type.equals(\"rw\")) {\n        \/\/ \u521b\u5efa\u4efb\u52a1\n        if (tasksConfig.contains(\"tasks.\" + name)) {\n            sender.sendMessage(ChatColor.RED + \"\u4efb\u52a1 '\" + name + \"' \u5df2\u5b58\u5728!\");\n            return true;\n        }\n\n        tasksConfig.set(\"tasks.\" + name + \".commands\", new ArrayList&lt;String&gt;());\n        saveConfigs();\n        sender.sendMessage(ChatColor.GREEN + \"\u4efb\u52a1 '\" + name + \"' \u521b\u5efa\u6210\u529f!\");\n    } else if (type.equals(\"cl\")) {\n        \/\/ \u521b\u5efa\u6750\u6599\n        if (!(sender instanceof Player)) {\n            sender.sendMessage(ChatColor.RED + \"\u53ea\u6709\u73a9\u5bb6\u53ef\u4ee5\u6267\u884c\u6b64\u547d\u4ee4!\");\n            return true;\n        }\n\n        Player player = (Player) sender;\n        ItemStack item = player.getInventory().getItemInMainHand();\n\n        if (item.getType() == Material.AIR) {\n            sender.sendMessage(ChatColor.RED + \"\u4f60\u5fc5\u987b\u624b\u6301\u4e00\u4e2a\u7269\u54c1!\");\n            return true;\n        }\n\n        if (materialsConfig.contains(\"materials.\" + name)) {\n            sender.sendMessage(ChatColor.RED + \"\u6750\u6599 '\" + name + \"' \u5df2\u5b58\u5728!\");\n            return true;\n        }\n\n        ItemMeta meta = item.getItemMeta();\n        String displayName = meta.hasDisplayName() ? meta.getDisplayName() : \"\";\n        String lore = meta.hasLore() &amp;&amp; !meta.getLore().isEmpty() ? meta.getLore().get(0) : \"\";\n\n        materialsConfig.set(\"materials.\" + name + \".material\", item.getType().toString());\n        materialsConfig.set(\"materials.\" + name + \".displayname\", displayName);\n        materialsConfig.set(\"materials.\" + name + \".lore\", lore);\n        saveConfigs();\n\n        sender.sendMessage(ChatColor.GREEN + \"\u6750\u6599 '\" + name + \"' \u521b\u5efa\u6210\u529f!\");\n    } else {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr create &lt;rw|cl&gt; &lt;\u540d\u79f0&gt;\");\n        return true;\n    }\n\n    return true;\n}\n\nprivate boolean handleDelete(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 3) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr delete rw &lt;\u4efb\u52a1\u540d\u79f0&gt;\");\n        return true;\n    }\n\n    String type = args&#91;1].toLowerCase();\n    String name = args&#91;2];\n\n    if (type.equals(\"rw\")) {\n        if (!tasksConfig.contains(\"tasks.\" + name)) {\n            sender.sendMessage(ChatColor.RED + \"\u4efb\u52a1 '\" + name + \"' \u4e0d\u5b58\u5728!\");\n            return true;\n        }\n\n        tasksConfig.set(\"tasks.\" + name, null);\n        saveConfigs();\n        sender.sendMessage(ChatColor.GREEN + \"\u4efb\u52a1 '\" + name + \"' \u5220\u9664\u6210\u529f!\");\n    } else {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr delete rw &lt;\u4efb\u52a1\u540d\u79f0&gt;\");\n        return true;\n    }\n\n    return true;\n}\n\nprivate boolean handleBind(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 3) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr bind &lt;\u4efb\u52a1\u540d\u79f0&gt; &lt;\u547d\u4ee4&gt;\");\n        return true;\n    }\n\n    String taskName = args&#91;1];\n    if (!tasksConfig.contains(\"tasks.\" + taskName)) {\n        sender.sendMessage(ChatColor.RED + \"\u4efb\u52a1 '\" + taskName + \"' \u4e0d\u5b58\u5728!\");\n        return true;\n    }\n\n    String command = String.join(\" \", Arrays.copyOfRange(args, 2, args.length));\n    List&lt;String&gt; commands = tasksConfig.getStringList(\"tasks.\" + taskName + \".commands\");\n    commands.add(command);\n    tasksConfig.set(\"tasks.\" + taskName + \".commands\", commands);\n    saveConfigs();\n\n    sender.sendMessage(ChatColor.GREEN + \"\u547d\u4ee4\u5df2\u7ed1\u5b9a\u5230\u4efb\u52a1 '\" + taskName + \"'!\");\n    return true;\n}\n\nprivate boolean handleRW(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 2) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr rw &lt;list|listcommand&gt;\");\n        return true;\n    }\n\n    String sub = args&#91;1].toLowerCase();\n    if (sub.equals(\"list\")) {\n        Set&lt;String&gt; tasks = tasksConfig.getConfigurationSection(\"tasks\").getKeys(false);\n        if (tasks.isEmpty()) {\n            sender.sendMessage(ChatColor.YELLOW + \"\u6ca1\u6709\u53ef\u7528\u7684\u4efb\u52a1\u3002\");\n        } else {\n            sender.sendMessage(ChatColor.GREEN + \"\u53ef\u7528\u4efb\u52a1:\");\n            for (String task : tasks) {\n                sender.sendMessage(ChatColor.GRAY + \" - \" + task);\n            }\n        }\n    } else if (sub.equals(\"listcommand\")) {\n        if (args.length &lt; 3) {\n            sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr rw listcommand &lt;\u4efb\u52a1\u540d\u79f0&gt;\");\n            return true;\n        }\n\n        String taskName = args&#91;2];\n        if (!tasksConfig.contains(\"tasks.\" + taskName)) {\n            sender.sendMessage(ChatColor.RED + \"\u4efb\u52a1 '\" + taskName + \"' \u4e0d\u5b58\u5728!\");\n            return true;\n        }\n\n        List&lt;String&gt; commands = tasksConfig.getStringList(\"tasks.\" + taskName + \".commands\");\n        if (commands.isEmpty()) {\n            sender.sendMessage(ChatColor.YELLOW + \"\u4efb\u52a1 '\" + taskName + \"' \u6ca1\u6709\u7ed1\u5b9a\u4efb\u4f55\u547d\u4ee4\u3002\");\n        } else {\n            sender.sendMessage(ChatColor.GREEN + \"\u4efb\u52a1 '\" + taskName + \"' \u7ed1\u5b9a\u7684\u547d\u4ee4:\");\n            for (int i = 0; i &lt; commands.size(); i++) {\n                sender.sendMessage(ChatColor.GRAY + \" \" + (i + 1) + \". \" + commands.get(i));\n            }\n        }\n    } else {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr rw &lt;list|listcommand&gt;\");\n        return true;\n    }\n\n    return true;\n}\n\nprivate boolean handleSJ(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 4) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr sj add &lt;\u6750\u6599\u540d\u79f0&gt; &lt;\u6570\u91cf&gt;\");\n        return true;\n    }\n\n    if (!(sender instanceof Player)) {\n        sender.sendMessage(ChatColor.RED + \"\u53ea\u6709\u73a9\u5bb6\u53ef\u4ee5\u6267\u884c\u6b64\u547d\u4ee4!\");\n        return true;\n    }\n\n    Player player = (Player) sender;\n    if (!player.isOp()) {\n        sender.sendMessage(ChatColor.RED + \"\u4f60\u6ca1\u6709\u6743\u9650\u6267\u884c\u6b64\u547d\u4ee4!\");\n        return true;\n    }\n\n    String action = args&#91;1].toLowerCase();\n    if (action.equals(\"add\")) {\n        String materialName = args&#91;2];\n        if (!materialsConfig.contains(\"materials.\" + materialName)) {\n            sender.sendMessage(ChatColor.RED + \"\u6750\u6599 '\" + materialName + \"' \u4e0d\u5b58\u5728!\");\n            return true;\n        }\n\n        int amount;\n        try {\n            amount = Integer.parseInt(args&#91;3]);\n        } catch (NumberFormatException e) {\n            sender.sendMessage(ChatColor.RED + \"\u6570\u91cf\u5fc5\u987b\u662f\u6709\u6548\u7684\u6570\u5b57!\");\n            return true;\n        }\n\n        ItemStack item = player.getInventory().getItemInMainHand();\n        if (item.getType() == Material.AIR) {\n            sender.sendMessage(ChatColor.RED + \"\u4f60\u5fc5\u987b\u624b\u6301\u4e00\u4e2a\u7269\u54c1!\");\n            return true;\n        }\n\n        ItemMeta meta = item.getItemMeta();\n        List&lt;String&gt; lore = meta.hasLore() ? meta.getLore() : new ArrayList&lt;&gt;();\n\n        \/\/ \u68c0\u67e5\u662f\u5426\u5df2\u5b58\u5728\u8be5\u6750\u6599\u7684\u6536\u96c6\u8fdb\u5ea6\n        boolean found = false;\n        for (int i = 0; i &lt; lore.size(); i++) {\n            String line = ChatColor.stripColor(lore.get(i));\n            if (line.startsWith(materialName + \" (\")) {\n                lore.set(i, ChatColor.GRAY + materialName + \" (0\/\" + amount + \")\");\n                found = true;\n                break;\n            }\n        }\n\n        if (!found) {\n            lore.add(ChatColor.GRAY + materialName + \" (0\/\" + amount + \")\");\n        }\n\n        meta.setLore(lore);\n        item.setItemMeta(meta);\n        sender.sendMessage(ChatColor.GREEN + \"\u5df2\u6dfb\u52a0\u6750\u6599\u6536\u96c6\u8fdb\u5ea6\u5230\u624b\u6301\u7269\u54c1!\");\n    } else {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr sj add &lt;\u6750\u6599\u540d\u79f0&gt; &lt;\u6570\u91cf&gt;\");\n        return true;\n    }\n\n    return true;\n}\n\nprivate boolean handleSetRW(CommandSender sender, String&#91;] args) {\n    if (args.length &lt; 2) {\n        sender.sendMessage(ChatColor.RED + \"\u7528\u6cd5: \/sjr setrw &lt;\u4efb\u52a1\u540d\u79f0&gt;\");\n        return true;\n    }\n\n    if (!(sender instanceof Player)) {\n        sender.sendMessage(ChatColor.RED + \"\u53ea\u6709\u73a9\u5bb6\u53ef\u4ee5\u6267\u884c\u6b64\u547d\u4ee4!\");\n        return true;\n    }\n\n    Player player = (Player) sender;\n    String taskName = args&#91;1];\n\n    if (!tasksConfig.contains(\"tasks.\" + taskName)) {\n        sender.sendMessage(ChatColor.RED + \"\u4efb\u52a1 '\" + taskName + \"' \u4e0d\u5b58\u5728!\");\n        return true;\n    }\n\n    ItemStack item = player.getInventory().getItemInMainHand();\n    if (item.getType() == Material.AIR) {\n        sender.sendMessage(ChatColor.RED + \"\u4f60\u5fc5\u987b\u624b\u6301\u4e00\u4e2a\u7269\u54c1!\");\n        return true;\n    }\n\n    ItemMeta meta = item.getItemMeta();\n    List&lt;String&gt; lore = meta.hasLore() ? meta.getLore() : new ArrayList&lt;&gt;();\n\n    \/\/ \u68c0\u67e5\u662f\u5426\u5df2\u5b58\u5728\u4efb\u52a1\n    boolean found = false;\n    for (int i = 0; i &lt; lore.size(); i++) {\n        String line = ChatColor.stripColor(lore.get(i));\n        if (line.startsWith(\"&#91;\u4efb\u52a1] \")) {\n            lore.set(i, ChatColor.GREEN + \"&#91;\u4efb\u52a1] \" + taskName);\n            found = true;\n            break;\n        }\n    }\n\n    if (!found) {\n        lore.add(ChatColor.GREEN + \"&#91;\u4efb\u52a1] \" + taskName);\n    }\n\n    meta.setLore(lore);\n    item.setItemMeta(meta);\n    sender.sendMessage(ChatColor.GREEN + \"\u5df2\u8bbe\u7f6e\u624b\u6301\u7269\u54c1\u7684\u4efb\u52a1\u4e3a: \" + taskName);\n\n    return true;\n}\n\n@EventHandler\npublic void onPlayerInteract(PlayerInteractEvent event) {\n    if (event.getHand() != EquipmentSlot.HAND) return;\n\n    Player player = event.getPlayer();\n    ItemStack item = event.getItem();\n\n    if (item == null || item.getType() == Material.AIR) return;\n\n    if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {\n        \/\/ \u68c0\u67e5\u662f\u5426Shift+\u53f3\u952e\uff08\u5b8c\u6210\u4efb\u52a1\uff09\n        if (player.isSneaking()) {\n            handleTaskCompletion(player, item);\n        } else {\n            \/\/ \u666e\u901a\u53f3\u952e\uff08\u6536\u96c6\u6750\u6599\uff09\n            handleMaterialCollection(player, item);\n        }\n    }\n}\n\nprivate void handleMaterialCollection(Player player, ItemStack taskItem) {\n    ItemMeta meta = taskItem.getItemMeta();\n    if (!meta.hasLore()) return;\n\n    List&lt;String&gt; lore = meta.getLore();\n    boolean updated = false;\n\n    for (int i = 0; i &lt; lore.size(); i++) {\n        String line = ChatColor.stripColor(lore.get(i));\n        if (line.contains(\"(\") &amp;&amp; line.contains(\"\/\") &amp;&amp; line.contains(\")\")) {\n            \/\/ \u53ef\u80fd\u662f\u6750\u6599\u8fdb\u5ea6\u884c\n            String&#91;] parts = line.split(\"\\\\s+\\\\(\");\n            if (parts.length &lt; 2) continue;\n\n            String materialName = parts&#91;0];\n            if (!materialsConfig.contains(\"materials.\" + materialName)) continue;\n\n            String progressPart = parts&#91;1].replace(\")\", \"\");\n            String&#91;] progress = progressPart.split(\"\/\");\n            if (progress.length != 2) continue;\n\n            int current, required;\n            try {\n                current = Integer.parseInt(progress&#91;0]);\n                required = Integer.parseInt(progress&#91;1]);\n            } catch (NumberFormatException e) {\n                continue;\n            }\n\n            if (current &gt;= required) continue; \/\/ \u5df2\u7ecf\u5b8c\u6210\n\n            \/\/ \u83b7\u53d6\u6750\u6599\u5b9a\u4e49\n            String materialType = materialsConfig.getString(\"materials.\" + materialName + \".material\");\n            String displayName = materialsConfig.getString(\"materials.\" + materialName + \".displayname\");\n            String materialLore = materialsConfig.getString(\"materials.\" + materialName + \".lore\");\n\n            \/\/ \u5728\u73a9\u5bb6\u80cc\u5305\u4e2d\u67e5\u627e\u5339\u914d\u7684\u6750\u6599\n            for (ItemStack item : player.getInventory().getContents()) {\n                if (item == null || item.getType() == Material.AIR) continue;\n\n                ItemMeta itemMeta = item.getItemMeta();\n                boolean typeMatches = item.getType().toString().equals(materialType);\n                boolean nameMatches = (displayName.isEmpty() &amp;&amp; !itemMeta.hasDisplayName()) || \n                                     (itemMeta.hasDisplayName() &amp;&amp; itemMeta.getDisplayName().equals(displayName));\n                boolean loreMatches = (materialLore.isEmpty() &amp;&amp; (!itemMeta.hasLore() || itemMeta.getLore().isEmpty())) ||\n                                     (itemMeta.hasLore() &amp;&amp; !itemMeta.getLore().isEmpty() &amp;&amp; \n                                      itemMeta.getLore().get(0).equals(materialLore));\n\n                if (typeMatches &amp;&amp; nameMatches &amp;&amp; loreMatches) {\n                    int toCollect = Math.min(required - current, item.getAmount());\n                    item.setAmount(item.getAmount() - toCollect);\n                    current += toCollect;\n\n                    lore.set(i, ChatColor.GRAY + materialName + \" (\" + current + \"\/\" + required + \")\");\n                    updated = true;\n\n                    if (current &gt;= required) break;\n                }\n            }\n        }\n    }\n\n    if (updated) {\n        meta.setLore(lore);\n        taskItem.setItemMeta(meta);\n        player.sendMessage(ChatColor.GREEN + \"\u6750\u6599\u6536\u96c6\u8fdb\u5ea6\u5df2\u66f4\u65b0!\");\n    }\n}\n\nprivate void handleTaskCompletion(Player player, ItemStack taskItem) {\n    ItemMeta meta = taskItem.getItemMeta();\n    if (!meta.hasLore()) return;\n\n    List&lt;String&gt; lore = meta.getLore();\n    String taskName = null;\n\n    \/\/ \u67e5\u627e\u4efb\u52a1\u540d\u79f0\n    for (String line : lore) {\n        String plainLine = ChatColor.stripColor(line);\n        if (plainLine.startsWith(\"&#91;\u4efb\u52a1] \")) {\n            taskName = plainLine.substring(4);\n            break;\n        }\n    }\n\n    if (taskName == null || !tasksConfig.contains(\"tasks.\" + taskName)) {\n        player.sendMessage(ChatColor.RED + \"\u6b64\u7269\u54c1\u6ca1\u6709\u6709\u6548\u7684\u4efb\u52a1!\");\n        return;\n    }\n\n    \/\/ \u68c0\u67e5\u6240\u6709\u6750\u6599\u662f\u5426\u6536\u96c6\u5b8c\u6210\n    boolean allCompleted = true;\n    for (String line : lore) {\n        String plainLine = ChatColor.stripColor(line);\n        if (plainLine.contains(\"(\") &amp;&amp; plainLine.contains(\"\/\") &amp;&amp; plainLine.contains(\")\")) {\n            String&#91;] parts = plainLine.split(\"\\\\s+\\\\(\");\n            if (parts.length &lt; 2) continue;\n\n            String progressPart = parts&#91;1].replace(\")\", \"\");\n            String&#91;] progress = progressPart.split(\"\/\");\n            if (progress.length != 2) continue;\n\n            int current, required;\n            try {\n                current = Integer.parseInt(progress&#91;0]);\n                required = Integer.parseInt(progress&#91;1]);\n            } catch (NumberFormatException e) {\n                continue;\n            }\n\n            if (current &lt; required) {\n                allCompleted = false;\n                break;\n            }\n        }\n    }\n\n    if (!allCompleted) {\n        player.sendMessage(ChatColor.RED + \"\u6750\u6599\u6536\u96c6\u672a\u5b8c\u6210\uff0c\u65e0\u6cd5\u63d0\u4ea4\u4efb\u52a1!\");\n        return;\n    }\n\n    \/\/ \u6267\u884c\u4efb\u52a1\u547d\u4ee4\n    List&lt;String&gt; commands = tasksConfig.getStringList(\"tasks.\" + taskName + \".commands\");\n    for (String cmd : commands) {\n        String processedCmd = cmd.replace(\"%player%\", player.getName());\n        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), processedCmd);\n    }\n\n    \/\/ \u79fb\u9664\u7269\u54c1\n    taskItem.setAmount(taskItem.getAmount() - 1);\n    player.sendMessage(ChatColor.GREEN + \"\u4efb\u52a1 '\" + taskName + \"' \u5df2\u5b8c\u6210!\");\n}\n}<\/code><\/pre>\n\n\n\n<p>plugin.yml\u6587\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>name: SJRPlugin\nversion: 1.0\nmain: com.example.sjrplugin.SJRPlugin\napi-version: 1.20\ncommands:\nsjr:\ndescription: \u7269\u54c1\u6536\u96c6\u4efb\u52a1\u547d\u4ee4\nusage: \/sjr \u2026\npermission: sjr.use\npermission-message: \u4f60\u6ca1\u6709\u6743\u9650\u4f7f\u7528\u6b64\u547d\u4ee4\npermissions:\nsjr.use:\ndescription: \u5141\u8bb8\u4f7f\u7528\u7269\u54c1\u6536\u96c6\u4efb\u52a1\u547d\u4ee4\ndefault: op<\/code><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u4f7f\u7528\u8bf4\u660e<\/h2>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>\u521b\u5efa\u4efb\u52a1<\/strong>:\u00a0<code>\/sjr create rw \u4efb\u52a1\u540d\u5b57<\/code>\u00a0&#8211; \u521b\u5efa\u4e00\u4e2a\u65b0\u4efb\u52a1<\/li>\n\n\n\n<li><strong>\u5220\u9664\u4efb\u52a1<\/strong>:\u00a0<code>\/sjr delete rw \u4efb\u52a1\u540d\u5b57<\/code>\u00a0&#8211; \u5220\u9664\u4e00\u4e2a\u4efb\u52a1<\/li>\n\n\n\n<li><strong>\u7ed1\u5b9a\u547d\u4ee4<\/strong>:\u00a0<code>\/sjr bind \u4efb\u52a1\u540d\u5b57 \u547d\u4ee4<\/code>\u00a0&#8211; \u4e3a\u4efb\u52a1\u7ed1\u5b9a\u5b8c\u6210\u65f6\u6267\u884c\u7684\u547d\u4ee4\uff08\u652f\u6301 %player% \u53d8\u91cf\uff09<\/li>\n\n\n\n<li><strong>\u67e5\u770b\u4efb\u52a1\u5217\u8868<\/strong>:\u00a0<code>\/sjr rw list<\/code>\u00a0&#8211; \u67e5\u770b\u6240\u6709\u4efb\u52a1<\/li>\n\n\n\n<li><strong>\u67e5\u770b\u4efb\u52a1\u547d\u4ee4<\/strong>:\u00a0<code>\/sjr rw listcommand \u4efb\u52a1\u540d\u5b57<\/code>\u00a0&#8211; \u67e5\u770b\u4efb\u52a1\u7ed1\u5b9a\u7684\u547d\u4ee4<\/li>\n\n\n\n<li><strong>\u521b\u5efa\u6750\u6599<\/strong>:\u00a0<code>\/sjr create cl \u6750\u6599\u540d\u5b57<\/code>\u00a0&#8211; \u4fdd\u5b58\u624b\u6301\u7269\u54c1\u4e3a\u6750\u6599<\/li>\n\n\n\n<li><strong>\u6dfb\u52a0\u6750\u6599\u6536\u96c6<\/strong>:\u00a0<code>\/sjr sj add \u6750\u6599\u540d\u5b57 \u6570\u91cf<\/code>\u00a0&#8211; \u4e3a\u624b\u6301\u7269\u54c1\u6dfb\u52a0\u6750\u6599\u6536\u96c6\u8fdb\u5ea6<\/li>\n\n\n\n<li><strong>\u8bbe\u7f6e\u4efb\u52a1<\/strong>:\u00a0<code>\/sjr setrw \u4efb\u52a1\u540d\u5b57<\/code>\u00a0&#8211; \u4e3a\u624b\u6301\u7269\u54c1\u8bbe\u7f6e\u4efb\u52a1<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\u529f\u80fd\u8bf4\u660e<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u73a9\u5bb6\u624b\u6301\u4efb\u52a1\u7269\u54c1\u53f3\u952e\u53ef\u4ee5\u6536\u96c6\u80cc\u5305\u4e2d\u7684\u6750\u6599<\/li>\n\n\n\n<li>\u6750\u6599\u6536\u96c6\u5b8c\u6210\u540e\uff0cShift+\u53f3\u952e\u53ef\u4ee5\u5b8c\u6210\u4efb\u52a1<\/li>\n\n\n\n<li>\u4efb\u52a1\u5b8c\u6210\u540e\u4f1a\u6267\u884c\u7ed1\u5b9a\u7684\u547d\u4ee4\u5e76\u6d88\u8017\u4efb\u52a1\u7269\u54c1<\/li>\n\n\n\n<li>\u6750\u6599\u5339\u914d\u57fa\u4e8e\u7269\u54c1ID\u3001\u540d\u79f0\u548c\u7b2c\u4e00\u884cLore<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u6e90\u4ee3\u7801 plugin.yml\u6587\u4ef6 \u4f7f\u7528\u8bf4\u660e \u529f\u80fd\u8bf4\u660e<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-174","post","type-post","status-publish","format-standard","hentry","category-learn"],"_links":{"self":[{"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/posts\/174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/comments?post=174"}],"version-history":[{"count":8,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/posts\/174\/revisions"}],"predecessor-version":[{"id":183,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/posts\/174\/revisions\/183"}],"wp:attachment":[{"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/media?parent=174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/categories?post=174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/web.mcfrys.cn\/index.php\/wp-json\/wp\/v2\/tags?post=174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}