福利·变量 LyPlaceholder
LyPlaceholder 是一个 Bukkit/Paper 服务端变量管理插件,用于保存玩家独立变量和全服共用变量。管理员可以通过指令直接修改变量,也可以编写定时规则,按固定间隔或指定日期自动计算、重置和更新变量。
插件支持通过 PlaceholderAPI 将变量提供给计分板、菜单、聊天、任务等其他插件。变量可以使用 YAML 或 MySQL 持久化,并可额外启用 Redis 作为前置缓存。
功能概览
- 玩家变量:每名玩家分别保存一份变量数据。
- 服务器变量:全服共用同一份变量数据。
- 变量管理:支持设置、增加、减少、查询和删除变量。
- 定时刷新:支持固定间隔、每天、每周、每月和每年规则。
- 离线补刷新:玩家上线并完成数据加载后,可补偿离线期间错过的刷新规则。
- 玩家条件:玩家规则可以检查权限、反向权限和 PlaceholderAPI 表达式。
- 刷新脚本:支持读取旧值、批量写入变量、数学运算、条件分支、消息和命令动作。
- 规则倒计时:可以通过 PlaceholderAPI 获取规则下一次触发的剩余时间。
- 递归配置:刷新规则目录支持递归读取子目录中的
.yml文件。 - 安全重载:规则校验失败时保留原有刷新任务,不应用错误配置。
- 多种存储:默认使用 YAML,可切换至 MySQL,并可独立启用 Redis 缓存。
- 按需保存:自动保存仅处理发生变化的数据,最低间隔为 10 秒。
运行要求
| 项目 | 要求 | 是否必需 |
|---|---|---|
| Java | Java 8 | 必需 |
| 服务端 | 项目以 Paper 1.16.5 为目标版本 | 必需 |
| PlaceholderAPI | 输出插件变量、使用 PAPI 条件或在脚本中解析其他占位符 | 按需安装 |
| LyMySQLCore | MySQL 模式下负责玩家数据的安全加载与保存 | 启用 MySQL 时必需 |
| MySQL | 变量持久化存储 | 可选 |
| Redis | 变量前置缓存 | 可选 |
PlaceholderAPI 未安装时,变量管理、YAML/MySQL 存储和不依赖 PAPI 的刷新规则仍可运行,但 %lybl_...% 变量、papi: 条件和脚本中的 占位符() 无法使用。
MySQL 前置要求
启用 mysql.enable 前,必须安装并启用 LyMySQLCore,并确保 LyMySQLCore 已成功连接数据库。前置缺失或数据库连接未完成时,MySQL 相关功能不会生效,插件变量系统也无法正常完成初始化。
Redis 连接要求
启用 redis.enable 后,Redis 必须能够正常连接。Redis 连接失败时,变量系统不会继续初始化。
变量类型
| 类型 | 数据范围 | 适合保存的内容 |
|---|---|---|
| 玩家变量 | 每名玩家独立保存 | 玩家次数、状态、积分、奖励记录和每日进度 |
| 服务器变量 | 全服共用一份 | 全服状态、活动阶段、累计次数和公共统计值 |
变量 ID 只能包含中文、字母、数字、下划线或短横线。读取不存在的变量时,PlaceholderAPI 返回空文本;脚本中的 变量值() 同样返回空文本。
PlaceholderAPI 变量
PlaceholderAPI 扩展标识为 lybl。
| 变量 | 返回内容 |
|---|---|
%lybl_player_变量ID% | 当前玩家对应的玩家变量值 |
%lybl_server_变量ID% | 指定服务器变量值 |
%lybl_countdown_player_规则ID% | 玩家刷新规则下一次触发的倒计时 |
%lybl_countdown_server_规则ID% | 服务器刷新规则下一次触发的倒计时 |
玩家变量必须具有玩家上下文,因此 %lybl_player_变量ID% 在没有玩家上下文时返回空文本。变量或规则不存在时,对应占位符也返回空文本。
倒计时会省略左侧连续为零的单位。例如剩余时间为 5 分 3 秒时,返回 5分 3秒。一条规则配置多个触发时间时,倒计时返回距离最近一次触发的剩余时间。
规则 ID 是刷新配置中的顶层节点名称,实际写入的变量 ID 则由脚本中的 设置值() 决定。两者可以不同。
管理指令
插件主指令为 /lybl,所有管理操作都需要 lyplaceholder.admin 权限。
| 指令 | 说明 |
|---|---|
/lybl reload | 重新读取并校验玩家与服务器变量刷新规则,同时更新自动保存间隔和操作提示。 |
/lybl set player <玩家> <变量ID> <值> | 设置在线玩家变量,值可以包含空格。 |
/lybl add player <玩家> <变量ID> <数字> | 增加在线玩家变量;变量不存在时从 0 开始。 |
/lybl take player <玩家> <变量ID> <数字> | 减少在线玩家变量;变量不存在时从 0 开始。 |
/lybl get player <玩家> <变量ID> | 查询在线玩家变量。 |
/lybl remove player <玩家> <变量ID> | 删除在线玩家变量。 |
/lybl set server <变量ID> <值> | 设置服务器变量,值可以包含空格。 |
/lybl add server <变量ID> <数字> | 增加服务器变量;变量不存在时从 0 开始。 |
/lybl take server <变量ID> <数字> | 减少服务器变量;变量不存在时从 0 开始。 |
/lybl get server <变量ID> | 查询服务器变量。 |
/lybl remove server <变量ID> | 删除服务器变量。 |
add 和 take 使用精确十进制运算,操作数与变量当前值都必须是有效数字。玩家变量指令只能操作在线且变量数据已经加载完成的玩家。
插件提供指令补全,可以补全操作名称、变量作用域、在线玩家名称以及已经存在的变量 ID。没有管理权限的发送者不会获得这些补全内容。
权限
| 权限 | 作用 |
|---|---|
lyplaceholder.admin | 使用 /lybl 的重载和变量管理功能 |
刷新规则
玩家变量刷新规则位于 playerPlaceholderRefresh,服务器变量刷新规则位于 serverPlaceholderRefresh。两个目录都支持递归读取子目录中的 .yml 文件,一个文件可以包含多条规则。
每条启用的规则至少需要一个 trigger-time 和一个非空的 script:
yaml
每日状态规则:
enable: true
trigger-time:
- '定时:每天 00:00'
script: |-
设置值("每日状态", "已重置")
message: []
command: []| 配置项 | 适用范围 | 说明 |
|---|---|---|
enable | 玩家、服务器 | 是否启用当前规则;省略时默认为 true。 |
trigger-time | 玩家、服务器 | 触发时间列表,至少填写一条。 |
condition | 仅玩家规则 | 玩家刷新条件;列表中的条件必须全部满足。 |
script | 玩家、服务器 | 必填的多行刷新脚本,通过 设置值() 写入变量。 |
message | 玩家、服务器 | 每个成功写入的变量对应发送的消息列表。 |
command | 玩家、服务器 | 每个成功写入的变量对应执行的命令列表。 |
旧版 value 节点已不再支持。规则中出现 value 会导致重载失败,变量必须通过 script 中的 设置值("变量ID", 内容) 写入。
规则 ID 只能包含中文、字母、数字、下划线或短横线。同一作用域内不能出现重复规则 ID,但玩家规则和服务器规则可以使用相同名称。多个不同规则可以写入同一个变量。
插件会跳过完整文件名为 示例玩家变量刷新配置_不会启用.yml 和 示例系统变量刷新配置_不会启用.yml 的两个内置示例。其他 .yml 文件即使名称中包含“示例”,仍会正常读取。
执行 /lybl reload 时,插件会完整校验所有刷新文件。任意规则存在重复 ID、错误时间、错误条件、空脚本或脚本语法错误时,本次重载失败,原有刷新任务继续运行。
定时表达式
| 类型 | 格式 |
|---|---|
| 固定秒数 | 每隔 30s |
| 固定分钟 | 每隔 5m |
| 固定小时 | 每隔 2h |
| 固定天数 | 每隔 1d |
| 每天 | 定时:每天 12:00 |
| 每天精确到秒 | 定时:每天 12:00:30 |
| 每周单日 | 定时:每周 周一 09:00 |
| 每周列表 | 定时:每周 周一,周三,周五 09:00 |
| 每周范围 | 定时:每周 周一至周五 09:00 |
| 每月单日 | 定时:每月 3号 12:00 |
| 每月列表 | 定时:每月 1号,15号,最后一天 12:00 |
| 每月范围 | 定时:每月 1-5号 12:00 |
| 每年 | 定时:每年 1月 1日 00:00 |
每隔 后必须填写正整数,并使用小写单位 s、m、h 或 d。定时时间支持 HH:mm 和 HH:mm:ss。
星期支持 周一 至 周日、周天、星期一 至 星期日 和 星期天。列表逗号支持 , 与 ,,范围分隔符支持 ~、~、至、- 和 -。
定时: 以及时间中的冒号必须使用半角英文冒号。一条规则可以配置多个 trigger-time,任意一个时间到达都会触发该规则。
玩家刷新条件
condition 只适用于玩家变量规则。服务器变量规则不会读取或判断该节点,即使填写也会被忽略。
| 条件格式 | 说明 |
|---|---|
permission: 权限节点 | 玩家必须拥有指定权限。 |
nopermission: 权限节点 | 玩家必须没有指定权限。 |
papi: 表达式 | 使用 PlaceholderAPI 解析并判断表达式。 |
yaml
condition:
- 'permission: lyplaceholder.example.enable'
- 'nopermission: lyplaceholder.example.blocked'
- 'papi: %player_level% >= 5'同一列表中的条件必须全部满足。papi: 条件支持 >、>=、<、<=、==、!=、数学运算、&& 和 ||,并且需要 PlaceholderAPI 已启用。
玩家规则到达触发时间后会先记录规则刷新时间,再检查条件。即使条件不满足,该触发点也会视为已经处理。如果规则需要 PAPI 条件但 PlaceholderAPI 暂时不可用,本次不会记录刷新时间,依赖恢复后仍可重新检查并进行补偿。
刷新脚本
每条规则都必须提供非空的 script。脚本只会写入明确调用 设置值() 的变量;没有调用时不会修改变量。同一脚本可以写入多个变量,同一变量被多次设置时以最后一次为准。
| 函数 | 作用 |
|---|---|
变量值("变量ID") | 读取当前作用域中变量写入前的值,不存在时返回空文本。 |
设置值("变量ID", 内容) | 创建或更新玩家变量或服务器变量。 |
数字(内容) | 转换为数字;空文本或无法转换的内容得到 0。 |
字符串(内容) | 转换为文本。 |
占位符("%变量%") | 使用 PlaceholderAPI 解析占位符。 |
最大值(数字...) | 返回参数中的最大数字。 |
最小值(数字...) | 返回参数中的最小数字。 |
绝对值(数字) | 返回数字绝对值。 |
向下取整(数字) | 向下取整。 |
向上取整(数字) | 向上取整。 |
四舍五入(数字) | 四舍五入为整数。 |
玩家消息("文本") | 向当前玩家发送消息,并转换 & 颜色代码。 |
全服消息("文本") | 向全部在线玩家广播消息,仅允许服务器规则使用。 |
OP指令("命令") | 临时以当前玩家 OP 身份执行命令。 |
控制台指令("命令") | 以服务器控制台身份执行命令。 |
玩家指令("命令") | 以当前玩家身份执行命令。 |
脚本支持 +、-、*、/、%、比较运算、&&、||、!、三元表达式和数组。还支持多行 if、else if 和 else 条件块。
| 对象类型 | 可用方法 |
|---|---|
| 文本 | 长度()、包含()、前缀判断()、后缀判断()、替换()、转小写()、转大写()、去空白()、截取()、等于() |
| 数字 | 绝对值()、向下取整()、向上取整()、四舍五入() |
| 列表 | 长度()、读取()、包含()、为空() |
普通表达式按行执行,可以使用分号结尾。空行以及以 # 或 // 开头的行会被忽略。脚本没有可直接读取的规则 ID、玩家名或触发时间等内置变量。
服务器规则没有玩家上下文,因此不应使用需要玩家的 占位符()。服务器规则中的 玩家消息()、OP指令() 和 玩家指令() 不会执行;全服消息() 和 控制台指令() 可以正常使用。玩家规则使用 全服消息() 会在重载校验阶段被拒绝。
脚本动作函数与规则节点中的 message、command 会同时执行。若不希望重复发送消息或执行命令,应只选择其中一种方式。
规则消息与命令
规则节点中的 message 和 command 会针对脚本成功写入的每个变量分别执行一次。
| 占位符 | 内容 |
|---|---|
{id} | 当前刷新规则 ID |
{value} | 当前写入后的变量值 |
| PlaceholderAPI 变量 | 在具有玩家上下文时继续交给 PlaceholderAPI 解析 |
command 支持以下执行方式:
| 格式 | 执行身份 |
|---|---|
[console]命令 | 服务器控制台 |
[op]命令 | 当前玩家的临时 OP 身份 |
命令 | 当前玩家身份 |
服务器规则完成变量写入后,会对全部在线玩家处理规则节点中的消息和命令。因此不带 [console] 的命令会分别以在线玩家身份执行。
离线补刷新机制
玩家变量数据加载完成后,插件会检查玩家上次记录的规则刷新时间。如果在上次时间至当前时间之间存在任意触发点,该规则会按照当前条件补执行一次,而不是按错过次数重复执行。
新规则没有历史刷新时间时,只会记录当前时间,不会追溯更早的触发点。刷新时间按规则保存,不再为每个变量单独保存刷新时间。
存储方式
mysql.enable 决定使用 MySQL 还是 YAML 作为持久化层,redis.enable 独立决定是否启用 Redis 前置缓存。
| MySQL | Redis | 读取方式 | 保存位置 |
|---|---|---|---|
| 开启 | 开启 | 同时读取 Redis 与 MySQL,比较版本后使用较新的数据 | Redis 和 MySQL |
| 关闭 | 开启 | 同时读取 Redis 与 YAML,比较版本后使用较新的数据 | Redis 和 YAML |
| 开启 | 关闭 | 从 MySQL 读取 | MySQL |
| 关闭 | 关闭 | 从 YAML 读取 | YAML |
Redis 与持久化层同时启用时,插件会比较数据快照版本,使用较新数据修复较旧的一侧。版本相同时优先信任持久化层。保存时会拒绝旧版本快照覆盖远端较新数据。
切换 MySQL 持久化方式前,需要自行迁移已有变量数据。MySQL、Redis 的启用状态、地址、端口、认证信息或数据库配置发生变化后,需要重启服务器,不能仅通过 /lybl reload 应用。
数据保存时机
插件会在以下情况下保存变量数据:
- 玩家正常退出或被踢出服务器时。
- 管理指令成功修改变量后。
- 到达
auto-save-seconds间隔且变量数据发生变化时。 - 插件正常关闭时。
自动保存默认间隔为 60 秒,配置值不能小于 10 秒。变量快照没有变化时,不会访问 Redis、MySQL 或 YAML。普通保存失败后,变更状态会保留,后续自动保存会继续尝试。
配置文件
| 路径 | 作用 |
|---|---|
plugins/LyPlaceholder/config.yml | 自动保存、变量操作提示、Redis 和 MySQL 设置。 |
plugins/LyPlaceholder/playerPlaceholderRefresh | 玩家变量刷新规则,递归读取子目录中的 .yml 文件。 |
plugins/LyPlaceholder/serverPlaceholderRefresh | 服务器变量刷新规则,递归读取子目录中的 .yml 文件。 |
重要配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
auto-save-seconds | 60 | 自动保存检查间隔,不能小于 10 秒。 |
message.set | 已配置 | set 操作成功提示。 |
message.add | 已配置 | add 操作成功提示。 |
message.take | 已配置 | take 操作成功提示。 |
message.remove | 已配置 | remove 操作成功提示。 |
redis.enable | false | 是否启用 Redis 前置缓存。 |
redis.host | 127.0.0.1 | Redis 地址。 |
redis.port | 6379 | Redis 端口。 |
redis.username | default | Redis 用户名。 |
redis.password | 空文本 | Redis 密码。 |
redis.database | 0 | Redis 数据库编号。 |
mysql.enable | false | 是否使用 MySQL 持久化;关闭时使用 YAML。 |
mysql.databasename | mc2 | MySQL 数据库名称,数据库需要提前创建。 |
mysql.username | mc2 | MySQL 用户名。 |
mysql.password | mc1234 | MySQL 密码。 |
mysql.port | 3306 | MySQL 端口。 |
mysql.ip | 127.0.0.1 | MySQL 地址。 |
MySQL 数据库需要提前创建,变量数据表由插件自动创建。
变量修改提示支持以下内容:
| 占位符 | 说明 |
|---|---|
{target} | 玩家变量为玩家名,服务器变量固定为“系统”。 |
{id} | 变量 ID。 |
{value} | 修改后的变量值。 |
{amount} | add 或 take 的本次运算数。 |
& 颜色代码 | 转换为 Minecraft 颜色。 |
对应的 message 节点留空或删除后,该操作成功时不会发送提示。
版本信息
| 项目 | 内容 |
|---|---|
| 插件版本 | 1.0.0 |
| Java 目标版本 | Java 8 |
| 服务端目标版本 | Paper 1.16.5 |
| 插件类型 | Bukkit/Paper 服务端插件 |
| 客户端要求 | 不需要安装客户端 MOD |