koishi-plugin-ll-mc 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +69 -8
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -398,6 +398,12 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
398
398
|
koishi_1.Schema.object({}),
|
|
399
399
|
]),
|
|
400
400
|
]),
|
|
401
|
+
// --- 群头像手动指定(官机没有群头像,只能手动填) ---
|
|
402
|
+
koishi_1.Schema.object({
|
|
403
|
+
groupAvatarMap: koishi_1.Schema.dict(String)
|
|
404
|
+
.default({})
|
|
405
|
+
.description('群头像手动指定(键=群ID,官机填群openid,OneBot 填数字群号;值=头像图片URL,或直接填数字QQ群号自动生成头像链接)。官机平台不提供群头像接口,只能手动填才能显示真头像。'),
|
|
406
|
+
}).description("群头像手动指定"),
|
|
401
407
|
]);
|
|
402
408
|
const periodMapping = {
|
|
403
409
|
today: { field: "todayPostCount", name: "今日" },
|
|
@@ -487,6 +493,8 @@ async function apply(ctx, config) {
|
|
|
487
493
|
await reloadIconCache();
|
|
488
494
|
await reloadBarBgImgCache();
|
|
489
495
|
await reloadFontCache();
|
|
496
|
+
// 预热 OneBot 群列表(用于官机群头像按群名匹配)
|
|
497
|
+
refreshNapCatGuildMap();
|
|
490
498
|
// 执行非破坏性的状态初始化
|
|
491
499
|
await initializeResetStates();
|
|
492
500
|
// 安全地检查并弥补真正错过的重置任务
|
|
@@ -1958,31 +1966,84 @@ async function apply(ctx, config) {
|
|
|
1958
1966
|
(channelInfo[channelId]?.channelName || `群聊${channelId}`),
|
|
1959
1967
|
// 使用 channelId 作为 RankingData 的 userId 和头像源
|
|
1960
1968
|
userId: channelId,
|
|
1961
|
-
avatar: groupAvatarUrl(channelId),
|
|
1969
|
+
avatar: groupAvatarUrl(channelId, channelInfo[channelId]?.channelName),
|
|
1962
1970
|
count,
|
|
1963
1971
|
percentage: calculatePercentage(count, totalCount),
|
|
1964
1972
|
}));
|
|
1965
1973
|
}
|
|
1966
1974
|
/**
|
|
1967
|
-
* 群头像 URL
|
|
1968
|
-
*
|
|
1969
|
-
*
|
|
1970
|
-
*
|
|
1971
|
-
*
|
|
1975
|
+
* 群头像 URL 解析链:
|
|
1976
|
+
* 1. 配置手动指定 groupAvatarMap(键=群ID,值=URL 或数字群号)
|
|
1977
|
+
* 2. 数字群号(OneBot/NapCat)→ p.qlogo.cn/gh/{群号}
|
|
1978
|
+
* 3. 官机 openid → 按群名从 NapCat 群列表匹配数字群号(两个机器人在同一群时自动生效)
|
|
1979
|
+
* 4. 官机 qqapp 端点尝试(与成员头像同源,多数情况对群无效)
|
|
1980
|
+
* 5. 默认占位头像(下载失败也会走内置兜底)
|
|
1972
1981
|
*/
|
|
1973
|
-
function groupAvatarUrl(channelId) {
|
|
1974
|
-
if (channelId === "#"
|
|
1982
|
+
function groupAvatarUrl(channelId, channelName) {
|
|
1983
|
+
if (!channelId || channelId === "#") {
|
|
1975
1984
|
return `https://p.qlogo.cn/gh/426230045/426230045/100`;
|
|
1976
1985
|
}
|
|
1986
|
+
// 1. 手动指定
|
|
1987
|
+
const manual = config.groupAvatarMap?.[channelId];
|
|
1988
|
+
if (manual) {
|
|
1989
|
+
return /^\d+$/.test(manual)
|
|
1990
|
+
? `https://p.qlogo.cn/gh/${manual}/${manual}/100`
|
|
1991
|
+
: manual;
|
|
1992
|
+
}
|
|
1993
|
+
// 2. 数字群号(OneBot)
|
|
1977
1994
|
if (/^\d+$/.test(channelId)) {
|
|
1978
1995
|
return `https://p.qlogo.cn/gh/${channelId}/${channelId}/100`;
|
|
1979
1996
|
}
|
|
1997
|
+
// 3. 官机 openid:按群名匹配 NapCat 数字群号
|
|
1998
|
+
if (channelName) {
|
|
1999
|
+
refreshNapCatGuildMap();
|
|
2000
|
+
const numeric = napCatGuildIdByName.get(channelName);
|
|
2001
|
+
if (numeric) {
|
|
2002
|
+
return `https://p.qlogo.cn/gh/${numeric}/${numeric}/100`;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
// 4. 官机 qqapp 端点尝试
|
|
1980
2006
|
const qqBot = (ctx.bots || []).find(b => b.platform === "qq" && b.config?.id);
|
|
1981
2007
|
if (qqBot?.config?.id) {
|
|
1982
2008
|
return `https://q.qlogo.cn/qqapp/${qqBot.config.id}/${channelId}/640`;
|
|
1983
2009
|
}
|
|
2010
|
+
// 5. 默认占位
|
|
1984
2011
|
return `https://p.qlogo.cn/gh/426230045/426230045/100`;
|
|
1985
2012
|
}
|
|
2013
|
+
// NapCat/OneBot 群列表缓存:群名 -> 数字群号(用于官机群按名匹配头像)
|
|
2014
|
+
const napCatGuildIdByName = new Map();
|
|
2015
|
+
let napCatMapTask = null;
|
|
2016
|
+
function refreshNapCatGuildMap() {
|
|
2017
|
+
if (napCatMapTask) return;
|
|
2018
|
+
napCatMapTask = (async () => {
|
|
2019
|
+
try {
|
|
2020
|
+
const found = [];
|
|
2021
|
+
for (const bot of ctx.bots || []) {
|
|
2022
|
+
if (bot.platform === "qq") continue;
|
|
2023
|
+
if (typeof bot.getGuildList !== "function") continue;
|
|
2024
|
+
const list = await bot.getGuildList();
|
|
2025
|
+
for (const g of list?.data || []) {
|
|
2026
|
+
if (g?.name && g?.id) {
|
|
2027
|
+
found.push([g.name, g.id]);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
if (found.length) {
|
|
2032
|
+
for (const [name, id] of found) {
|
|
2033
|
+
napCatGuildIdByName.set(name, id);
|
|
2034
|
+
}
|
|
2035
|
+
if (config.verbose) logger.info(`[mc] 已缓存 ${found.length} 个 OneBot 群(用于官机群头像匹配)`);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
catch (e) {
|
|
2039
|
+
logger.warn(`[mc] 获取 OneBot 群列表失败: ${e?.message}`);
|
|
2040
|
+
}
|
|
2041
|
+
finally {
|
|
2042
|
+
// 10 分钟后允许重新刷新
|
|
2043
|
+
setTimeout(() => { napCatMapTask = null; }, 10 * 60 * 1000);
|
|
2044
|
+
}
|
|
2045
|
+
})();
|
|
2046
|
+
}
|
|
1986
2047
|
// --- 辅助函数:图表生成 ---
|
|
1987
2048
|
/**
|
|
1988
2049
|
* 生成图表的静态 CSS 样式。
|