Files

53 lines
1.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 🤖 bottts 机器人头像生成共享逻辑(预览页与 PNG 渲染共用,保证 seed 序列一致)
* - 过滤负面表情变体:eyes.dizzy(眩晕)、mouth.bite(龇牙)
* - 确定性 seed(agent-N),负面/重复时自动追加后缀重试
*/
'use strict';
/** 负面变体特征字符串(来自 dicebear-bottts.js 定义,命中即视为负面表情) */
const NEG_MARKERS = [
'M30.5 15.3c.4-.4', // eyes.dizzy(眩晕旋转眼)
'6-8H10z' // mouth.bite(咬合龇牙)
];
function isNegative(svg) {
return NEG_MARKERS.some(m => svg.includes(m));
}
/**
* 生成 count 个不重复、非负面表情的头像
* @param {(seed:string)=>{svg:string}} render 渲染函数(同 seed 同输出)
* @param {number} count 数量
* @returns {{seed:string, svg:string}[]}
*/
function generateSeeds(render, count) {
const out = [];
let n = 1;
let guard = 0;
const MAX_GUARD = count * 120 + 5000;
while (out.length < count) {
if (++guard > MAX_GUARD) {
throw new Error(`[bot-common] 生成 ${count} 个唯一头像失败:该风格可能渲染无变化(n=${n}, 已有 ${out.length})`);
}
let seed = 'agent-' + n;
let svg = render(seed).svg;
if (!svg) { n++; continue; } // 空渲染直接跳过
let attempt = 0;
while (isNegative(svg) || out.some(o => o.svg === svg)) {
attempt++;
if (attempt > 60) break; // 保护
seed = 'agent-' + n + '-' + attempt;
svg = render(seed).svg;
if (!svg) { n++; break; }
}
if (!isNegative(svg) && !out.some(o => o.svg === svg)) {
out.push({ seed, svg });
}
n++;
}
return out;
}
module.exports = { generateSeeds, isNegative };