Paper API · Paper 指令
Paper Brigadier 指令
以 Paper Brigadier API 註冊指令:LifecycleEvents.COMMANDS、內建與自訂參數(k/m/b 金額)、權限 requires、補全只讀快照與 reload 子指令。
paper-brigadier-command更新於 2026年10月9日觸發關鍵字
Brigadier指令補全LifecycleEvents.COMMANDSCommands.literal自訂參數型別金額 k m bPaper Brigadier Command
目的
用 Paper 的 Brigadier API 註冊有型別參數、有補全、有分層權限的指令。內建 ArgumentTypes(玩家選擇器、世界、物品、座標…)由伺服器解析;自訂參數(例如 1.5k / 2m / 1b 金額)解析失敗時回傳清楚的聊天欄錯誤。
簡單、不需補全的指令仍可留在 plugin.yml 的 commands: + getCommand();同一個指令不可兩種方式都宣告。
平台需求
- Paper 1.21.11 / 26.2(兩版皆經編譯驗證)
- 純 Paper API,不需要 Paperweight
- 唯一差異:
CommandSourceStack#getPlayerOrThrow()只在 26.2;1.21.11 以getExecutor()判斷
產生的代碼
註冊(onEnable)
public final class ExamplePlugin extends JavaPlugin {
@Override
public void onEnable() {
PayCommand pay = new PayCommand((from, to, amount) -> PayService.Result.OK);
getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, event -> {
Commands registrar = event.registrar();
registrar.register(pay.build(), "Pay another player", List.of("transfer"));
});
}
}
/pay <player> <amount>
import com.mojang.brigadier.Command;
import com.mojang.brigadier.tree.LiteralCommandNode;
LiteralCommandNode<CommandSourceStack> node = Commands.literal("pay")
.requires(CommandSupport.permission("example.pay"))
.then(Commands.argument("target", ArgumentTypes.player())
.then(Commands.argument("amount", new AmountArgumentType())
.executes(context -> Command.SINGLE_SUCCESS)))
.build();
自訂 k/m/b 金額參數
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.OptionalLong;
public final class AmountArgumentType implements CustomArgumentType.Converted<Long, String> {
@Override
public Long convert(String nativeType) throws CommandSyntaxException {
OptionalLong parsed = Amounts.parse(nativeType); // 1.5k -> 1500
if (parsed.isEmpty()) {
throw CommandSupport.error("<red>Invalid amount <input>.", Placeholder.unparsed("input", nativeType));
}
return parsed.getAsLong();
}
@Override
public ArgumentType<String> getNativeType() { return StringArgumentType.word(); }
}
規則
- 權限用
getSender()檢查,針對自己的操作用getExecutor() - 成功回
Command.SINGLE_SUCCESS;失敗throw指令例外,不要回0再自己印訊息 - 玩家輸入進 MiniMessage 一律用
Placeholder.unparsed - 權限在
plugin.yml的permissions:宣告並給明確 default;使用 Brigadier 時不寫commands: paper-plugin.yml沒有commands:;bootstrap 註冊用PluginBootstrap#bootstrap+LifecycleEvents.COMMANDS
執行緒安全
executes在主執行緒;耗時工作自行丟非同步並回主執行緒回覆suggests不保證在主執行緒:只讀不可變快照,不查資料庫、不走訪可變集合