koishi-plugin-starfx-bot 0.5.1 → 0.6.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 +14 -2
- package/lib/index.js +109 -22
- package/package.json +1 -1
- package/readme.md +15 -14
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Context, h, Schema, Session } from 'koishi';
|
|
1
|
+
import { Context, h, Logger, Schema, Session } from 'koishi';
|
|
2
2
|
export declare const name = "starfx-bot";
|
|
3
3
|
export declare let baseDir: string;
|
|
4
4
|
export declare let assetsDir: string;
|
|
5
|
+
export declare const starfxLogger: Logger;
|
|
5
6
|
export interface Config {
|
|
6
7
|
openLock: boolean;
|
|
7
8
|
openSold: boolean;
|
|
@@ -10,6 +11,7 @@ export interface Config {
|
|
|
10
11
|
atNotSayOther: boolean;
|
|
11
12
|
atNotSayProperty: number;
|
|
12
13
|
atNotSayOtherProperty: number;
|
|
14
|
+
record: boolean;
|
|
13
15
|
replyBot: string;
|
|
14
16
|
iLoveYou: boolean;
|
|
15
17
|
}
|
|
@@ -17,6 +19,7 @@ export declare const Config: Schema<Schemastery.ObjectS<{
|
|
|
17
19
|
openLock: Schema<boolean, boolean>;
|
|
18
20
|
openSold: Schema<boolean, boolean>;
|
|
19
21
|
bangdreamBorder: Schema<boolean, boolean>;
|
|
22
|
+
record: Schema<boolean, boolean>;
|
|
20
23
|
atNotSay: Schema<boolean, boolean>;
|
|
21
24
|
atNotSayProperty: Schema<number, number>;
|
|
22
25
|
atNotSayOther: Schema<boolean, boolean>;
|
|
@@ -27,6 +30,7 @@ export declare const Config: Schema<Schemastery.ObjectS<{
|
|
|
27
30
|
openLock: boolean;
|
|
28
31
|
openSold: boolean;
|
|
29
32
|
bangdreamBorder: boolean;
|
|
33
|
+
record: boolean;
|
|
30
34
|
atNotSay: boolean;
|
|
31
35
|
atNotSayProperty: number;
|
|
32
36
|
atNotSayOther: boolean;
|
|
@@ -36,7 +40,15 @@ export declare const Config: Schema<Schemastery.ObjectS<{
|
|
|
36
40
|
} & import("cosmokit").Dict>;
|
|
37
41
|
export declare const usage = "<h5>StarFreedomX\u7684\u81EA\u7528\u63D2\u4EF6 \u653E\u4E86\u4E00\u4E9B\u5C0F\u529F\u80FD</h5>\n ";
|
|
38
42
|
export declare function apply(ctx: Context, cfg: Config): void;
|
|
39
|
-
export declare function
|
|
43
|
+
export declare function addRecord(ctx: Context, gid: string, avatarUrl: string): Promise<string>;
|
|
44
|
+
export declare function getRecord(gid: string): Promise<string>;
|
|
45
|
+
export declare function getImageSrc(session: Session, param: string, option?: {
|
|
46
|
+
number?: boolean;
|
|
47
|
+
img?: boolean;
|
|
48
|
+
at?: boolean;
|
|
49
|
+
noParam?: boolean;
|
|
50
|
+
quote?: boolean;
|
|
51
|
+
}): Promise<string>;
|
|
40
52
|
export declare function handleBanGDreamConfig(ctx: Context, options: any): Promise<{
|
|
41
53
|
color: string;
|
|
42
54
|
band: string;
|
package/lib/index.js
CHANGED
|
@@ -41,14 +41,17 @@ var require_zh_CN = __commonJS({
|
|
|
41
41
|
var src_exports = {};
|
|
42
42
|
__export(src_exports, {
|
|
43
43
|
Config: () => Config,
|
|
44
|
+
addRecord: () => addRecord,
|
|
44
45
|
apply: () => apply,
|
|
45
46
|
assetsDir: () => assetsDir,
|
|
46
47
|
baseDir: () => baseDir,
|
|
47
48
|
drawLock: () => drawLock,
|
|
48
49
|
drawSold: () => drawSold,
|
|
49
50
|
getImageSrc: () => getImageSrc,
|
|
51
|
+
getRecord: () => getRecord,
|
|
50
52
|
handleBanGDreamConfig: () => handleBanGDreamConfig,
|
|
51
53
|
name: () => name,
|
|
54
|
+
starfxLogger: () => starfxLogger,
|
|
52
55
|
usage: () => usage
|
|
53
56
|
});
|
|
54
57
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -56,14 +59,17 @@ var import_koishi = require("koishi");
|
|
|
56
59
|
var import_sharp = __toESM(require("sharp"));
|
|
57
60
|
var fs = __toESM(require("fs"));
|
|
58
61
|
var import_jimp = require("jimp");
|
|
62
|
+
var import_node_path = __toESM(require("node:path"));
|
|
59
63
|
var name = "starfx-bot";
|
|
60
64
|
var baseDir;
|
|
61
65
|
var assetsDir;
|
|
66
|
+
var starfxLogger = new import_koishi.Logger("starfx-bot");
|
|
62
67
|
var Config = import_koishi.Schema.intersect([
|
|
63
68
|
import_koishi.Schema.object({
|
|
64
69
|
openLock: import_koishi.Schema.boolean().default(true).description("开启明日方舟封印功能"),
|
|
65
70
|
openSold: import_koishi.Schema.boolean().default(true).description('开启闲鱼"卖掉了"功能'),
|
|
66
71
|
bangdreamBorder: import_koishi.Schema.boolean().default(true).description("开启BanG Dream!边框功能"),
|
|
72
|
+
record: import_koishi.Schema.boolean().default(true).description("开启群语录功能"),
|
|
67
73
|
atNotSay: import_koishi.Schema.boolean().default(true).description("开启‘艾特我又不说话’功能"),
|
|
68
74
|
atNotSayProperty: import_koishi.Schema.number().role("slider").min(0).max(1).step(0.01).default(0.5).description("'艾特我又不说话'回复概率"),
|
|
69
75
|
atNotSayOther: import_koishi.Schema.boolean().default(true).description("开启‘艾特他又不说话’功能"),
|
|
@@ -98,11 +104,36 @@ function apply(ctx, cfg) {
|
|
|
98
104
|
return import_koishi.h.image(imageBase64);
|
|
99
105
|
});
|
|
100
106
|
}
|
|
107
|
+
if (cfg.record) {
|
|
108
|
+
ctx.command("投稿 [param]").action(async ({ session }, param) => {
|
|
109
|
+
const imageSrc = await getImageSrc(
|
|
110
|
+
session,
|
|
111
|
+
param,
|
|
112
|
+
{
|
|
113
|
+
img: true,
|
|
114
|
+
at: false,
|
|
115
|
+
quote: true,
|
|
116
|
+
noParam: false,
|
|
117
|
+
number: false
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
if (!imageSrc) {
|
|
121
|
+
return "请发送带图片的指令消息或引用图片消息进行投稿";
|
|
122
|
+
}
|
|
123
|
+
return await addRecord(ctx, session.gid.replace(":", "_"), imageSrc);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
101
126
|
ctx.middleware(async (session, next) => {
|
|
102
127
|
const elements = session.elements;
|
|
103
128
|
await atNotSayReply(cfg, session, elements);
|
|
104
129
|
await replyBot(cfg, session, elements);
|
|
105
130
|
await iLoveYou(cfg, session, elements);
|
|
131
|
+
if (cfg.record && session.content?.startsWith("语录")) {
|
|
132
|
+
const filepath = await getRecord(session.gid.replace(":", "_"));
|
|
133
|
+
starfxLogger.info(`send record: ${filepath}`);
|
|
134
|
+
if (!filepath) return "暂无语录呢";
|
|
135
|
+
return import_koishi.h.image(filepath);
|
|
136
|
+
}
|
|
106
137
|
return next();
|
|
107
138
|
});
|
|
108
139
|
function initAssets() {
|
|
@@ -121,27 +152,80 @@ function apply(ctx, cfg) {
|
|
|
121
152
|
__name(initAssets, "initAssets");
|
|
122
153
|
}
|
|
123
154
|
__name(apply, "apply");
|
|
124
|
-
async function
|
|
125
|
-
|
|
155
|
+
async function addRecord(ctx, gid, avatarUrl) {
|
|
156
|
+
const recordDir = `${assetsDir}/record/${gid}`;
|
|
157
|
+
const avatarBuffer = await ctx.http.get(avatarUrl, { responseType: "arraybuffer" });
|
|
158
|
+
saveImage(avatarBuffer, recordDir);
|
|
159
|
+
return "添加成功!";
|
|
160
|
+
}
|
|
161
|
+
__name(addRecord, "addRecord");
|
|
162
|
+
async function getRecord(gid) {
|
|
163
|
+
const recordDir = `${assetsDir}/record/${gid}`;
|
|
164
|
+
const files = fs.readdirSync(recordDir);
|
|
165
|
+
return files?.length ? import_node_path.default.join(recordDir, import_koishi.Random.pick(files)) : null;
|
|
166
|
+
}
|
|
167
|
+
__name(getRecord, "getRecord");
|
|
168
|
+
function getTodayPrefix() {
|
|
169
|
+
const now = /* @__PURE__ */ new Date();
|
|
170
|
+
const yyyy = now.getFullYear();
|
|
171
|
+
const mm = String(now.getMonth() + 1).padStart(2, "0");
|
|
172
|
+
const dd = String(now.getDate()).padStart(2, "0");
|
|
173
|
+
return `${yyyy}${mm}${dd}`;
|
|
174
|
+
}
|
|
175
|
+
__name(getTodayPrefix, "getTodayPrefix");
|
|
176
|
+
function getNextSequenceNumber(directory, prefix) {
|
|
177
|
+
const files = fs.existsSync(directory) ? fs.readdirSync(directory) : [];
|
|
178
|
+
const regex = new RegExp(`^${prefix}-(\\d+)\\.jpg$`);
|
|
179
|
+
let maxNum = 0;
|
|
180
|
+
files.forEach((file) => {
|
|
181
|
+
const match = file.match(regex);
|
|
182
|
+
if (match) {
|
|
183
|
+
const num = parseInt(match[1], 10);
|
|
184
|
+
if (num > maxNum) {
|
|
185
|
+
maxNum = num;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return maxNum + 1;
|
|
190
|
+
}
|
|
191
|
+
__name(getNextSequenceNumber, "getNextSequenceNumber");
|
|
192
|
+
function saveImage(arrayBuffer, directory) {
|
|
193
|
+
const prefix = getTodayPrefix();
|
|
194
|
+
const seq = getNextSequenceNumber(directory, prefix);
|
|
195
|
+
const filename = `${prefix}-${seq}.jpg`;
|
|
196
|
+
const filepath = import_node_path.default.join(directory, filename);
|
|
197
|
+
if (!fs.existsSync(directory)) {
|
|
198
|
+
fs.mkdirSync(directory, { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
201
|
+
fs.writeFileSync(filepath, buffer);
|
|
202
|
+
console.log(`已保存图片:${filepath}`);
|
|
203
|
+
}
|
|
204
|
+
__name(saveImage, "saveImage");
|
|
205
|
+
async function getImageSrc(session, param, option) {
|
|
206
|
+
const number = option?.number ?? true, img = option?.img ?? true, at = option?.at ?? true, noParam = option?.noParam ?? true, quote = option?.quote ?? true;
|
|
207
|
+
if (number && param?.length && param?.length === String(Number(param))?.length) {
|
|
126
208
|
return `https://q1.qlogo.cn/g?b=qq&nk=${param}&s=640`;
|
|
127
|
-
} else if (!param?.length) {
|
|
209
|
+
} else if (noParam && !param?.length) {
|
|
128
210
|
return `https://q1.qlogo.cn/g?b=qq&nk=${session.userId}&s=640`;
|
|
129
211
|
}
|
|
130
212
|
const elementArray = session.elements;
|
|
131
213
|
for (const element of elementArray) {
|
|
132
|
-
if (element?.type === "img") {
|
|
214
|
+
if (img && element?.type === "img") {
|
|
133
215
|
return element?.attrs?.src;
|
|
134
|
-
} else if (element?.type === "at" && element?.attrs?.id) {
|
|
216
|
+
} else if (at && element?.type === "at" && element?.attrs?.id) {
|
|
135
217
|
return `https://q1.qlogo.cn/g?b=qq&nk=${element.attrs.id}&s=640`;
|
|
136
218
|
}
|
|
137
219
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
220
|
+
if (quote) {
|
|
221
|
+
const quoteElementArray = session?.quote?.elements;
|
|
222
|
+
if (quoteElementArray?.length) {
|
|
223
|
+
for (const element of quoteElementArray) {
|
|
224
|
+
if (img && element?.type === "img") {
|
|
225
|
+
return element?.attrs?.src;
|
|
226
|
+
} else if (at && element?.type === "at" && element?.attrs?.id && element.attrs.id !== session.selfId) {
|
|
227
|
+
return `https://q1.qlogo.cn/g?b=qq&nk=${element?.attrs?.id}&s=640`;
|
|
228
|
+
}
|
|
145
229
|
}
|
|
146
230
|
}
|
|
147
231
|
}
|
|
@@ -156,14 +240,14 @@ async function handleBanGDreamConfig(ctx, options) {
|
|
|
156
240
|
happy: ["happy", "orange", "橙", "橙色"]
|
|
157
241
|
};
|
|
158
242
|
const bands = {
|
|
159
|
-
ppp: ["ppp", "
|
|
160
|
-
ag: ["ag", "
|
|
161
|
-
pp: ["pp", "
|
|
162
|
-
hhw: ["hhw", "ハロー、ハッピーワールド!", "
|
|
163
|
-
r: ["r", "
|
|
164
|
-
ras: ["ras", "
|
|
165
|
-
mnk: ["mnk", "モニカ", "蝶团", "蝶", "
|
|
166
|
-
go: ["go", "
|
|
243
|
+
ppp: ["ppp", "poppin'Party", "破琵琶", "步品破茶", "poppin", "popipa", "poppinparty", "ポピパ"],
|
|
244
|
+
ag: ["ag", "afterglow", "夕阳红", "悪蓋愚狼"],
|
|
245
|
+
pp: ["pp", "pastel*palettes", "pastel*palettes", "pastelPalettes", "怕死怕累", "pastel", "palettes", "pasupare", "パスパレ", "破巣照破烈斗"],
|
|
246
|
+
hhw: ["hhw", "ハロー、ハッピーワールド!", "hello,happyworld!", "hellohappyworld", "ハロハピ", "hello,happyworld!", "harohapi", "破狼法被威悪怒", "儿歌团", "好好玩"],
|
|
247
|
+
r: ["r", "roselia", "露世里恶", "萝", "露世裏悪", "ロゼリア", "r组", "相声团", "相声组"],
|
|
248
|
+
ras: ["ras", "raiseasuilen", "raise", "suilen", "ラス", "零図悪酔恋", "睡莲", "麗厨唖睡蓮", "睡蓮"],
|
|
249
|
+
mnk: ["mnk", "モニカ", "蝶团", "蝶", "morfonica", "毛二力", "monika", "monica"],
|
|
250
|
+
go: ["go", "mygo!!!!!", "mygo!!!!!", "mygo", "我去!!!!!", "我去!!!!!", "我去", "卖狗"]
|
|
167
251
|
};
|
|
168
252
|
const trains = {
|
|
169
253
|
"color_star": ["花后", "1", "彩", "true"],
|
|
@@ -194,9 +278,9 @@ async function handleBanGDreamConfig(ctx, options) {
|
|
|
194
278
|
}
|
|
195
279
|
const starNum = options.starNum ? parseInt(options.starNum) : 0;
|
|
196
280
|
drawConfig.starNum = starNum > 0 && starNum < 10 ? starNum : 0;
|
|
197
|
-
if (
|
|
281
|
+
if (options.train) {
|
|
198
282
|
for (const [train, aliases] of Object.entries(trains)) {
|
|
199
|
-
if (aliases.includes(options.
|
|
283
|
+
if (aliases.includes(options.train.toLowerCase())) {
|
|
200
284
|
drawConfig.starType = train;
|
|
201
285
|
break;
|
|
202
286
|
}
|
|
@@ -360,13 +444,16 @@ __name(drawBanGDream, "drawBanGDream");
|
|
|
360
444
|
// Annotate the CommonJS export names for ESM import in node:
|
|
361
445
|
0 && (module.exports = {
|
|
362
446
|
Config,
|
|
447
|
+
addRecord,
|
|
363
448
|
apply,
|
|
364
449
|
assetsDir,
|
|
365
450
|
baseDir,
|
|
366
451
|
drawLock,
|
|
367
452
|
drawSold,
|
|
368
453
|
getImageSrc,
|
|
454
|
+
getRecord,
|
|
369
455
|
handleBanGDreamConfig,
|
|
370
456
|
name,
|
|
457
|
+
starfxLogger,
|
|
371
458
|
usage
|
|
372
459
|
});
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -13,17 +13,18 @@ StarFreedomX机器人的小功能,自用
|
|
|
13
13
|
* 我也喜欢你!
|
|
14
14
|
|
|
15
15
|
# 更新日志
|
|
16
|
-
| 版本 | 更新日志
|
|
17
|
-
|
|
18
|
-
| `0.0.1` | 加入封印功能
|
|
19
|
-
| `0.1.0` | 加入"卖掉了"功能
|
|
20
|
-
| `0.2.0` | 加入"艾特我又不说话"回复功能
|
|
21
|
-
| `0.3.0` | 加入"我喜欢你"和"我才不是机器人!"回复功能
|
|
22
|
-
| `0.3.3` | 修订添加"我才不是机器人"是否需要at
|
|
23
|
-
| `0.3.4` | 分离"艾特我/他又不说话"的两个选项为单独的开关
|
|
24
|
-
| `0.3.5` | 修复丢失的assets
|
|
25
|
-
| `0.3.6` | 添加"艾特我/他又不说话"的概率配置
|
|
26
|
-
| `0.4.0` | 更改处理库为sharp
|
|
27
|
-
| `0.4.1` | 修复sharp处理w>h的图报错的bug
|
|
28
|
-
| `0.5.0` | 加入BanG Dream!边框功能
|
|
29
|
-
| `0.5.1` | 对边框的参数做了限定,修复了异常输入导致的报错
|
|
16
|
+
| 版本 | 更新日志 |
|
|
17
|
+
|---------|-----------------------------|
|
|
18
|
+
| `0.0.1` | 加入封印功能 |
|
|
19
|
+
| `0.1.0` | 加入"卖掉了"功能 |
|
|
20
|
+
| `0.2.0` | 加入"艾特我又不说话"回复功能 |
|
|
21
|
+
| `0.3.0` | 加入"我喜欢你"和"我才不是机器人!"回复功能 |
|
|
22
|
+
| `0.3.3` | 修订添加"我才不是机器人"是否需要at |
|
|
23
|
+
| `0.3.4` | 分离"艾特我/他又不说话"的两个选项为单独的开关 |
|
|
24
|
+
| `0.3.5` | 修复丢失的assets |
|
|
25
|
+
| `0.3.6` | 添加"艾特我/他又不说话"的概率配置 |
|
|
26
|
+
| `0.4.0` | 更改处理库为sharp |
|
|
27
|
+
| `0.4.1` | 修复sharp处理w>h的图报错的bug |
|
|
28
|
+
| `0.5.0` | 加入BanG Dream!边框功能 |
|
|
29
|
+
| `0.5.1` | 对边框的参数做了限定,修复了异常输入导致的报错 |
|
|
30
|
+
| `0.6.0` | 加入群语录功能,修复一处bangdream绘制的bug |
|