koishi-plugin-starfx-bot 0.26.7 → 0.27.0
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.d.ts +7 -0
- package/lib/index.js +117 -8
- package/lib/utils.d.ts +16 -0
- package/package.json +1 -1
- package/readme.md +2 -1
package/lib/index.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export declare const name = "starfx-bot";
|
|
|
3
3
|
export declare const inject: {
|
|
4
4
|
optional: string[];
|
|
5
5
|
};
|
|
6
|
+
declare module 'koishi' {
|
|
7
|
+
interface Channel {
|
|
8
|
+
pickupLength: number;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
6
11
|
export declare let baseDir: string;
|
|
7
12
|
export declare let assetsDir: string;
|
|
8
13
|
export declare const starfxLogger: Logger;
|
|
@@ -40,6 +45,8 @@ export interface Config {
|
|
|
40
45
|
forward: boolean;
|
|
41
46
|
searchExchangeRate: boolean;
|
|
42
47
|
intervalGetExchangeRate: boolean;
|
|
48
|
+
roomNumToName: boolean;
|
|
49
|
+
roomNumLength: number;
|
|
43
50
|
atNotSay: boolean;
|
|
44
51
|
atNotSayProperty: number;
|
|
45
52
|
atNotSayOther: boolean;
|
package/lib/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
// src/locales/zh-CN.yml
|
|
34
34
|
var require_zh_CN = __commonJS({
|
|
35
35
|
"src/locales/zh-CN.yml"(exports2, module2) {
|
|
36
|
-
module2.exports = { commands: { roll: { messages: { noParam: "你问啥?", invalid: "你要不看看你说的是啥", "too-many": "太、太多了啦!", noodles: "扔出了{num}个{noodles}面的骰子,点数如下:{points}", possibility: "{param}是{possibility}%", choose: "当然是{option}啦!" } }, "room-number": { messages: { roomNumber: "当前的房间号是: {room}", changeRoom: "已将当前房间号 {oldRoom} 修改为 {newRoom}", newRoom: "已添加房间号: {room}", noRoom: "当前没有保存的房间", delRoom: "已删除房间: {room}", invalid: "无效输入" } }, forward: { messages: { delete: "已删除转发群聊: {gid}", noTarget: "未配置转发群组", success: "已转发消息到: {target}", noMessage: "请引用要转发的消息", setOK: "已配置转发: {target}", forwardContent: "[转发消息]<br/> {content}" } }, "waiting-play": { messages: { addReady: "已添加,当前待机{num}人: <br/>{list}", delReady: "已删除,当前待机{num}人: <br/>{list}", delFailed: "未删除,当前待机{num}人: <br/>{list}", clearReady: "待机列表已清空", listReady: "当前待机{num}人: <br/>{list}", invalid: "输入无效" } } }, middleware: { messages: { atNotReply: "艾特我又不说话", atNotReplyOther: "艾特他又不说话", notBot: "我才不是机器人!", loveMessage: "我喜欢你", iLoveU: "我也喜欢你" } } };
|
|
36
|
+
module2.exports = { commands: { roll: { messages: { noParam: "你问啥?", invalid: "你要不看看你说的是啥", "too-many": "太、太多了啦!", noodles: "扔出了{num}个{noodles}面的骰子,点数如下:{points}", possibility: "{param}是{possibility}%", choose: "当然是{option}啦!" } }, "room-number": { messages: { roomNumber: "当前的房间号是: {room}", changeRoom: "已将当前房间号 {oldRoom} 修改为 {newRoom}", newRoom: "已添加房间号: {room}", noRoom: "当前没有保存的房间", delRoom: "已删除房间: {room}", invalid: "无效输入" } }, forward: { messages: { delete: "已删除转发群聊: {gid}", noTarget: "未配置转发群组", success: "已转发消息到: {target}", noMessage: "请引用要转发的消息", setOK: "已配置转发: {target}", forwardContent: "[转发消息]<br/> {content}" } }, "waiting-play": { messages: { addReady: "已添加,当前待机{num}人: <br/>{list}", delReady: "已删除,当前待机{num}人: <br/>{list}", delFailed: "未删除,当前待机{num}人: <br/>{list}", clearReady: "待机列表已清空", listReady: "当前待机{num}人: <br/>{list}", invalid: "输入无效" } }, 打开拾取: { messages: { success: "已开启拾取\n当前拾取位数: {length}", noPermission: "你没有权限打开拾取", noGuild: "请在群聊中使用该指令", invalidLength: "位数设定不合理,请输入 1-20 之间的数字" } }, 关闭拾取: { messages: { success: "已关闭拾取", noPermission: "你没有权限关闭拾取", noGuild: "请在群聊中使用该指令" } }, 拾取状态: { messages: { enabled: "拾取状态: 已打开\n当前拾取位数: {length}", disabled: "拾取状态: 已关闭", noPermission: "你没有权限查看拾取状态", noGuild: "请在群聊中使用该指令" } } }, middleware: { messages: { atNotReply: "艾特我又不说话", atNotReplyOther: "艾特他又不说话", notBot: "我才不是机器人!", loveMessage: "我喜欢你", iLoveU: "我也喜欢你", notManager: "当前bot没有管理员权限,无法修改群名", editFuncNotFound: "无法找到设置群名的底层方法", editGroupNameSuccess: "检测到车牌 {content},群名修改成功!", editGroupNameRetrySuccess: '检测到车牌 {content},由于限制已修改为 "{spacedContent}"' } } };
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
|
|
@@ -63,7 +63,7 @@ var package_default = {
|
|
|
63
63
|
contributors: [
|
|
64
64
|
"StarFreedomX <starfreedomx@outlook.com>"
|
|
65
65
|
],
|
|
66
|
-
version: "0.
|
|
66
|
+
version: "0.27.0",
|
|
67
67
|
main: "lib/index.js",
|
|
68
68
|
typings: "lib/index.d.ts",
|
|
69
69
|
files: [
|
|
@@ -99,7 +99,7 @@ var package_default = {
|
|
|
99
99
|
koishi: "^4.18.7"
|
|
100
100
|
},
|
|
101
101
|
dependencies: {
|
|
102
|
-
axios: "^1.
|
|
102
|
+
axios: "^1.15.0",
|
|
103
103
|
"chart.js": "^4.5.1",
|
|
104
104
|
"chartjs-adapter-dayjs-3": "^1.2.3",
|
|
105
105
|
cheerio: "^1.0.0",
|
|
@@ -630,7 +630,7 @@ async function getImageSrc(session, param, option) {
|
|
|
630
630
|
__name(getImageSrc, "getImageSrc");
|
|
631
631
|
async function getImageFromUrl(ctx, url) {
|
|
632
632
|
if (!url) throw new Error("URL must be provided");
|
|
633
|
-
const sharp = ctx
|
|
633
|
+
const sharp = getSharpConstructor(ctx);
|
|
634
634
|
try {
|
|
635
635
|
let input;
|
|
636
636
|
if (/^https?:\/\//i.test(url)) {
|
|
@@ -856,6 +856,40 @@ function ready(session, cfg, param, readyMap) {
|
|
|
856
856
|
return returnMessage;
|
|
857
857
|
}
|
|
858
858
|
__name(ready, "ready");
|
|
859
|
+
function getSharpConstructor(ctx) {
|
|
860
|
+
const raw = ctx.QhzySharp?.Sharp;
|
|
861
|
+
if (!raw) throw new Error("Sharp Service 尚未就绪");
|
|
862
|
+
const sharpConstructor = typeof raw === "function" ? raw : raw.default;
|
|
863
|
+
if (typeof sharpConstructor !== "function") {
|
|
864
|
+
throw new Error("无法获取 Sharp 构造函数,请尝试重启 Koishi 或检查 w-node 状态");
|
|
865
|
+
}
|
|
866
|
+
return sharpConstructor;
|
|
867
|
+
}
|
|
868
|
+
__name(getSharpConstructor, "getSharpConstructor");
|
|
869
|
+
async function getAuthority(session) {
|
|
870
|
+
const user = await session.observeUser(["authority"]);
|
|
871
|
+
const authority = user?.authority || 0;
|
|
872
|
+
const roles = (session.event.member?.roles || []).map(
|
|
873
|
+
(r) => typeof r === "string" ? r : r.id
|
|
874
|
+
);
|
|
875
|
+
return { authority, roles };
|
|
876
|
+
}
|
|
877
|
+
__name(getAuthority, "getAuthority");
|
|
878
|
+
async function canBotManage(session) {
|
|
879
|
+
try {
|
|
880
|
+
const selfMember = await session.bot.getGuildMember(session.guildId, session.selfId);
|
|
881
|
+
const roles = (selfMember.roles || []).map((r) => typeof r === "string" ? r : r.id);
|
|
882
|
+
return roles.includes("admin") || roles.includes("owner");
|
|
883
|
+
} catch (e) {
|
|
884
|
+
return false;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
__name(canBotManage, "canBotManage");
|
|
888
|
+
async function canGrant(session) {
|
|
889
|
+
const { authority, roles } = await getAuthority(session);
|
|
890
|
+
return authority > 1 || roles.includes("admin") || roles.includes("owner");
|
|
891
|
+
}
|
|
892
|
+
__name(canGrant, "canGrant");
|
|
859
893
|
|
|
860
894
|
// src/plugins/drawHead.ts
|
|
861
895
|
async function handleBanGDreamConfig(options) {
|
|
@@ -997,7 +1031,7 @@ async function drawLock(ctx, baseImage) {
|
|
|
997
1031
|
console.error(error.message);
|
|
998
1032
|
}
|
|
999
1033
|
}
|
|
1000
|
-
const sharp = ctx
|
|
1034
|
+
const sharp = getSharpConstructor(ctx);
|
|
1001
1035
|
const imageMetadata = await image.metadata();
|
|
1002
1036
|
const lockUrl = `${baseDir}/data/starfx-bot/assets/lock.png`;
|
|
1003
1037
|
const size1 = Math.min(imageMetadata.width, imageMetadata.height);
|
|
@@ -1021,7 +1055,7 @@ async function drawSold(ctx, baseImage) {
|
|
|
1021
1055
|
console.error(error.message);
|
|
1022
1056
|
}
|
|
1023
1057
|
}
|
|
1024
|
-
const sharp = ctx
|
|
1058
|
+
const sharp = getSharpConstructor(ctx);
|
|
1025
1059
|
const imageMetadata = await image.metadata();
|
|
1026
1060
|
const size1 = Math.min(imageMetadata.width, imageMetadata.height);
|
|
1027
1061
|
image.resize({ width: size1, height: size1, fit: "cover" });
|
|
@@ -1082,7 +1116,7 @@ async function drawBanGDream(ctx, avatar, inputOptions) {
|
|
|
1082
1116
|
import_node_path3.default.join(assetsDir, "bangborder", `${options.border}.png`)
|
|
1083
1117
|
)
|
|
1084
1118
|
]);
|
|
1085
|
-
const sharp = ctx
|
|
1119
|
+
const sharp = getSharpConstructor(ctx);
|
|
1086
1120
|
let image = avatarSharp.resize(500 * zoom, 500 * zoom, { fit: "cover" });
|
|
1087
1121
|
const borderImage = await sharp(borderBuffer).resize(500 * zoom, 500 * zoom, { fit: "cover" }).toBuffer();
|
|
1088
1122
|
const colorImage = await sharp(colorBuffer).resize(130 * zoom, 130 * zoom, { fit: "cover" }).toBuffer();
|
|
@@ -1265,7 +1299,9 @@ var Config = import_koishi5.Schema.intersect([
|
|
|
1265
1299
|
),
|
|
1266
1300
|
forward: import_koishi5.Schema.boolean().default(true).description("消息转发功能"),
|
|
1267
1301
|
searchExchangeRate: import_koishi5.Schema.boolean().default(false).description("查汇率功能"),
|
|
1268
|
-
intervalGetExchangeRate: import_koishi5.Schema.boolean().default(false).description("汇率定时推送功能").hidden()
|
|
1302
|
+
intervalGetExchangeRate: import_koishi5.Schema.boolean().default(false).description("汇率定时推送功能").hidden(),
|
|
1303
|
+
roomNumToName: import_koishi5.Schema.boolean().default(false).description("监听车牌修改群名功能"),
|
|
1304
|
+
roomNumLength: import_koishi5.Schema.number().default(5).description("默认车牌位数")
|
|
1269
1305
|
}).description("指令小功能"),
|
|
1270
1306
|
import_koishi5.Schema.object({
|
|
1271
1307
|
atNotSay: import_koishi5.Schema.boolean().default(true).description("开启‘艾特我又不说话’功能"),
|
|
@@ -1318,6 +1354,10 @@ var Config = import_koishi5.Schema.intersect([
|
|
|
1318
1354
|
}).description("高级配置")
|
|
1319
1355
|
]);
|
|
1320
1356
|
function apply(ctx, cfg) {
|
|
1357
|
+
ctx.model.extend("channel", {
|
|
1358
|
+
pickupLength: "unsigned"
|
|
1359
|
+
// 无符号整数
|
|
1360
|
+
});
|
|
1321
1361
|
ctx.i18n.define("zh-CN", require_zh_CN());
|
|
1322
1362
|
baseDir = ctx.baseDir;
|
|
1323
1363
|
assetsDir = `${ctx.baseDir}/data/starfx-bot/assets`;
|
|
@@ -1643,8 +1683,77 @@ function apply(ctx, cfg) {
|
|
|
1643
1683
|
}
|
|
1644
1684
|
});
|
|
1645
1685
|
}
|
|
1686
|
+
if (cfg.roomNumToName) {
|
|
1687
|
+
ctx.command("打开拾取 [length:number]").alias("开启拾取", "设置拾取", "开启车牌检测").channelFields(["pickupLength"]).action(async ({ session }, length) => {
|
|
1688
|
+
if (!detectControl(featureControl, session.guildId, "pickup")) return;
|
|
1689
|
+
if (!session.guildId) return session.text(".noGuild");
|
|
1690
|
+
if (!await canGrant(session)) return session.text(".noPermission");
|
|
1691
|
+
const finalLength = length || cfg.roomNumLength || 5;
|
|
1692
|
+
if (finalLength < 1 || finalLength > 20) return session.text(".invalidLength");
|
|
1693
|
+
session.channel.pickupLength = finalLength;
|
|
1694
|
+
return session.text(".success", { length: finalLength });
|
|
1695
|
+
});
|
|
1696
|
+
ctx.command("关闭拾取").channelFields(["pickupLength"]).action(async ({ session }) => {
|
|
1697
|
+
if (!detectControl(featureControl, session.guildId, "pickup")) return;
|
|
1698
|
+
if (!session.guildId) return session.text(".noGuild");
|
|
1699
|
+
if (!await canGrant(session)) return session.text(".noPermission");
|
|
1700
|
+
if (!await canBotManage(session)) return session.text("middleware.messages.notManager");
|
|
1701
|
+
session.channel.pickupLength = 0;
|
|
1702
|
+
return session.text(".success");
|
|
1703
|
+
});
|
|
1704
|
+
ctx.command("拾取状态").channelFields(["pickupLength"]).action(async ({ session }) => {
|
|
1705
|
+
if (!detectControl(featureControl, session.guildId, "pickup")) return;
|
|
1706
|
+
if (!session.guildId) return session.text(".noGuild");
|
|
1707
|
+
if (!await canGrant(session)) return session.text(".noPermission");
|
|
1708
|
+
if (!await canBotManage(session)) return session.text("middleware.messages.notManager");
|
|
1709
|
+
return session.channel.pickupLength > 0 ? session.text(".enabled", { length: session.channel.pickupLength }) : session.text(".disabled");
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1646
1712
|
ctx.middleware(async (session, next) => {
|
|
1647
1713
|
const elements = session.elements;
|
|
1714
|
+
if (cfg.roomNumToName && session.guildId && detectControl(featureControl, session.guildId, "pickup")) {
|
|
1715
|
+
const channel = await session.observeChannel(["pickupLength"]);
|
|
1716
|
+
const targetLength = channel.pickupLength;
|
|
1717
|
+
const content = session.content?.trim();
|
|
1718
|
+
if (targetLength > 0 && new RegExp(`^\\d{${targetLength}}$`).test(content)) {
|
|
1719
|
+
if (!await canBotManage(session)) return session.text("middleware.messages.notManager");
|
|
1720
|
+
const setGroupName = /* @__PURE__ */ __name(async (name2) => {
|
|
1721
|
+
const internal = session.bot.internal;
|
|
1722
|
+
if (typeof internal?._request === "function" && session.platform === "onebot") {
|
|
1723
|
+
const response = await internal._request("set_group_name", {
|
|
1724
|
+
group_id: session.guildId,
|
|
1725
|
+
group_name: name2
|
|
1726
|
+
});
|
|
1727
|
+
if (response && response.retcode !== 0 && response.status !== "ok") {
|
|
1728
|
+
throw new Error(`OneBot 报错 (Code: ${response.retcode}): ${JSON.stringify(response)}`);
|
|
1729
|
+
}
|
|
1730
|
+
return response;
|
|
1731
|
+
}
|
|
1732
|
+
if (internal.set_group_name) {
|
|
1733
|
+
return await internal.set_group_name(session.guildId, name2);
|
|
1734
|
+
}
|
|
1735
|
+
if (session.bot.updateChannel) {
|
|
1736
|
+
return await session.bot.updateChannel(session.guildId, { name: name2 });
|
|
1737
|
+
}
|
|
1738
|
+
throw new Error(session.text("middleware.messages.editFuncNotFound"));
|
|
1739
|
+
}, "setGroupName");
|
|
1740
|
+
try {
|
|
1741
|
+
await setGroupName(content);
|
|
1742
|
+
await session.send(session.text("middleware.messages.editGroupNameSuccess", { content }));
|
|
1743
|
+
return;
|
|
1744
|
+
} catch (e) {
|
|
1745
|
+
starfxLogger.warn(`纯数字修改失败,尝试添加空格重试: ${content}`);
|
|
1746
|
+
try {
|
|
1747
|
+
const spacedContent = content.replace(/(\d{3})(?=\d)/g, "$1 ");
|
|
1748
|
+
await setGroupName(spacedContent);
|
|
1749
|
+
await session.send(session.text("middleware.messages.editGroupNameRetrySuccess", { content, spacedContent }));
|
|
1750
|
+
return;
|
|
1751
|
+
} catch (retryError) {
|
|
1752
|
+
starfxLogger.error(`尝试添加空格修改群名依然失败: ${retryError}`);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1648
1757
|
if (cfg.openRepeat && detectControl(featureControl, session.guildId, "repeat")) {
|
|
1649
1758
|
const content = session.content;
|
|
1650
1759
|
const ctxArr = repeatContextMap.get(session.gid);
|
package/lib/utils.d.ts
CHANGED
|
@@ -108,4 +108,20 @@ export declare function safeQuote(str: string, useQuote: boolean): string;
|
|
|
108
108
|
export declare function writeMap<K, V>(map: Map<K, V>, dest: string): void;
|
|
109
109
|
export declare function readMap<K, V>(url: string): Map<K, V>;
|
|
110
110
|
export declare function ready(session: Session, cfg: Config, param: string, readyMap: Map<string, string[]>): string;
|
|
111
|
+
/**
|
|
112
|
+
* 安全地从上下文中获取 Sharp 构造函数
|
|
113
|
+
*/
|
|
114
|
+
export declare function getSharpConstructor(ctx: Context): any;
|
|
115
|
+
/**
|
|
116
|
+
* 检查用户权限
|
|
117
|
+
*/
|
|
118
|
+
export declare function getAuthority(session: Session): Promise<{
|
|
119
|
+
authority: number;
|
|
120
|
+
roles: string[];
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* 专门检查机器人是否有权执行群管理操作
|
|
124
|
+
*/
|
|
125
|
+
export declare function canBotManage(session: Session): Promise<boolean>;
|
|
126
|
+
export declare function canGrant(session: Session): Promise<boolean>;
|
|
111
127
|
export {};
|
package/package.json
CHANGED
package/readme.md
CHANGED