PAPI Bridge - HimxhMC/HimDSL GitHub Wiki

PlaceholderAPI 桥接 / PAPI Bridge

与上一章的区别 / Difference from the Previous Chapter

上一章的 $player$、$world$ 是 HimDSL 自己解析的占位符。本章讲的 papi 系列桥接到 PlaceholderAPI——一个 Minecraft 生态里通用的占位符系统。其他插件可以通过 PlaceholderAPI 暴露数据,HimDSL 通过本章的函数读取。

The $player$, $world$ in the previous chapter are HimDSL's own placeholders. This chapter's papi family bridges to PlaceholderAPI — a general placeholder system in the Minecraft ecosystem. Other plugins expose data through PlaceholderAPI; HimDSL reads it via these functions.

这是 HimDSL 与外部插件交互的推荐方式**。比直接调 Java API 更简洁,不需要关心对方插件的类名和方法。

This is the recommended way for HimDSL to interact with other plugins — simpler than calling Java APIs directly, no need to know class names or method signatures.


前置条件 / Prerequisites

服务器上需要安装 PlaceholderAPI 插件。没有安装时,本章的函数不会报错,会返回空字符串。这是设计上的软依赖——你的脚本不会因为对方插件缺失而崩。

The server needs the PlaceholderAPI plugin. Without it, the functions here do not error; they return empty strings. This is intentional soft dependency — your script won't crash if the other plugin is missing.


papi:读取占位符 / papi: Read a Placeholder

PlaceholderAPI 的占位符写法是 %插件名_变量%,例如 %player_name%、%vault_eco_balance%。HimDSL 里去掉 %:

PlaceholderAPI placeholders look like %plugin_var%, e.g. %player_name%, %vault_eco_balance%. In HimDSL, drop the %:

string name = papi("player_name");
string balance = papi("vault_eco_balance");

也可以带 %:

Or include them:

string name = papi("%player_name%");       // 等价

需要玩家上下文的占位符,传第二个参数:

Placeholders needing a player context take a second argument:

var p = @p;
string balance = papi("vault_eco_balance", p);

第二个参数可以是引用、玩家名、或 OfflinePlayer:

The second argument may be a reference, a player name, or an OfflinePlayer:

papi("player_name", @p)
papi("player_name", "Steve")

papiSet:注册本地变量 / papiSet: Register a Local Variable

papiSet 不写入 PlaceholderAPI,而是在 HimDSL 内部注册一个本地变量,之后的 papi(key) 会优先返回它:

papiSet does not write into PlaceholderAPI; it registers a HimDSL-local variable that future papi(key) calls return first:

papiSet("server_motd", "欢迎光临");
string motd = papi("server_motd");      // "欢迎光临"

本地变量优先于 PlaceholderAPI。当同名占位符在两边都存在时,用本地值。

Local variables take priority over PlaceholderAPI. With a name clash, the local value wins.

日常脚本里 papiSet 用处不大。它的主要场景是给其他插件——你写了一个 HimDSL 脚本,其他插件想通过 %himdsl_server_motd% 读它——但 HimDSL 并不会自动把本地变量暴露给 PlaceholderAPI。所以这一用途需要额外配置,脚本里通常不需要。

papiSet is rarely useful in daily scripts. Its main scenario is for other plugins — you write a HimDSL script and other plugins want to read it as %himdsl_server_motd% — but HimDSL does not automatically expose locals to PlaceholderAPI. So this needs extra setup and is usually unnecessary.

日常脚本用不到 papiSet。知道有这个函数,用到时再查即可。

Daily scripts rarely need papiSet. Know it exists; look it up when you need it.


papiRegister / papiUnregister / papiHas

三个管理本地变量的函数:

Three management functions for local variables:

papiRegister("my_counter");     // 注册,初值为 ""
papiSet("my_counter", "10");    // 设置值
bool has = papiHas("my_counter");   // true
papiUnregister("my_counter");   // 移除

和 papiSet 一样,这些函数在日常脚本中很少用。

As with papiSet, these are rarely needed in daily scripts.


一个实用例子 / A Practical Example

场景:读取 Vault 经济插件的余额,在聊天里欢迎有钱的玩家。

Scenario: read Vault economy balance and welcome rich players in chat.

int main() {
    var players = @a;
    int total = players.size();

    for (int i = 0; i < total; i = i + 1) {
        var p = players.get(i);
        string balanceStr = papi("vault_eco_balance", p);
        double balance = toDouble(balanceStr);

        if (balance > 1000) {
            runcmd("CONSOLE", "say " + p.name + " 是富豪!");
        }
    }
}

papi 返回的总是字符串,需要数字时用 toDouble / toInt 转换。

papi always returns a string; convert with toDouble / toInt when a number is needed.


常见错误 / Common Mistakes

错误一:写成 %xxx% 的完整形式

两种写法都支持,但如果从 PlaceholderAPI 文档复制,记得**% 会一起被复制进去**:

string s = papi("%player_name%");        // ✓ 也行
string s = papi("player_name");          // ✓ 更简洁

两种都可以,选一种保持一致。

错误二:把 papi 当成"一定有值"

PlaceholderAPI 未安装时,papi 返回 ""。后续 toInt 会得到 0,toDouble 会得到 0.0——不会报错,但也没数据。

总是验证返回值:

string s = papi("player_name", p);
if (s == "") {
    // 处理缺失情况
}

错误三:找不到对应的 PlaceholderAPI 变量

papi("xxx") 返回空字符串不一定是错误——可能是对方插件没装、变量名拼错、或该玩家没有这个数据。用 /papi parse <player> <placeholder> 命令(如果 PAPI 装了调试功能)验证一下。

Mistake 1: %xxx% vs xxx

Both forms work; pick one and stay consistent.

Mistake 2: Assuming papi always has a value

Returns "" when the plugin is missing. Validate.

Mistake 3: Unresolved placeholder names

Empty result may mean missing plugin, wrong name, or no data for that player.


与直接调用 Java API 的对比 / Versus Calling Java APIs

PlaceholderAPI 覆盖的插件数量有限。如果某个插件不提供 PAPI 变量,只能通过 Java 互操作调用:

PlaceholderAPI only covers plugins that register variables. If a plugin does not, Java interop is the only way:

// 有 PAPI 变量时
string bal = papi("vault_eco_balance", p);

// 没有时(假设的 API)
var econ = SomeEconomyAPI.getBalance(p.uuid);

优先用 papi——它屏蔽了对方插件的具体实现,脚本更稳定。找不到对应 PAPI 变量时,再考虑 Java 互操作。

Prefer papi — it hides the other plugin's internals, making your script more stable. Fall back to Java interop only when no PAPI variable exists.


小结 / Summary

  • papi(key [, player]) 读 PlaceholderAPI 占位符,返回字符串。

  • 需要玩家上下文时传第二个参数。

  • 未安装 PlaceholderAPI 时返回空字符串,不报错。

  • papiSet / papiRegister / papiUnregister / papiHas 管理本地变量,日常脚本很少用。

  • papi 是与其他插件交互的推荐方式。

  • 找不到变量时再考虑 Java 互操作。

  • papi(key [, player]) reads PlaceholderAPI placeholders; returns a string.

  • Pass a second argument when player context is needed.

  • Returns "" when PlaceholderAPI is absent; no error.

  • papiSet / papiRegister / papiUnregister / papiHas manage local variables; rarely needed.

  • papi is the recommended way to interact with other plugins.

  • Fall back to Java interop only when no PAPI variable exists.


Minecraft 集成部分回顾 / Minecraft Integration Review

Minecraft 集成部分到此结束。四章覆盖了:选择器与过滤器、EntityRef 引用、占位符(兼容性参考)、PlaceholderAPI 桥接。

The Minecraft Integration section ends here. Four chapters covered: selectors and filters, EntityRef references, placeholders (compatibility reference), and the PlaceholderAPI bridge.

选择原则:

Decision guide:

  • 找实体 → 选择器。

  • 读/改实体数据 → 引用字段与方法(首选)。

  • 软依赖功能 → 占位符(只有这一条路)。

  • 与其他插件交互 → papi。

  • Locate entities → selectors.

  • Read/modify entity data → reference fields and methods (preferred).

  • Soft-dependency features → placeholders (only way).

  • Interact with other plugins → papi.

写新脚本时,只要引用能做到,就用引用。占位符只在它不可替代的地方出现。

When writing new scripts, use references wherever they work. Placeholders appear only where they are irreplaceable.


下一步 / Next Steps

下一部分进入事件与调度。第十章 @EventHandler 从最基础的事件监听写起。

The next part covers Events & Scheduling. Chapter @EventHandler starts with the basics of event listening.


⚠️ **GitHub.com Fallback** ⚠️