AgentStack
SKILL verified MIT Self-run

Generate Message System

skill-mrpippi-mjp-claude-skills-generate-message-system · by MrPippi

依使用者提供的訊息鍵值清單,產生 messages.yml 設定檔與 MessageManager Java 類別,支援 MiniMessage / Legacy 格式、PlaceholderAPI 佔位符替換、前綴設定。當使用者說「幫我建立訊息系統」、「MessageManager」、「messages.yml」、「MiniMessage」時自動應用。

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add skill-mrpippi-mjp-claude-skills-generate-message-system

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Generate Message System? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Generate Message System Skill

目標

依使用者提供的訊息鍵值清單,自動產生:

  • messages.yml 設定檔(含前綴、所有訊息鍵值、繁體中文預設值)
  • MessageManager.java 工具類別(讀取、替換佔位符、傳送給玩家/控制台)

使用流程

  1. 詢問訊息鍵值清單:使用者列出需要的訊息 key(例:no-permission, reload-success
  2. 詢問格式化系統minimessage(推薦)或 legacy(舊版色碼)
  3. 詢問是否整合 PlaceholderAPI:是否需要 %player_name% 等佔位符
  4. 產生 messages.yml:含前綴與所有訊息鍵值的繁體中文預設值
  5. 產生 MessageManager.java:依選擇格式輸出對應版本
  6. 說明在主類中的初始化方式

輸入參數說明

| 參數 | 說明 | 範例 | |------|------|------| | message_keys | 訊息鍵值清單 | no-permission, player-only, reload-success | | format | 格式化系統 | minimessage(預設)或 legacy(&a, &c 色碼) | | use_papi | 是否整合 PlaceholderAPI | true / false |


代碼範本

1. messages.yml

# MPS — messages.yml
# 支援 MiniMessage 格式:https://docs.advntr.dev/minimessage/format.html
# 顏色標籤範例:成功、錯誤、警告
# 若使用 Legacy 格式(legacy: true),請使用 &a、&c、&e 等色碼。

prefix: "[MyPlugin] "

messages:
  no-permission: "你沒有執行此操作的權限。"
  player-only: "此指令僅限玩家執行。"
  reload-success: "設定檔已重新載入。"
  invalid-args: "用法錯誤。請輸入 / help 查看說明。"

規則:

  • 前綴統一放在 prefix 鍵,MessageManager 自動附加
  • MiniMessage 格式使用 ` 語法;Legacy 格式使用 &` 色碼
  • 使用 {placeholder} 表示動態替換的佔位符

2. MessageManager.java(MiniMessage 版本)

package com.example.myplugin.manager;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.util.Map;

/**
 * MyPlugin 訊息管理員
 * 從 messages.yml 讀取訊息,支援 MiniMessage 格式與佔位符替換。
 */
public class MessageManager {

    private static final MiniMessage MM = MiniMessage.miniMessage();

    private final JavaPlugin plugin;
    private FileConfiguration messages;
    private String prefix;

    public MessageManager(JavaPlugin plugin) {
        this.plugin = plugin;
        reload();
    }

    /** 重新載入 messages.yml */
    public void reload() {
        File file = new File(plugin.getDataFolder(), "messages.yml");
        if (!file.exists()) {
            plugin.saveResource("messages.yml", false);
        }
        messages = YamlConfiguration.loadConfiguration(file);
        prefix = messages.getString("prefix", "[Plugin] ");
    }

    /**
     * 取得訊息 Component(已附加前綴)
     *
     * @param key         messages.yml 中的鍵(例如 "no-permission")
     * @param placeholders 成對的鍵值替換(例如 "player", player.getName())
     */
    public Component get(String key, Map placeholders) {
        String raw = messages.getString("messages." + key, "Missing message: " + key + "");

        TagResolver.Builder resolver = TagResolver.builder();
        placeholders.forEach((k, v) ->
            resolver.resolver(Placeholder.parsed(k, v))
        );

        Component msg = MM.deserialize(raw, resolver.build());
        Component pre = MM.deserialize(prefix);
        return pre.append(msg);
    }

    /** 取得訊息 Component(無佔位符替換) */
    public Component get(String key) {
        return get(key, Map.of());
    }

    /** 傳送訊息給 CommandSender */
    public void send(CommandSender sender, String key, Map placeholders) {
        sender.sendMessage(get(key, placeholders));
    }

    /** 傳送訊息給 CommandSender(無佔位符替換) */
    public void send(CommandSender sender, String key) {
        sender.sendMessage(get(key));
    }
}

3. MessageManager.java(Legacy 版本)

package com.example.myplugin.manager;

import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.util.Map;

/**
 * MyPlugin 訊息管理員(Legacy 色碼版)
 * 從 messages.yml 讀取訊息,支援 & 色碼與簡單字串替換。
 */
public class MessageManager {

    private final JavaPlugin plugin;
    private FileConfiguration messages;
    private String prefix;

    public MessageManager(JavaPlugin plugin) {
        this.plugin = plugin;
        reload();
    }

    public void reload() {
        File file = new File(plugin.getDataFolder(), "messages.yml");
        if (!file.exists()) {
            plugin.saveResource("messages.yml", false);
        }
        messages = YamlConfiguration.loadConfiguration(file);
        prefix = color(messages.getString("prefix", "&8[Plugin]&r "));
    }

    public String get(String key, Map placeholders) {
        String raw = messages.getString("messages." + key, "&cMissing message: " + key);
        for (Map.Entry entry : placeholders.entrySet()) {
            raw = raw.replace("{" + entry.getKey() + "}", entry.getValue());
        }
        return prefix + color(raw);
    }

    public String get(String key) {
        return get(key, Map.of());
    }

    public void send(CommandSender sender, String key, Map placeholders) {
        sender.sendMessage(get(key, placeholders));
    }

    public void send(CommandSender sender, String key) {
        sender.sendMessage(get(key));
    }

    private static String color(String text) {
        return ChatColor.translateAlternateColorCodes('&', text);
    }
}

PlaceholderAPI 整合(選用)

use_papi: true 時,在 get() 方法中加入 PAPI 解析:

// 在 messages.yml 中可使用 %player_name%、%vault_eco_balance% 等
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.entity.Player;

public Component get(Player player, String key, Map placeholders) {
    String raw = messages.getString("messages." + key, "Missing: " + key + "");
    // PAPI 解析(需先替換 PAPI 佔位符,再做 MiniMessage 解析)
    if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
        raw = PlaceholderAPI.setPlaceholders(player, raw);
    }
    // ... 後續 MiniMessage 解析同上
}

在主類中初始化

private MessageManager messageManager;

@Override
public void onEnable() {
    saveResource("messages.yml", false);
    this.messageManager = new MessageManager(this);
}

public MessageManager getMessageManager() {
    return messageManager;
}

常見錯誤與修正

| 錯誤 | 原因 | 修正 | |------|------|------| | missing message: xxx 顯示在遊戲中 | messages.yml 中找不到該 key | 確認鍵名拼寫正確,確保 messages.yml 包含該 key | | MiniMessage 標籤未渲染(顯示原始 `)| 使用 Legacy 模式但訊息是 MiniMessage 格式 | 確認 format 設定與訊息格式一致 | | FileNotFoundException 於 reload() | messages.yml 不存在且未呼叫 saveResource | 在 onEnable() 呼叫 saveResource("messages.yml", false) | | PlaceholderAPI 佔位符未替換 | PAPI 未安裝或 setPlaceholders() 未呼叫 | 確認伺服器已安裝 PlaceholderAPI,且 use_papi: true 時有正確整合 | | 前綴重複出現 | 在 messages.yml 的訊息值中又加了前綴 | 前綴統一由 MessageManager` 附加,訊息值本身不含前綴 |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.