Skip to content

常见问题

变量为什么返回空文本

依次检查以下内容:

  1. 使用的变量格式是否正确:

    变量用途
    %lyplaceholder_player_变量ID%读取当前玩家的玩家变量
    %lyplaceholder_server_变量ID%读取服务器共用变量
    %lyplaceholder_countdown_player_规则ID%读取玩家刷新规则的触发倒计时
    %lyplaceholder_countdown_server_规则ID%读取服务器刷新规则的触发倒计时
  2. PlaceholderAPI 是否已经安装并正常启用。PlaceholderAPI 是可选依赖,但未安装时无法通过其他插件读取上述变量,也无法计算使用 PAPI 的刷新条件和脚本。

  3. 玩家变量是否在具有玩家上下文的位置读取。服务器变量不需要玩家上下文。

  4. 对应变量是否已经通过管理指令或刷新脚本中的 设置值() 创建。刷新规则 ID 不会自动创建同名变量。

  5. 玩家变量数据是否已经加载完成。玩家刚进入服务器时,数据读取可能尚未结束。

  6. 变量 ID 是否完全一致。变量 ID 只能包含中文、字母、数字、下划线或短横线,长度不能超过 128 个字符。

为什么旧的 %lybl_...% 变量不能使用

当前变量标识使用 lyplaceholder,不是 lybllybl 是插件管理指令名称。

例如,读取玩家的“金币”变量应使用:

text
%lyplaceholder_player_金币%

不要写成:

text
%lybl_player_金币%

为什么玩家变量命令提示数据尚未加载

玩家变量管理指令只能操作在线玩家,并且必须等待该玩家的变量数据加载完成。

数据会从当前持久化层读取;启用 Redis 时,还会同时读取 Redis 快照并比较数据版本。MySQL、Redis 或磁盘响应缓慢时,加载时间可能增加。

如果数据加载失败,插件会将玩家踢出服务器,避免在未加载完整数据的情况下覆盖原有变量。

为什么无法通过命令操作离线玩家变量

玩家变量管理指令只支持在线玩家。以下指令中的目标玩家必须在线,并且变量数据已经加载完成:

text
/lybl set player <玩家> <变量ID> <值>
/lybl add player <玩家> <变量ID> <数字>
/lybl take player <玩家> <变量ID> <数字>
/lybl get player <玩家> <变量ID>
/lybl remove player <玩家> <变量ID>

服务器变量不属于具体玩家,可以直接使用 server 作用域操作。

为什么执行指令时提示没有权限

全部管理指令都需要权限:

权限用途默认拥有者
lyplaceholder.admin重载刷新规则以及管理玩家变量、服务器变量管理员

没有该权限时,插件会提示“你没有权限执行该命令”。

为什么 addtake 执行失败

addtake 只用于数字运算,需要同时满足以下条件:

  • 指令提供的操作数是有效数字。
  • 目标变量已有值时,当前值也是有效数字。
  • set 外,指令参数中不能附带多余内容。

如果目标变量不存在,addtake 会先以 0 创建变量,再执行计算。计算使用精确十进制数,并会去除没有意义的末尾零。

文本变量应使用 set 修改:

text
/lybl set player <玩家> <变量ID> <值>
/lybl set server <变量ID> <值>

set 的值可以包含空格。

为什么变量 ID 或规则 ID 无法使用

变量 ID 和规则 ID 只能包含以下字符:

  • 中文字符
  • 英文字母
  • 数字
  • 下划线 _
  • 短横线 -

变量 ID 最长为 128 个字符,规则 ID 最长为 127 个字符。空格、点号、冒号、斜杠等字符不能用于 ID。

同一作用域内不能存在重复的规则 ID。玩家刷新规则与服务器刷新规则属于不同作用域,可以分别使用相同的规则 ID。

为什么刷新规则没有载入

依次检查以下内容:

  1. 文件扩展名是否为 .yml

  2. 文件是否放入正确目录:

    规则类型目录
    玩家变量刷新规则plugins/LyPlaceholder/playerPlaceholderRefresh
    服务器变量刷新规则plugins/LyPlaceholder/serverPlaceholderRefresh
  3. 文件名是否正好是插件内置示例文件名。以下两个完整文件名会被跳过:

    • 示例玩家变量刷新配置_不会启用.yml
    • 示例系统变量刷新配置_不会启用.yml

    需要使用示例时,请复制文件并修改文件名。其他以“示例”开头的 .yml 文件不会因此被跳过。

  4. 规则是否设置了 enable: false。省略 enable 时默认为启用。

  5. 每条规则是否配置了非空的 script。旧的 value 配置不再支持。

  6. trigger-timeconditionscript 是否存在格式错误。

  7. 同一作用域内是否存在重复规则 ID。

  8. 规则 ID 和脚本中的变量 ID 是否使用了不允许的字符。

  9. 玩家规则脚本是否错误调用了 全服消息()。该函数只能用于服务器规则。

执行 /lybl reload 后,插件会列出成功载入的规则。如果任一文件校验失败,本次重载会失败,但原来正在运行的刷新任务会继续保留。

刷新配置能否放在子目录中

可以。玩家刷新目录和服务器刷新目录都会递归读取子目录中的 .yml 文件。

一个文件可以包含多条规则,多个规则也可以写入同一个变量,但同一作用域内的规则 ID 不能重复。

为什么刷新规则触发了,但没有修改变量

可能原因如下:

  • 脚本没有调用 设置值("变量ID", 内容)
  • 玩家没有通过全部 condition 条件。
  • 脚本发生除零、未知函数、参数错误或非法变量 ID 等运行错误。
  • 玩家规则调用了 占位符(),但 PlaceholderAPI 未启用。
  • 服务器规则调用了依赖玩家上下文的函数。

script 是刷新规则唯一的变量写入入口。同一脚本可以调用多次 设置值();同一个变量被设置多次时,以最后一次写入的值为准。

脚本执行失败时,本次不会写入任何变量,但该触发点仍会被记录为已经处理。

为什么服务器规则中的 condition 没有效果

condition 只适用于玩家变量刷新规则。服务器变量刷新规则不会读取、校验或判断 condition,即使配置了也会忽略。

服务器规则如果需要判断服务器变量旧值,应在 script 中使用 变量值()if/else

为什么 PAPI 条件不生效

玩家规则的 PAPI 条件必须使用以下格式:

yaml
condition:
  - 'papi: %player_level% >= 5'

检查以下内容:

  • PlaceholderAPI 是否已经安装并启用。
  • 条件前缀后的冒号是否为半角英文冒号 :
  • PAPI 变量能否在该玩家身上正常返回内容。
  • 表达式是否包含完整的左右操作数。
  • 字符串引号是否完整闭合。

PAPI 条件支持 >>=<<===!=、数学运算、&&||。同一个 condition 列表中的所有条件必须全部满足。

如果玩家规则需要计算 PAPI 条件,但 PlaceholderAPI 暂时不可用,本次不会记录该规则的刷新时间。PlaceholderAPI 恢复后,插件仍可重新检测并进行补偿刷新。

为什么条件使用中文冒号后重载失败

条件前缀只接受半角英文冒号:

yaml
condition:
  - 'permission: lyplaceholder.example.enable'
  - 'nopermission: lyplaceholder.example.blocked'
  - 'papi: %player_level% >= 5'

以下写法中的中文冒号不会被接受:

yaml
condition:
  - 'permission: lyplaceholder.example.enable'

可用的条件前缀只有 permission:nopermission:papi:

为什么定时表达式无法载入

刷新时间只能使用 每隔定时: 两类表达式。常见检查项如下:

  • 定时: 必须使用半角英文冒号。
  • 时间必须为 HH:mmHH:mm:ss
  • 每隔 后必须是正整数和小写单位。
  • 小时、分钟和秒必须在有效范围内。
  • 每年表达式中的日期必须属于对应月份。
  • 星期范围必须从较早的星期写到较晚的星期。
  • 每月日期范围必须从较小日期写到较大日期。

有效示例:

yaml
trigger-time:
  - '每隔 30s'
  - '每隔 5m'
  - '定时:每天 12:00'
  - '定时:每周 周一至周五 09:00'
  - '定时:每月 1号,15号,最后一天 12:00'
  - '定时:每年 1月 1日 00:00'

无效示例:

yaml
trigger-time:
  - '定时:每天 12:00'
  - '每隔 0m'
  - '定时:每天 25:00'
  - '定时:每年 2月 30日 12:00'

一条规则可以配置多个触发时间吗

可以。trigger-time 可以填写多条表达式,任意一个时间到达都会触发该规则。

倒计时变量会返回距离最近一次触发的剩余时间,而不是固定取列表中的第一条表达式。

为什么倒计时变量返回空文本

依次检查:

  1. 使用的是规则 ID,不是脚本写入的变量 ID。
  2. 规则已经成功载入并处于启用状态。
  3. 变量作用域与规则目录一致。
  4. PlaceholderAPI 已经正常启用。
  5. 规则 ID 拼写完全一致。

例如,玩家刷新配置的顶层节点为:

yaml
金币刷新规则:
  trigger-time:
    - '每隔 30m'
  script: |-
    设置值("金币", 0)

对应倒计时变量是:

text
%lyplaceholder_countdown_player_金币刷新规则%

这里的 金币刷新规则 是规则 ID,金币 才是实际写入的变量 ID。

倒计时为什么没有显示完整的天、时、分、秒

倒计时会省略最左侧连续为零的单位,这是正常行为。

实际剩余时间返回内容
5 分 3 秒5分 3秒
2 时 0 分 3 秒2时 0分 3秒
1 天整1天 0时 0分 0秒
已到触发时间0秒

玩家离线期间错过刷新时间怎么办

插件会按规则记录最近一次已经处理的触发时间。玩家下次上线并完成变量加载后,如果从上次触发时间到当前时间之间存在至少一个触发点,插件会根据当前条件补刷新一次。

需要注意:

  • 即使离线期间错过多次触发,也只补刷新一次。
  • 补刷新时使用玩家当前的权限和 PAPI 数据检查条件。
  • 新规则没有历史触发时间时,只会初始化当前时间,不会追溯规则创建前的事件。
  • 规则到达触发时间后,即使玩家未通过条件,通常也会记录该触发点已经处理。
  • 如果因 PlaceholderAPI 未启用而无法计算 PAPI 条件,则不会记录刷新时间,恢复后仍可重新检测。

为什么服务器脚本中的玩家函数不执行

服务器规则没有玩家上下文,因此以下函数不会执行:

  • 玩家消息()
  • 玩家指令()
  • OP指令()

服务器规则可以使用:

  • 全服消息()
  • 控制台指令()
  • 服务器变量相关的 变量值()设置值()

服务器规则也不应调用需要玩家上下文的 占位符()。玩家规则可以使用玩家相关函数,但不能使用 全服消息()

为什么消息或命令执行了两次

刷新脚本中的动作函数与规则节点中的 messagecommand 会同时执行。

例如,同时配置以下两种方式会产生重复效果:

yaml
script: |-
  玩家消息("&a变量已刷新")
message:
  - '&a变量已刷新'

如果不需要重复发送消息或执行命令,请只保留脚本动作函数,或只保留规则的 messagecommand 节点。

为什么 MySQL 开启后没有生效

MySQL 模式必须安装 LyMySQLCore 1.0.3,并且 LyMySQLCore 已成功连接数据库。缺少该插件或数据库连接未完成时,MySQL 相关功能不会生效,LyPlaceholder 也会阻止变量功能初始化。

依次检查:

  • 已安装并正常启用 LyMySQLCore 1.0.3
  • LyMySQLCore 已成功连接数据库。
  • mysql.enable 已设为 true
  • MySQL 数据库已经提前创建。
  • mysql.ipmysql.portmysql.databasenamemysql.usernamemysql.password 正确。
  • 数据库名称只包含字母、数字、下划线或短横线。
  • 修改 MySQL 配置后已经完整重启服务器。

变量表和版本表会由插件自动创建,但数据库本身需要提前创建。

MySQL 或 Redis 尚未连接时为什么玩家无法进入服务器

MySQL 模式下,插件会在玩家登录时检查 MySQL 是否已连接。启用 Redis 后,也会同时检查 Redis 是否可用。

只要已启用的存储连接尚未准备完成,玩家就会被拒绝登录,以避免读取到不完整数据或使用空数据覆盖原有变量。应检查控制台中的连接错误,并确认服务地址、端口和认证信息正确。

Redis 开启后为什么插件功能没有初始化

Redis 是变量的可选前置缓存层。设置 redis.enable: true 后,Redis 连接必须成功;连接失败会停止变量功能初始化。

检查以下配置:

配置项检查内容
redis.hostRedis 地址不能为空
redis.port端口必须在 165535 之间
redis.username使用 ACL 时填写正确用户名
redis.password填写正确密码;无密码时可以留空
redis.database数据库编号不能小于 0

修改 Redis 开关或连接参数后需要重启服务器。

Redis 是否可以代替 YAML 或 MySQL

不能。Redis 是可选的前置缓存层,YAML 或 MySQL 仍作为持久化层。

MySQLRedis读取来源保存位置
关闭关闭YAMLYAML
开启关闭MySQLMySQL
关闭开启Redis 与 YAMLRedis 与 YAML
开启开启Redis 与 MySQLRedis 与 MySQL

同时启用 Redis 和持久化层时,插件会比较快照版本并选择最新数据,再修复较旧的一侧。版本相同时优先信任 MySQL 或 YAML。

切换 YAML 与 MySQL 后旧变量为什么没有出现

mysql.enable 只负责切换持久化层,不会自动把已有 YAML 数据迁移到 MySQL,也不会自动把 MySQL 数据迁移回 YAML。

切换持久化方式前,需要自行迁移已有变量数据。切换后还必须重启服务器。

为什么修改配置后重载没有生效

/lybl reload 主要用于重新读取和校验玩家、服务器刷新规则。

以下内容修改后需要重启服务器:

  • mysql.enable
  • MySQL 地址、端口、数据库名、用户名或密码
  • redis.enable
  • Redis 地址、端口、用户名、密码或数据库编号

如果重载刷新规则失败,插件会保留原来正在运行的任务,不会使用校验失败的新配置。

自动保存为什么没有产生写入记录

自动保存只会在变量数据发生变化时执行。数据没有变化时,插件不会访问 Redis、MySQL 或 YAML,这是正常行为。

auto-save-seconds 的最低有效间隔为 10 秒。变量还会在以下时机保存:

  • 执行变量修改指令后。
  • 玩家退出或被踢出服务器时。
  • 插件正常关闭时。

普通存储写入失败后,未保存的变更会保留,并在后续自动保存时继续重试。

YAML 数据文件损坏后怎么办

YAML 模式使用 UTF-8 无 BOM 读写,并在覆盖已有数据前生成 .bak 备份。保存时会先写入临时文件,再使用原子替换更新正式文件。

读取主文件失败时,插件会尝试读取对应的备份文件。备份有效时,会自动恢复主文件并在控制台输出提示。如果主文件和备份都无法读取,玩家变量会加载失败,服务器变量也无法正常恢复。

不要在服务器运行期间手动同时修改主文件和 .bak 文件。

为什么旧数据没有覆盖 Redis 或 MySQL 中的数据

Redis、MySQL 和 YAML 快照带有数据版本。保存时如果远端已经存在相同或更高版本,插件会拒绝使用旧快照覆盖远端数据。

这是防止多次异步保存、跨服缓存或慢存储响应造成数据回退的保护机制。出现版本冲突提示时,插件会保留远端较新的数据,而不是强制覆盖。

重载失败后变量任务是否会全部停止

不会。执行 /lybl reload 时,插件会先读取并校验全部刷新文件。任一文件存在错误时,本次重载失败,旧刷新任务保持不变。

修复配置后再次执行:

text
/lybl reload

成功后,插件会反馈实际载入的规则;没有任何可用规则时也会给出对应提示。