Sueta

CatCraftTitle

1.6.0

这个是一个高版本服务器头衔插件 This is a plugin for managing player titles on high-version Minecraft servers.

·Plugin

CatCraftTitle

中文 | English


插件作用

CatCraftTitle 是一个轻量级、支持 GUI 管理、中英双语、功能完善的 Minecraft 头衔与后缀管理插件,支持 MySQL / PostgreSQL / SQLite 三种数据库,帮助服务器轻松实现玩家头衔系统,并支持跨服同步。

内置商店系统(可用内置金币或 Vault 经济)、每日签到、基于 PlaceholderAPI 的自动称号、Tab/头顶显示与 RGB 渐变。

本次更新使用了 DeepSeek V4.1 Flash。

CatCraft


1.6.0 更新详情(24 处修复 + 新功能 + 兼容性说明)

1.6.0 更新内容

〇、本轮安全审计修复(全项目复查,共修复 24 处问题,下表按类别合并为 16 行)

本轮对全部 33 个源文件做了一遍完整复查,修掉以下问题(都经过真实服务端/演练验证):

#问题影响处理
1Folia 上探测不到区域调度器(1.19.4 没有 RegionizedServer 类)Folia 上所有定时任务报错、插件被禁用多标记探测 + 按 API 可用性选路 + 调度失败不再抛出
2player_signin 建表语句多了一个单引号签到表建不起来,签到永远失败修正语句,并加静态检查防复发
3商品表主键迁移只复制 4 列隐藏/展示状态被重置为可购买、备注丢失保留 state/note + 备份校验 + 失败自动回滚
4余额首次读取的「建行」不在锁内并发时默认值可能覆盖刚充值的余额建行移入同一把锁
5签到时先记日期再发奖励发奖失败会白吃掉当天签到奖励为 0 不算失败;发奖失败回滚签到日期
6InternalCurrency 金额强转 int 溢出超大金额会存成负数余额转 int 前做上下限收敛
7商店价格可为负数负数价格等于免费白拿服务层拒绝负价,购买时也拦截
8离线玩家发放头衔不查重同 ID 会把已有头衔覆盖成后缀补上与在线路径一致的查重
9聊天输入回调跑在异步聊天线程异步线程里开 GUI/改记分板(Folia 直接报错)统一改到玩家线程执行
10Q 键/数字键也能触发 GUI 操作与购买误按键就购买/切换状态只响应左/右/Shift 点击
11管理面板「首页/末页」箭头是死的超过一页时无法跳转补上 47/51 槽位处理
12空列表提示会被背景填充覆盖玩家看不到「没有称号」等提示调整绘制顺序
13条件右侧解析为空时字符串比较恒为真变量写错会让全服玩家都拿到称号空值一律判定不满足
14=> / =< / <> 写法会让整条规则失效按文档写法的规则被静默丢弃词法器支持这三种写法
15matches 是子串匹配、真值判断里 0.00 为真与文档不符,易误判改为整串匹配;纯数字 0 判为假
16若干文案/解析问题英文签收提示乱码、负数 ID 可发放、超长称号丢颜色、TPS 假值逐一修正

这些修复都补了自动化检查:冒烟测试从 76 项增加到 103 项,新增「全新空库安装」演练(31 项)
与「商品表迁移」专项演练(11 项),数据库升级演练保持 16 项全通过。

一、管理员面板重新设计

面板按「信息区 / 功能开关区 / 管理入口区 / 底部摘要」重新分区,一眼看清状态,并新增两个子面板:

位置内容
第 1 行插件信息 · 服务器状态(TPS 1m/5m/15m、在线、内存) · 数据库状态
第 2 行属性支持 / RGB / 商店 / Tab 显示 / 聊天格式 / 更新检测 / 自动称号规则自检
第 3 行玩家称号管理 · 商店商品管理 · 语言切换 · 重载配置 · 立即检查更新
第 6 行面板摘要(当前货币、规则条数、最新版本)+ 关闭

二、面板内直接管理玩家称号(新功能)

  • 玩家称号管理 → 在线玩家列表:头像分页展示所有在线玩家,点头像即可管理
  • 搜索玩家:点击「搜索玩家」后在聊天栏输入玩家名或 UUID(支持离线玩家),直接打开该玩家的称号管理
  • 玩家管理页可一键完成:查看头衔/后缀列表、发放头衔或后缀、清空全部称号(二次确认)、激活/停用、改名、删除
  • 聊天栏输入说明:点击按钮后直接打字发送即可,60 秒内有效,输入 cancel 取消

列表内操作方式(每个物品的说明里也写了):

操作效果
左键激活 / 停用该称号
右键修改显示名(聊天栏输入新名字)
Shift + 左键删除该称号
发放按钮聊天栏输入 ID 显示名

三、商店商品管理面板(新功能)

面板内完成商品的全部管理(等价于 /titleadmin shop ...,但更直观):

操作效果
左键循环切换状态:在售 → 展示(不可购买)→ 隐藏
右键修改价格(聊天栏输入数字)
Shift + 右键修改备注(如「活动限定」,输入 clear 清除)
Shift + 左键删除商品
新增商品按钮聊天栏输入 ID 类型 价格 显示名

四、玩家面板优化

  • 主页头像显示「拥有头衔 X 个 · 后缀 Y 个」
  • 头衔/后缀/商店列表页新增 首页 / 末页 按钮(原来是 上一页 / 下一页)
  • 列表物品标明来源(自动规则 / 管理员或商店)与状态,操作提示更明确

1.6.0 更新内容 · 更新检测与署名

一、更新检测重做(修复 502 / 检测不生效)

  • 多地址回退(共 5 个来源):api.github.com/.../releases/latest → github.com/.../releases/latest(跟随跳转读 tag)→ api.github.com/.../tags → raw.githubusercontent.com 上 build.gradle 里的版本号(master / main 两个分支都试)。某个地址被代理或加速器挡住时会自动换下一个;即使仓库没有发布 Release,也能通过 build.gradle 检测到新版本
  • 失败自动重试:5xx、429、超时各重试一次;404(仓库还没有 Release)直接换下一个地址
  • 定期复查:默认每 6 小时检查一次(settings.update-check-interval-hours)
  • 在聊天栏通知有 op 或 catcraft.admin 权限的玩家,并支持玩家上线时补发(settings.update-notify-ops)
  • 控制台横幅可关闭(settings.update-notify-console: false)
  • 手动检查:/titleadmin updatecheck
  • 失败时会给出可操作提示:502 通常是代理/加速器造成的,建议把 api.github.com、github.com 加入加速器的直连/绕过名单

注意:releases/latest 与 tags 接口要求仓库存在 Release 或 Tag(例如打 v1.6.0 标签);如果都没有,会自动回退到读取仓库里 build.gradle 的版本号,因此不会因为「没发 Release」而完全失效。

二、署名调整

  • 控制台横幅、游戏内帮助、管理面板不再输出「DeepSeek V4.1 Flash」
  • 相关说明只保留在 config.yml 头部注释与 README 中;plugin.yml 的 authors 只保留插件作者本人

三、配置新增(config-version 9)

settings:
  check-update: true
  update-check-interval-hours: 6   # 更新检测间隔(小时)
  update-notify-console: true      # 发现新版本是否在控制台打印横幅
  update-notify-ops: true          # 发现新版本是否在聊天栏通知 op / 管理员

1.6.0 更新内容 · Minecraft 26.3 适配与源码整理

一、适配 Minecraft 26.3

  • 编译目标升级到 spigot-api:26.3-R0.1-SNAPSHOT(build.gradle 里集中为一个变量 spigotApiVersion,以后适配新版本改一行即可)
  • 继续保留 1.16+ 全兼容:所有可能被新版改动的接口都改成「存在才用」的写法,避免升版本就炸:
    • 不再依赖已被标记弃用的 ChatColor,颜色转换由插件自己实现
    • 旧聊天事件 AsyncPlayerChatEvent 改为运行时探测后再注册:即使未来某个版本移除了它,插件也不会崩,只会停用聊天称号格式并在控制台提示(Tab / 头顶显示不受影响)
    • 调度器在 Bukkit.getScheduler() 不可用时自动改用区域调度器(Folia / 新架构服务端)
    • 最大血量改从属性 API 读取,同时兼容 MAX_HEALTH 新名与 GENERIC_MAX_HEALTH 旧名,失败回退 Player#getMaxHealth()
  • 支持范围更新为 Spigot / Paper / Purpur 1.16.x ~ 26.3

二、顺带修掉 1.16 / 1.17 的兼容问题

之前用到了 1.18 才有的配置注释 API(getComments / setComments),在 1.16/1.17 上会抛 NoSuchMethodError(被捕获所以不崩溃,但有三处功能静默降级)。现在改为反射探测调用:

功能1.18+1.16 / 1.17
保存配置保留注释保留不再报错(该版本没有注释 API,所以注释不保留)
升级自动补全新配置项是可补新项
生成 messages_xx.yml是是

三、源码整理

  • 按要求移除了 Java 源码中的全部注释,只保留 config.yml 与 build.gradle 里的少量配置说明
  • 代码逻辑没有任何变化:编译验证与 73 项逻辑测试全部通过
  • 带注释的完整源码另有备份,需要对照或恢复随时说

1.6.0 更新内容 · 商品三态与属性条件系统

本次更新来自用户反馈:「能不能加一个支持添加不可售卖的头衔」 与 「能不能兼容一下属性插件」。

一、不可售卖的头衔(商品三态)

商店商品现在有三种状态,用 /titleadmin shop state <ID> <类型> <状态> 切换:

状态效果
sellable正常出售,玩家可购买(默认)
display展示但不可购买:仍在商店列表里,橙色灰显并显示备注(如「活动限定 · 参与活动获得」),玩家点击会收到获取方式提示
hidden完全隐藏:不出现在玩家的商店界面,只能由管理员指令 / 活动 / 自动规则发放
  • 备注文本:/titleadmin shop note <ID> <类型> 活动限定:参与周末活动获得(支持颜色代码,填 clear 清空)
  • 商品列表、GUI 悬浮说明都会显示状态与备注;管理面板的商店按钮会统计「在售 / 展示 / 隐藏」数量
  • 玩家点击不可购买的商品会提示获取方式,而不是一句笼统的「购买失败」
  • 隐藏商品与不存在的商品在购买接口上一视同仁,玩家无法探测到隐藏内容

二、属性插件兼容(条件系统增强)

  • 条件表达式:支持 &&(且)、||(或)、!(非)、括号、区间 in 10..30 / not in 10..30、
    字符串 equals / contains / startsWith / endsWith / matches(正则)、以及真值判断
  • 比较运算符:> >= < <= == !=,也接受 SQL 风格写法 => =< <>(含义相同)
  • 易踩坑的两点(1.6.0 起行为固定下来):
    • matches 是整串匹配,%world% matches world 不会命中 world_nether;要模糊匹配请写 matches world.*
    • 比较运算符右侧解析为空(例如变量没装好、写错名字)时一律判定为不满足,不会再出现
      「条件恒为真、全服玩家都拿到称号」的情况;真值判断里 0、0.0、0%、-0 都算假
  • 数值容错:属性插件输出的 1,234、85%、物理攻击 120 这类文本都能解析出数字参与比较
    (旧版遇到这些会直接判定为「不满足」,这正是很多人觉得「属性插件不兼容」的原因)
  • 内置变量(不需要 PlaceholderAPI):
    {level} {exp} {health} {health_percent} {food} {gamemode} {world}
    {playtime_minutes} {first_played_days} {kills} {deaths} {mob_kills} {walk_km}
    {balance} {vault_balance} {currency} {titles} {suffixes} {online_players} {hour}
    {perm:权限节点}、{has_title:ID}、{has_suffix:ID}
  • PAPI 变量解析失败不再误判:旧版会把 %ap_attack_2% 里的数字 2 当成数值比较
  • 新增排查指令 /titleadmin autotest <玩家>:逐条显示每条规则的变量解析结果与判定结论,
    一眼看出是变量没解析出来、还是阈值写错了
  • 未安装 PlaceholderAPI 时不再整体关闭自动称号;只用内置变量的规则照常工作,控制台会提示哪些变量需要 PAPI

三、兼容性

  • 旧的 %xxx% >= 数字 写法完全兼容,老配置可直接沿用
  • config.yml 会自动补充新选项与注释(config-version: 9),不需要删除配置文件
  • 数据库自动迁移:shop_items 自动增加 state、note 两列,player_titles 的 is_auto 列同样自动补齐

1.6.0 更新内容 · BUG 修复与新增功能

修复的重要 BUG

#问题说明
1更新检测关闭了全服 SSL 校验旧版调用 setDefaultSSLSocketFactory / setDefaultHostnameVerifier(→true),等于让整个服务端(含其他插件、登录验证)的 HTTPS 都可被中间人劫持。已彻底移除。
2更新检测从未成功过GitHub 返回的是 "tag_name": "1.3.0"(冒号后有空格),旧版按 "tag_name":" 精确匹配,永远解析失败。已改为正则匹配,并把网络请求改为异步(不再卡开服)。
3聊天打 % 会整条消息丢失旧版把头衔+名字+后缀+消息整串塞进 setFormat(),Bukkit 还会再执行一次 String.format,只要消息里有 % 就抛异常。现在格式里只放 %1$s/%2$s,其余 % 自动转义。
4数据库抖动会把玩家金币清零旧版 getBalance() 在 SQL 异常时也会执行 setBalance(uuid, 0)。现在异常只返回默认值,绝不写库。
5RGB 模式显示成乱码旧版渐变没有处理 &d 这类传统颜色码,会给每个字符(包括 &、d 本身)加颜色前缀,结果头衔显示为字面量 &d[&d萌新喵]&7。已重写渐变算法。
6重载会清空 config.yml 的全部注释旧版任何开关/切语言/重载都会 saveConfig(),Bukkit 保存时会丢掉注释。现在保存前会从磁盘读回注释,注释不再丢失。
7Folia 上直接抛异常旧版声明 folia-supported: true 却使用 Bukkit.getScheduler()。现在统一走调度器封装,Folia 下自动使用区域调度器。
8没装 PAPI 时开属性支持会崩旧版无条件调用 PlaceholderAPI(只是 softdepend),会 NoClassDefFoundError。现在先检测,再安全降级。
9自动称号收不回来条件不再满足时,旧版调用 removeTitle() 会因“称号正在激活”被拒绝,导致称号永远收不回;clearAllAutoTitles() 还是空实现。现在会先停用再移除,并且只收回自动授予的(不会误删玩家自己买的)。
10商店商品主键错误shop_items 主键只有 id,导致“头衔 ID 5”和“后缀 ID 5”无法共存。启动时自动迁移为 (id, type) 复合主键。
11shop.default-balance 配置无效README 写了“新玩家默认金币”,实际代码从未读取。现已生效。
12MySQL/PG 连不上就没有回退README 承诺“自动切换 SQLite”,实际没有实现,导致存档静默失败。现已实现。
13默认头衔不可配置旧版硬编码 &d[&d萌新喵]&7。现在读取 settings.default-title。
14管理员面板 TPS 是假的旧版恒为 20.00。现在 Paper 读取真实 TPS,其他服务端用 tick 计时器统计 1m/5m/15m。
15切语言后面板标题不变AdminGUI.TITLE 是 static final,已改为每次打开时读取。
16控制台 Tab 补全报 ClassCastException玩家指令的补全直接 (Player) sender 强转,控制台执行时崩溃。
17GUI 可以让玩家拖入物品旧版只拦了点击事件,未处理 InventoryDragEvent。
18InventoryHolder#getInventory() 返回 null容易在 Paper/Folia 上触发 NPE,现在返回真实 Inventory。
19并发安全隐患聊天事件是异步线程读取玩家称号缓存,旧版用普通 HashMap;现已改为并发容器。
20ID 为 0 的称号永远无法激活setActiveTitle 里的条件是 id > 0,已修正。
21构建产物缺少数据库驱动implementation 的 JDBC 驱动不会被打进插件 jar,导致“内置 SQLite”实际连不上。现在 gradlew build 会打出包含驱动的完整 jar。
22其他%catcraft_balance% 未考虑商店关闭、AutoTitleManager 文件目录与包名不一致、属性支持重载后规则不生效、大量硬编码中文提示、英文文案参数顺序错误等。

新增功能

  • Vault 经济支持:shop.currency: internal|vault,可在配置文件或 /titleadmin shop currency 切换,未装 Vault 时自动回退内置金币。
  • Tab 列表 + 头顶昵称显示称号/后缀:基于记分板 team 实现,可开关;若玩家已被其他记分板/Rank 插件接管,插件会尊重原有显示。
  • 可配置 RGB 渐变:settings.gradient-colors 支持 1 段纯色到多段平滑渐变,支持 &#RRGGBB 十六进制颜色。
  • 可配置聊天格式:chat.format 支持 {title} {name} {suffix} {message},可设置是否覆盖其他聊天插件的格式。
  • 自定义消息文件:自动生成 messages_zh.yml / messages_en.yml,所有文案服主都能改;升级后新增的键会自动补进现有文件,不会覆盖你的修改。
  • 配置自动升级:插件启动/重载时会把新版本新增的配置项补进你现有的 config.yml(保留原有内容与注释),不再需要删掉配置文件重新生成。
  • 权限节点可配置:permissions.admin / use / shop,可对接服务器现有权限体系。
  • 真正的 Folia 适配:folia-supported: true 名副其实。
  • 新增指令:/titleadmin reload、/titleadmin shop toggle、/titleadmin shop currency。


功能特点

  • 多级头衔体系:每个玩家可拥有多个头衔,按 ID 独立管理,自由切换启用
  • 独立后缀系统:头衔与后缀分离设计,玩家可单独控制每个后缀的启用/关闭
  • 图形化 GUI 管理:玩家可通过 /catcraft gui 打开直观的界面管理所有称号
  • 管理员 GUI 控制面板:/titleadmin panel 查看真实 TPS/在线/内存、切换语言、开关功能、重载配置
  • 自动称号系统:基于 PlaceholderAPI 占位符,按等级、金币、击杀数等自动授予/收回称号,支持 >= <= == != > <
  • 实时语言切换:GUI 面板一键中英文切换,消息即时生效
  • 独立功能开关:RGB 渐变、商店、属性支持、Tab 显示、聊天格式均独立开关
  • 跨服数据同步:支持 MySQL / PostgreSQL,多服务器共享玩家数据
  • 本地存储备选:MySQL/PostgreSQL 连接失败自动回退 SQLite,数据不丢失
  • 无需重启修改:管理员可直接修改头衔显示名,即时生效
  • 玩家自助管理:玩家可通过指令或 GUI 管理自己的头衔和后缀
  • 默认头衔系统:无头衔玩家显示可配置的默认头衔
  • RGB 渐变色支持:渐变色可自定义,支持十六进制颜色
  • 完全国际化:中文/英文一键切换,文案可在消息文件中自由修改
  • PlaceholderAPI 支持:提供 %catcraft_title%、%catcraft_suffix%、%catcraft_balance% 等变量
  • 内置商店与金币系统:支持内置金币或 Vault 经济,每日签到可获得金币
  • 不可售卖的头衔:商品支持「可购买 / 展示但不可购买 / 完全隐藏」三态,可写备注(如「活动限定」)
  • 强大的自动称号条件:且/或/非、区间、字符串、正则、数值容错,并内置 30+ 变量(不依赖 PlaceholderAPI)
  • 启动信息看板:控制台显示版本、作者、数据库、PAPI/Vault、调度器状态

注意事项

  • PlaceholderAPI 不是必需的:只有「自动称号」与占位符变量需要它。
  • Vault 不是必需的:只有 shop.currency: vault 需要它。
  • 从旧版本升级时不需要删除 config.yml,插件会自动补全新选项并保留你的注释与设置。
  • 离线(非正版)服务器完全支持:面板里按名字搜索离线玩家时,插件会先查自己的 player_names 名字缓存;离线服还会按 Minecraft 的「离线 UUID」规则直接匹配玩家名(UUID.nameUUIDFromBytes("OfflinePlayer:名字")),不依赖 usercache.json。
  • 离线服注意:玩家改名后会得到新的 UUID(这是离线模式的机制),旧称号仍留在原 UUID 名下。
  • 本插件需要 Java 8 或更高的服务端运行环境;构建需要 JDK 17+(Gradle wrapper 已升级到 9.3.0,兼容较新的 JDK)。

头衔以及后缀统一管理 - GUI 界面

GUI


管理员 GUI 控制面板

admingui


兼容服务端

  • 支持:Paper 1.16.x ~ 26.3、Purpur 1.16.x ~ 26.3、Spigot 1.16.x ~ 26.3
  • 支持:Folia 1.19.4 ~ 26.3(Folia 自 1.19.4 起提供)
  • 不支持:Bukkit(不推荐)、Sponge / BungeeCord / Velocity

Folia 上的显示说明:Folia 1.19.x 的记分板队伍 API 尚未开放(registerNewTeam 会抛异常),
插件的 Tab/头顶显示会自动降级为「Tab 名字前缀」,并在控制台打印一次提示;聊天称号格式、
GUI、头衔/后缀功能不受影响。服务端版本较新的 Folia 若已支持记分板,则自动使用完整显示。

兼容数据库

  • MySQL(驱动已内置)
  • PostgreSQL(驱动已内置)
  • SQLite(驱动已内置)

必要前置

前置插件必需性说明
PlaceholderAPI可选自动称号条件解析与占位符变量
Vault + 经济插件可选使用 Vault 经济作为货币时必需
MySQL / PostgreSQL可选跨服数据库(不使用则用 SQLite)

玩家指令

指令说明
/catcraft gui打开图形化称号管理界面
/catcraft shop打开商店首页(头衔/后缀分类购买)
/catcraft list查看自己拥有的所有头衔和后缀及其激活状态
/catcraft active <ID>激活指定 ID 的头衔(再次执行则停用)
/catcraft deactive停用当前激活的头衔,恢复默认
/catcraft suffixactive <ID>激活指定 ID 的后缀(再次执行则停用)
/catcraft suffixdeactive停用当前激活的后缀
/catcraft remove <ID>移除自己拥有的某个称号(不能移除当前激活的/自动授予的)

管理员指令(需 catcraft.admin 权限)

控制面板与维护

指令说明
/titleadmin panel打开管理员 GUI 控制面板
/titleadmin reload重载 config.yml、消息文件、聊天格式与自动称号规则
/titleadmin autotest [玩家]查看自动称号规则的变量解析与判定详情(排查属性插件变量)

头衔管理

指令说明
/titleadmin give <玩家> <ID> <显示名>为玩家添加一个头衔(ID 必须全局唯一)
/titleadmin edit <玩家> <ID> <新显示名>修改玩家某个头衔的显示名
/titleadmin take <玩家> <ID>移除玩家的某个头衔(会自动停用)
/titleadmin list <玩家>查看玩家拥有的所有头衔及其激活状态
/titleadmin setactive <玩家> <ID>激活玩家的某个头衔
/titleadmin deactive <玩家>停用玩家当前激活的头衔

后缀管理

指令说明
/titleadmin suffixgive <玩家> <ID> <显示名>为玩家添加一个后缀
/titleadmin suffixedit <玩家> <ID> <新显示名>修改玩家某个后缀的显示名
/titleadmin suffixtake <玩家> <ID>移除玩家的某个后缀
/titleadmin suffixlist <玩家>查看玩家拥有的所有后缀
/titleadmin suffixsetactive <玩家> <ID>激活玩家的某个后缀
/titleadmin suffixdeactive <玩家>停用玩家当前激活的后缀

商店管理

指令说明
/titleadmin shop add <ID> <类型(0/1)> <价格> <显示名>添加商品
/titleadmin shop remove <ID> <类型>移除商品
/titleadmin shop setprice <ID> <类型> <新价格>修改价格
/titleadmin shop list列出所有商品与当前货币类型
/titleadmin shop givebalance <玩家> <金额>增加玩家余额(支持小数)
/titleadmin shop setbalance <玩家> <金额>设置玩家余额
/titleadmin shop toggle开关商店(并写回配置)
/titleadmin shop currency <internal|vault>切换货币类型(并写回配置)
/titleadmin shop state <ID> <类型> <sellable|display|hidden>设置商品状态(不可售卖的头衔用 display 或 hidden)
/titleadmin shop note <ID> <类型> <备注|clear>设置/清空商品备注(如「活动限定」)

类型:0 表示头衔,1 表示后缀。


权限节点

权限默认说明
catcraft.adminop管理员指令与管理员面板
catcraft.use所有人玩家指令与称号 GUI
catcraft.shop所有人商店与每日签到

以上权限名都可以在 config.yml 的 permissions 段改成你服务器现有的权限名。


PlaceholderAPI 变量

变量说明
%catcraft_title%当前激活的头衔(含颜色/RGB)
%catcraft_title_plain%当前激活的头衔(纯文本,去颜色)
%catcraft_suffix%当前激活的后缀(含颜色/RGB)
%catcraft_suffix_plain%当前激活的后缀(纯文本,去颜色)
%catcraft_balance%当前余额(按货币类型格式化)
%catcraft_currency%当前货币类型名称
%catcraft_active_title_id% / %catcraft_active_suffix_id%当前激活的 ID(未激活为 -1)
%catcraft_title_count% / %catcraft_suffix_count%拥有的头衔/后缀数量
%catcraft_shop_enabled%商店是否开启

配置文件(自动生成,示例)

config-version: 9          # 请勿手动修改(插件据此自动补充新选项)
language: zh               # zh / en

database:
  type: sqlite             # mysql / postgresql / sqlite(连接失败自动回退 sqlite)
  mysql:
    host: localhost
    port: 3306
    db: your_db
    user: your_user
    pass: your_pass
  postgresql:
    host: localhost
    port: 5432
    db: your_db
    user: your_user
    pass: your_pass
  sqlite:
    file: catcraft.db

permissions:               # 可改成你服务器现有的权限名
  admin: "catcraft.admin"
  use: "catcraft.use"
  shop: "catcraft.shop"

settings:
  debug: false
  enable-rgb: false
  gradient-colors:         # 1 段纯色或多段平滑渐变
    - "FF0000"
    - "FF00FF"
    - "8000FF"
  default-title: "&d[&d萌新喵]&7"   # 留空则不显示默认头衔
  attribute-support: false
  auto-check-interval: 30  # 自动称号检查间隔(秒)
  check-update: true
  update-check-interval-hours: 6   # 每隔几小时自动检查一次更新
  update-notify-console: true      # 发现新版本时在控制台提示
  update-notify-ops: true          # 发现新版本时在聊天栏通知在线管理员
  messages-file: true

chat:
  enabled: true
  format: "{title}{name}{suffix}: {message}"
  override-format: true    # false = 只在原版格式下接管
  display-name: true       # Tab 列表 + 头顶昵称显示称号

shop:
  enabled: false
  currency: internal       # internal / vault
  default-balance: 0       # 新玩家初始金币
  signin-reward: 30        # 每日签到奖励(0 = 只记录签到、不发金币)
  # 商品的三态与备注不需要写在配置里,用指令或管理面板设置:
  #   状态  /titleadmin shop state <ID> <类型> <sellable|display|hidden>
  #         sellable = 可购买 | display = 展示但不可购买 | hidden = 商店中完全隐藏
  #   备注  /titleadmin shop note <ID> <类型> <文本>(如「活动限定」,填 clear 清空)

# 自动称号规则(仅当 settings.attribute-support 为 true 时生效)
#
# 条件写法(1.6.0):
#   数值比较 : %player_level% >= 30      也支持 <= == != > < 与反向写法 30 <= %player_level%
#              另外接受 SQL 风格写法 => =< <>(含义分别是 >= <= !=)
#   且 / 或  : %a% >= 10 && %b% < 5      || 表示或,! 表示非,可用括号改变优先级
#   区间     : {level} in 10..30          not in 10..30 表示不在区间内
#   字符串   : %job% equals 战士          contains / startsWith / endsWith / matches(正则)
#              matches 为整串匹配:%world% matches world 不会命中 world_nether,模糊匹配请写 world.*
#              比较运算符右侧解析为空时一律判为不满足(避免变量写错导致全服都拿到称号)
#   真值判断 : %some_flag%                非空且不是 false/no/0/off/无/否 即为真(0 / 0.0 / 0% 都算假)
# 变量写法:
#   %xxx% —— PlaceholderAPI 变量(需要装 PlaceholderAPI 与对应插件)
#   {xxx} —— 插件内置变量,不需要 PAPI:{level} {health} {food} {playtime_minutes}
#            {kills} {deaths} {balance} {titles} {online_players} {hour}
#            {perm:权限节点} {has_title:ID} 等
# 数值容错:1,234 / 85% / 物理攻击 120 这类文本都能正确解析
# 排查问题:/titleadmin autotest <玩家>
auto-rules:
  - id: 1
    type: 0                # 0=头衔,1=后缀
    display: "&6[&e老手&6]"
    condition: "%player_level% >= 30"
  - id: 2
    type: 1
    display: " &8[&7大佬&8]"
    condition: "%vault_eco_balance% > 1000"
  - id: 3                  # 只用内置变量,不需要 PlaceholderAPI
    type: 0
    display: "&b[&f冒险者&b]"
    condition: "{level} in 10..30 && {playtime_minutes} > 1440"
  - id: 4                  # 属性插件变量 + 内置变量 + 权限判断混用
    type: 1
    display: " &8[&6VIP&8]"
    condition: "{perm:group.vip} == true || %ap_attack% > 500"

数据库结构

CREATE TABLE player_titles (
    uuid VARCHAR(36) NOT NULL,
    title_id INT NOT NULL,
    title_display VARCHAR(255) NOT NULL,
    type INT DEFAULT 0,       -- 0=头衔, 1=后缀
    is_active BOOLEAN DEFAULT FALSE,
    is_auto BOOLEAN DEFAULT FALSE,  -- 1.4.0 新增:是否由自动规则授予
    PRIMARY KEY (uuid, title_id)
);

CREATE TABLE shop_items (
    id INT NOT NULL,
    type INT NOT NULL,        -- 0=头衔商品, 1=后缀商品
    display VARCHAR(255) NOT NULL,
    price INT NOT NULL,
    state INT NOT NULL DEFAULT 0,        -- 1.5.0 新增:0=可购买, 1=仅展示, 2=隐藏
    note VARCHAR(128) NOT NULL DEFAULT '', -- 1.5.0 新增:备注(如「活动限定」)
    PRIMARY KEY (id, type)    -- 1.4.0:旧表(主键只有 id)会在启动时自动迁移,数据不丢
);

CREATE TABLE player_balances (
    uuid VARCHAR(36) PRIMARY KEY,
    balance INT NOT NULL DEFAULT 0
);

CREATE TABLE player_names (           -- 1.6.0 新增:玩家名缓存(面板搜索/离线服显示用)
    uuid VARCHAR(36) PRIMARY KEY,
    name VARCHAR(32) NOT NULL,
    last_seen BIGINT NOT NULL DEFAULT 0
);

CREATE TABLE player_signin (
    uuid VARCHAR(36) PRIMARY KEY,
    last_signin BIGINT NOT NULL DEFAULT 0
);

所有表在插件首次启动时自动创建;旧版本的表结构会在启动时自动迁移,无需手动操作。


从源码构建

./gradlew build          # 产物在 build/libs/CatCraftTitle-x.y.z.jar

适配新的 Minecraft 版本时,只需要修改 build.gradle 里的 spigotApiVersion(例如 26.3-R0.1-SNAPSHOT),然后重新执行上面的命令即可。

  • Gradle wrapper 已升级到 9.3.0(旧版 8.10.2 在 JDK 24+ 上会直接构建失败)。
  • 构建出的 jar 已包含 MySQL / PostgreSQL / SQLite 驱动,不需要再额外安装驱动。
  • 推送 v1.6.0 这样的 tag 时,GitHub Actions 会自动构建并发布 Release(工作流见 .github/workflows/build.yml)。

常见问题

Q:玩家没有头衔时显示什么?
A:显示 settings.default-title 配置的内容,留空则什么都不显示。

Q:MySQL/PostgreSQL 连接失败怎么办?
A:插件会自动回退到 SQLite 并在控制台提示,数据不会丢;修好数据库连接后重载即可。

Q:支持 RGB 颜色吗?
A:支持。开启 `settings.enable-r

Similar projects

Plugin →