koishi-plugin-ll-bns-fortune
v0.12.0
Published
剑灵怀旧服每日运势:宜/忌、玄学地图、彩色五角星运势指数,自定义底图出图
Maintainers
Readme
koishi-plugin-ll-bns-fortune
剑灵怀旧服「每日运势」插件:自定义底图 + 宜/忌 + 最佳玄学地图 + 彩色五角星运势指数,一条指令或一句话就出一张图。
特性
- 同一人同一天结果固定:随机种子 =
hash(用户ID + 东八区日期 + 盐),当天怎么发都一样,跨天自动换新。 另外还有一层落库缓存,重启、改配置、换底图都不会让今天的结果乱跳。 - 宜忌成对抽取:一次抽一整对(如「宜睡觉 / 忌熬夜」),结构上不可能出现「宜睡觉 / 忌睡觉」。
- 深色系五角星:默认 8 颗星(满星 8/8),矢量画的 Q 版胖星星,深红→赭橙→橄榄→墨绿→深青→靛蓝→深紫→暗紫红,未点亮的深紫描边。不依赖 emoji 字体,服务器上不会退化成方块。
- 关键词触发:群里说到「今日运势」「人品」之类就自动发,不用敲指令(可设冷却和每群每日上限)。
- 权重可控:8 档运势指数(钟形分布)、频道号、每一条宜忌对、每一个地图都能单独配权重。
- 剑灵怀旧服地图池:内置御龙林 / 大漠 / 水月平原 / 白青山脉 共 32 条。
- 全部可在设置页改:文案、地图、坐标、配色、字体、输出格式都不用改代码。
- 没有 canvas 也能跑:检测不到 canvas 时自动降级发纯文字,指令不会被打死。
安装
npm i koishi-plugin-ll-bns-fortune
npm i @napi-rs/canvas # 出图用,预编译二进制,不需要编译工具链装好插件后在 Koishi 控制台启用即可。插件本身不依赖数据库,但建议启用:开了落库缓存才能用「同一天不重算」,以后也好加历史查询。
@napi-rs/canvas也可以不装,此时插件只发文字。装了canvas(node-canvas)或@koishijs/plugin-canvas也能被自动识别,优先级是@napi-rs/canvas→canvas→ctx.canvas。
指令
| 指令 | 说明 |
|---|---|
| 运势 | 出图(默认) |
| 运势 文字 | 强制发文字 |
| 运势 图片 | 强制出图 |
指令名、别名都能在设置页改(默认 运势 / 今日运势 / jrys)。
关键词触发
不想让群友记指令,就打开设置页的 关键词触发:
| 配置项 | 默认 | 说明 |
|---|---|---|
| keywordReply | 关 | 总开关 |
| keywords | 今日运势 运势 jrys 人品 玄学 | 关键词列表,也可以填正则 |
| keywordMatch | contains | 匹配方式:包含 / 整句等于 / 正则 |
| keywordReplyTemplate | 空 | 抬头文案,支持 {at} {keyword} |
| keywordScope | group | 生效范围:所有会话 / 仅群聊 / 仅私聊 |
| keywordCooldown | 30 | 同一个人多少秒内只回一次,防刷屏 |
| keywordOncePerGroup | 0 | 每个群每天最多触发几次,0 = 不限 |
注意:关键词和指令是两套触发方式。如果两边都开着,而同名的词又同时出现在「指令名」和「关键词」里, 同一条消息可能会被响应两次。建议只留一种:要么用指令(
指令名保留、关键词关掉), 要么用关键词(把「指令名」改成不常用的一两个,比如bns运势,关键词里放运势)。
默认版式
角色立绘在左,右侧宣纸面板放文字。标题和五角星居中,其余内容左对齐(和参考排版一致), 整个文字块自动垂直居中,字号自动适配面板。
内置底图 assets/bg.png(1672×941)对应的面板几何:
| 配置项 | 默认值 | 含义 |
|---|---|---|
| panel.x | 0.607 | 面板左边缘 / 整图宽度 |
| panel.y | 0.180 | 面板上边缘 / 整图高度 |
| panel.w | 0.312 | 面板宽度 / 整图宽度 |
| panel.h | 0.668 | 面板高度 / 整图高度 |
| panel.paddingX | 0.06 | 面板内左右留白 / 面板宽 |
| panel.paddingY | 0.035 | 面板内上下留白 / 面板高 |
| panel.charsPerLine | 22 | 字号基准(= 文字块宽 / 这个值);这只是起点,实际字号会按高度自动放大 |
| panel.measureRatio | 0.98 | 文字块最大宽度占可用宽度 |
| panel.lineHeight | 1.62 | 行高倍数 |
| panel.blockFill | 1.0 | 松紧度:1 = 撑满可用区,调大留白更多 |
| panel.align | left | 整体对齐:left 左对齐 / center 居中 |
| panel.starSize | 1.15 | 五角星大小(相对字号倍数;8 颗星时别调太大,会顶出面板) |
| panel.starSpacing | 1.32 | 五角星间距 |
换底图时只改这几个数就行,其他不用碰。
字号是自动的:先按 charsPerLine 估一个起点,再二分放大到「刚好占满可用高度」(上限 2.4 倍,
并且只撑到 97% 留一点余量)。所以内容多的时候字小、内容少的时候字大,不用手动调。
嫌排版挤就按这个顺序调:
panel.blockFill调大(1.05→1.10)—— 四周留白立刻变多panel.lineHeight调大(1.7左右)—— 行与行之间更松panel.paddingY/panel.paddingX调大 —— 文字区整体收窄- 还挤就是文案太长,配合改
template或缩短宜忌文案
五角星(两种样式)
默认是 宝石质感:金色渐变 + 深金描边 + 内圈高光 + 中心亮斑,未点亮的星是浅灰平涂 + 深灰描边。 这是参考图那种立体星星,和「深色系平涂」是两个可切换的样式(设置页 panel.starStyle)。
深色系五角星(flat 样式)
运势指数不是文字,而是画出来的矢量五角星。默认 8 颗星,满星 = 8/8;形状是圆润的 「Q 版胖星星」(二次贝塞尔抹圆尖角,内圈半径带一点随机起伏),配色是深色系:
| 配置项 | 默认 | 说明 |
|---|---|---|
| starColors.fill | 深红 #9E2B3F → 赭橙 #A8541F → 橄榄 #8F7A14 → 墨绿 #3F6B33 → 深青 #1F5F6B → 靛蓝 #2B4C8C → 深紫 #4A3A82 → 暗紫红 #7A2E63 | 点亮的星,按第 1~8 颗依次取用 |
| starColors.empty | 深紫 #6B5F86 | 未点亮的星:淡填充 + 圆润深色描边 |
| starWeights.maxStars | 8 | 一共几颗星(满星 = 这个数) |
| starWeights.one ~ eight | 2/6/12/20/22/18/12/8 | 各档权重,默认钟形分布 |
不用 emoji、也不用额外字体文件,所以在没装中文字体的 Linux 服务器上也不会退化成黑白方块。 想换成自己的素材图也可以(以后要加)。
文案池写法
宜忌对(pairs)
一条一对,四种写法:
合卡|炸卡
打团本|单飞|3
睡觉|熬夜|1|快睡吧,今天的梦里什么都有
睡觉|熬夜|1|快睡吧,今天的梦里什么都有|今天或许值得再给好运一次机会。依次是:宜词 | 忌词 | 权重 | 详细文案 | 忌的详细文案。
第 3 段如果是纯数字就按权重解析,否则按详细文案处理。
- 想让某条更容易出现:写
打团本|单飞|5,或者干脆把这一行多写几遍(效果一样,还更好懂)。 - 只给词的话,标签会自动生成(
宜打团本:),模板里的{goodText}一行为因为重复而自动省略,不会出现「宜合卡:合卡」这种废话。 - 想要「宜睡觉:快睡吧…」这种效果,就带上第 4/5 段详细文案。
地图(maps)
一行一条,格式 主地图 · 子区域:
御龙林 · 竹林海岸|1|烟花从未停歇,今晚的梦里似乎藏着一个好结果。
大漠 · 土门客栈
水月平原 · 江流市|3- 第 2 段是纯数字就当权重,否则当文案 → 所以
地图名|文案也能直接用。 - 地图下面那行
{mapText}取的是这条地图自己的文案;没写文案的地图默认就不显示这一行。 - 想让所有地图都用同一句兜底文案,就把
mapTextFallback打开,再填mapText。
排版模板(template)
[center][size=0.86]您今日的运势指数为:
[center]{stars}
[size=0.74]今日幸运频道:{channel}
[size=0.74]宜{good}:{goodText}
[size=0.74]忌{bad}:{badText}
[size=0.74]今日最佳玄学地图是:{map}
[size=0.74]{mapText}行首可以加两种标记(顺序随意,可以叠加):
| 标记 | 作用 |
|---|---|
| [center] / [left] | 这一行的对齐方式,不写就跟随 panel.align |
| [size=0.74] | 这一行的字号倍率(相对整体字号) |
字号层级(默认):五角星(panel.starSize 控制)最大 → 标题 0.86 → 正文 0.74。
整体字号由 panel.charsPerLine 决定,行宽则由 panel.paddingX 决定;标记里的倍率是乘在整体字号上的,
所以想让整块字都大一圈,调 charsPerLine(调小 = 更大),而不是去改这些倍率。
{stars} 单独占一行时会被画成彩色五角星,并且自动居中。
可用占位符:
| 占位符 | 内容 |
|---|---|
| {stars} | 运势指数(绘制阶段画彩色五角星;文字降级时是 ★★★★☆) |
| {starCount} | 星数数字(1~5,一般不用自己写) |
| {channel} | 频道号 |
| {good} / {bad} | 宜 / 忌的短标签(放在「宜…:」里) |
| {goodText} / {badText} | 宜 / 忌的详细文案 |
| {map} | 玄学地图 |
| {mapText} | 地图下面那句补充说明 |
| {date} | 当日日期(YYYY-MM-DD) |
| {userId} | 用户 ID |
抽取逻辑
pairMode(默认开):成对抽取。关掉则goodLines/badLines和所有宜忌词混在一起各自独立随机。checkSame:独立模式下的保险,抽到宜忌同词就重抽。starMode:person(每人一套)/global(当天全群共用一套)。seedSalt:换一个值 = 整体换一批结果。想「重置全群运势」就改这里。
出图与输出
| 配置项 | 默认 | 说明 |
|---|---|---|
| background | 内置 assets/bg.png | 支持 http(s) 直链 / 绝对路径 / 插件相对路径 |
| renderScale | 2 | 渲染倍率。文字发糊就调到 2 或 3 |
| imageFormat | jpeg | 可选 jpeg / webp / png。JPEG 编码最快(1280 宽约 70ms),PNG 最慢(约 350ms)。要加透明装饰图就必须改回 png/webp |
| outputWidth | 1280 | 输出图片宽度。0 = 改用 renderScale 倍率渲染 |
| imageQuality | 92 | WebP / JPEG 质量 |
| fontPath | 站酷快乐体 | 字体:填字体名(自动下载)、系统字体名或文件路径。默认已填 Q 版字体,开箱即用 |
| fontFamilies | 按系统给默认值 | 字体族优先级 |
| decorations | [] | 装饰图层,见下 |
关于字体:Linux 服务器上如果没装中文字体,会画成方块。三种办法:
直接填字体名,插件自动下载(推荐,跨平台都能用):
| 填这个 | 字体 | 风格 | |---|---|---| |
站酷快乐体| ZCOOL KuaiLe | 圆头圆脑、笔画粗,最接近 Q 版 | |得意黑| Smiley Sans | 倾斜、活跃、有冲击力 | |霞鹜文楷| LXGW WenKai | 手写感楷体,温柔耐看 | |站酷小薇体| ZCOOL XiaoWei | 清秀偏楷,安静 | |马善政毛笔楷| Ma Shan Zheng | 毛笔楷书,国风古风 |下载后会缓存在
<数据目录>/data/ll-fortune/fonts/,只下一次,之后走本地文件。 下载失败不影响出图,只是退回默认字体并在日志里说明。填系统字体名:
幼圆、华文琥珀、华文彩云、方正姚体、微软雅黑、楷体等。 插件会直接定位到对应的字体文件再注册(canvas 不保证自己扫系统目录,指到文件最稳)。填文件路径或直链:
/usr/share/fonts/.../NotoSansCJK-Regular.ttc,或任意.ttf下载地址。
只装字体不打字也行:
apt install fonts-noto-cjk关于格式:webp 体积通常只有 PNG 的 1/5,但部分自建协议端不支持 WebP,会发出去裂图。如果遇到这种情况就切回 png;出图失败时插件本身也会自动退回 PNG 再试一次。
关于装饰图:decorations 是个数组,每项:
- url: https://图床/印章.png # 建议透明 PNG
x: 0.62 # 左上角 X,占整图宽度比例
y: 0.78 # 左上角 Y,占整图高度比例
w: 0.12 # 宽度,占整图宽度比例
opacity: 1默认是空的,不加也完全不影响出图。以后想加印章、花钿、飘带,往这里塞一条就行,不用改代码、不用发新版。
装饰图请走图床(透明 PNG),别让图床把透明通道转成白底。
配色
宣纸是暖白色,默认配色按它调过:
| 配置项 | 默认 | 用途 |
|---|---|---|
| colors.text | #4A3A55 | 正文(深紫灰,不用纯黑) |
| colors.accent | #B0306A | 高亮:频道号、宜忌词、地图 |
| colors.star | #C8434F | 星星(朱红,呼应边框) |
自测
node _dev/selftest.js会检查:同人同日一致性、跨天变化、4000 次抽样无「宜=忌」、权重分布、全局口径、文案池解析、模板去重、真实出图。
出图结果写到 _dev/preview-1x.png 和 _dev/preview-2x.webp,可以直接肉眼看排版。
目录
lib/index.js Schema 配置 + 指令 + 落库缓存
lib/render.js canvas 渲染:面板几何、自动字号、孤字控制、装饰图
lib/util.js 东八区日期、FNV 种子随机、权重抽取、中文换行
lib/data.js 默认文案池(24 对宜忌 + 32 条地图 + 模板)
assets/bg.png 内置底图
_dev/ 本地自测脚本与预览图(不随 npm 包发布)