koishi-plugin-starfx-bot 0.4.2 → 0.5.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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/lib/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare let assetsDir: string;
5
5
  export interface Config {
6
6
  openLock: boolean;
7
7
  openSold: boolean;
8
+ bangdreamBorder: boolean;
8
9
  atNotSay: boolean;
9
10
  atNotSayOther: boolean;
10
11
  atNotSayProperty: number;
@@ -15,6 +16,7 @@ export interface Config {
15
16
  export declare const Config: Schema<Schemastery.ObjectS<{
16
17
  openLock: Schema<boolean, boolean>;
17
18
  openSold: Schema<boolean, boolean>;
19
+ bangdreamBorder: Schema<boolean, boolean>;
18
20
  atNotSay: Schema<boolean, boolean>;
19
21
  atNotSayProperty: Schema<number, number>;
20
22
  atNotSayOther: Schema<boolean, boolean>;
@@ -24,6 +26,7 @@ export declare const Config: Schema<Schemastery.ObjectS<{
24
26
  }>, {
25
27
  openLock: boolean;
26
28
  openSold: boolean;
29
+ bangdreamBorder: boolean;
27
30
  atNotSay: boolean;
28
31
  atNotSayProperty: number;
29
32
  atNotSayOther: boolean;
@@ -33,11 +36,18 @@ export declare const Config: Schema<Schemastery.ObjectS<{
33
36
  } & import("cosmokit").Dict>;
34
37
  export declare const usage = "<h5>StarFreedomX\u7684\u81EA\u7528\u63D2\u4EF6 \u653E\u4E86\u4E00\u4E9B\u5C0F\u529F\u80FD</h5>\n ";
35
38
  export declare function apply(ctx: Context, cfg: Config): void;
36
- export declare function getImageSrc(session: Session, param: string): Promise<any>;
37
- export declare function drawLock(ctx: Context, baseImage: string): Promise<h | "发生错误" | "输入无效">;
39
+ export declare function getImageSrc(session: Session, param: string): Promise<string>;
40
+ export declare function handleBanGDreamConfig(ctx: Context, options: any): Promise<{
41
+ color: string;
42
+ band: string;
43
+ starType: string;
44
+ starNum: number;
45
+ border: string;
46
+ }>;
47
+ export declare function drawLock(ctx: Context, baseImage: string): Promise<"发生错误" | "输入无效" | h>;
38
48
  /**
39
49
  * "卖掉了"绘图函数
40
50
  * @param ctx
41
51
  * @param baseImage
42
52
  */
43
- export declare function drawSold(ctx: Context, baseImage: string): Promise<h | "发生错误" | "输入无效">;
53
+ export declare function drawSold(ctx: Context, baseImage: string): Promise<"发生错误" | "输入无效" | h>;
package/lib/index.js CHANGED
@@ -47,6 +47,7 @@ __export(src_exports, {
47
47
  drawLock: () => drawLock,
48
48
  drawSold: () => drawSold,
49
49
  getImageSrc: () => getImageSrc,
50
+ handleBanGDreamConfig: () => handleBanGDreamConfig,
50
51
  name: () => name,
51
52
  usage: () => usage
52
53
  });
@@ -54,6 +55,7 @@ module.exports = __toCommonJS(src_exports);
54
55
  var import_koishi = require("koishi");
55
56
  var import_sharp = __toESM(require("sharp"));
56
57
  var fs = __toESM(require("fs"));
58
+ var import_jimp = require("jimp");
57
59
  var name = "starfx-bot";
58
60
  var baseDir;
59
61
  var assetsDir;
@@ -61,6 +63,7 @@ var Config = import_koishi.Schema.intersect([
61
63
  import_koishi.Schema.object({
62
64
  openLock: import_koishi.Schema.boolean().default(true).description("开启明日方舟封印功能"),
63
65
  openSold: import_koishi.Schema.boolean().default(true).description('开启闲鱼"卖掉了"功能'),
66
+ bangdreamBorder: import_koishi.Schema.boolean().default(true).description("开启BanG Dream!边框功能"),
64
67
  atNotSay: import_koishi.Schema.boolean().default(true).description("开启‘艾特我又不说话’功能"),
65
68
  atNotSayProperty: import_koishi.Schema.number().role("slider").min(0).max(1).step(0.01).default(0.5).description("'艾特我又不说话'回复概率"),
66
69
  atNotSayOther: import_koishi.Schema.boolean().default(true).description("开启‘艾特他又不说话’功能"),
@@ -75,70 +78,47 @@ function apply(ctx, cfg) {
75
78
  ctx.i18n.define("zh-CN", require_zh_CN());
76
79
  baseDir = ctx.baseDir;
77
80
  assetsDir = `${ctx.baseDir}/data/starfx-bot/assets`;
78
- initAssets("lock.png");
79
- initAssets("sold.png");
81
+ initAssets();
80
82
  if (cfg.openLock) {
81
83
  ctx.command("封印 [param]").action(async ({ session }, param) => {
82
- console.log("elements");
83
- console.log(session.elements);
84
- console.log("quote");
85
- console.log(session.quote);
86
- console.log("param");
87
- console.log(param);
88
84
  return await drawLock(ctx, await getImageSrc(session, param));
89
85
  });
90
86
  }
91
87
  if (cfg.openSold) {
92
88
  ctx.command("卖掉了 [param]").action(async ({ session }, param) => {
93
- console.log("elements");
94
- console.log(session.elements);
95
- console.log("quote");
96
- console.log(session.quote);
97
- console.log("param");
98
- console.log(param);
99
89
  return await drawSold(ctx, await getImageSrc(session, param));
100
90
  });
101
91
  }
92
+ if (cfg.bangdreamBorder) {
93
+ ctx.command("bangdreamborder [param]").alias("bdbd").option("starNum", "-n <starNum: number>").option("color", "-c <color: string>").option("train", "-t <train: string>").option("band", "-b <band: string>").action(async ({ session, options }, param) => {
94
+ session.send("图片处理中请稍等...");
95
+ console.log(param);
96
+ const drawConfig = await handleBanGDreamConfig(ctx, options);
97
+ const imageBase64 = await drawBanGDream(await getImageSrc(session, param), drawConfig);
98
+ return import_koishi.h.image(imageBase64);
99
+ });
100
+ }
102
101
  ctx.middleware(async (session, next) => {
103
102
  const elements = session.elements;
104
- console.log(elements);
105
- if (cfg.atNotSay || cfg.atNotSayOther) {
106
- if (elements.length === 1 && elements[0].type === "at") {
107
- if (elements[0].attrs.id === session.selfId) {
108
- if (cfg.atNotSay) {
109
- if (import_koishi.Random.bool(cfg.atNotSayProperty)) {
110
- await session.send(session.text("middleware.messages.atNotReply"));
111
- }
112
- }
113
- } else {
114
- if (cfg.atNotSayOther) {
115
- if (import_koishi.Random.bool(cfg.atNotSayOtherProperty)) {
116
- await session.send(session.text("middleware.messages.atNotReplyOther"));
117
- }
118
- }
119
- }
120
- }
121
- }
122
- if (cfg.replyBot !== "关闭") {
123
- const bots = ["bot", "机器人", "Bot", "BOT", "机器人!", "机器人!", "人机"];
124
- const texts = elements?.filter((e) => e.type === "text").map((e) => e?.attrs?.content?.trim());
125
- const ats = elements?.filter((e) => e.type === "at").map((e) => e?.attrs?.id);
126
- const mentionedBot = texts?.some((t) => bots.includes(t));
127
- const atMe = ats?.includes(session.selfId);
128
- if (elements?.length === 1 && mentionedBot && cfg.replyBot === "无需at" || elements?.length === 2 && mentionedBot && atMe) {
129
- await session.send(session.text("middleware.messages.notBot"));
130
- }
131
- }
132
- if (cfg.iLoveYou) {
133
- if (elements?.length === 2 && elements.some((e) => e.type === "at" && e?.attrs?.id === session.selfId) && elements.some((e) => e.type === "text" && e?.attrs?.content?.trim() === session.text("middleware.messages.loveMessage"))) {
134
- await session.send(session.text("middleware.messages.iLoveU", {
135
- at: import_koishi.h.at(session.userId),
136
- quote: import_koishi.h.quote(session.messageId)
137
- }));
138
- }
139
- }
103
+ await atNotSayReply(cfg, session, elements);
104
+ await replyBot(cfg, session, elements);
105
+ await iLoveYou(cfg, session, elements);
140
106
  return next();
141
107
  });
108
+ function initAssets() {
109
+ const fromUrl = `${__dirname}/../assets`;
110
+ assetsDir = `${ctx.baseDir}/data/starfx-bot/assets`;
111
+ if (!fs.existsSync(fromUrl)) return;
112
+ if (!fs.readdirSync(fromUrl)?.length) return;
113
+ if (!fs.existsSync(assetsDir)) {
114
+ fs.mkdirSync(assetsDir, { recursive: true });
115
+ }
116
+ fs.cpSync(fromUrl, assetsDir, { recursive: true, force: true });
117
+ if (process.env.NODE_ENV !== "development") {
118
+ fs.rmSync(fromUrl, { recursive: true });
119
+ }
120
+ }
121
+ __name(initAssets, "initAssets");
142
122
  }
143
123
  __name(apply, "apply");
144
124
  async function getImageSrc(session, param) {
@@ -168,14 +148,62 @@ async function getImageSrc(session, param) {
168
148
  return "";
169
149
  }
170
150
  __name(getImageSrc, "getImageSrc");
171
- function initAssets(fileName) {
172
- if (fs.existsSync(`${__dirname}/../assets/${fileName}`)) {
173
- fs.mkdirSync(`${assetsDir}/`, { recursive: true });
174
- fs.copyFileSync(`${__dirname}/../assets/${fileName}`, `${assetsDir}/${fileName}`);
175
- fs.rmSync(`${__dirname}/../assets/${fileName}`);
151
+ async function handleBanGDreamConfig(ctx, options) {
152
+ const types = {
153
+ cool: ["cool", "blue", "蓝", "蓝色"],
154
+ powerful: ["powerful", "red", "红", "红色"],
155
+ peer: ["peer", "green", "绿", "绿色"],
156
+ happy: ["happy", "orange", "橙", "橙色"]
157
+ };
158
+ const bands = {
159
+ ppp: ["ppp", "Poppin'Party", "破琵琶", "步品破茶", "poppin", "popipa", "poppinparty", "ポピパ"],
160
+ ag: ["ag", "Afterglow", "夕阳红", "悪蓋愚狼"],
161
+ pp: ["pp", "Pastel*Palettes", "Pastel*Palettes", "PastelPalettes", "怕死怕累", "pastel", "palettes", "pasupare", "パスパレ", "破巣照破烈斗"],
162
+ hhw: ["hhw", "ハロー、ハッピーワールド!", "Hello,HappyWorld!", "helloHappyWorld", "ハロハピ", "Hello,HappyWorld!", "harohapi", "破狼法被威悪怒", "儿歌团", "好好玩"],
163
+ r: ["r", "Roselia", "露世里恶", "萝", "露世裏悪", "ロゼリア", "r组", "相声团", "相声组"],
164
+ ras: ["ras", "RaiseASuilen", "raise", "suilen", "ラス", "零図悪酔恋", "睡莲", "麗厨唖睡蓮", "睡蓮"],
165
+ mnk: ["mnk", "モニカ", "蝶团", "蝶", "Morfonica", "毛二力", "monika", "monica"],
166
+ go: ["go", "MyGO!!!!!", "MyGO!!!!!", "mygo", "我去!!!!!", "我去!!!!!", "我去", "卖狗"]
167
+ };
168
+ const trains = {
169
+ "color_star": ["花后", "1", "彩", "true"],
170
+ "normal_star": ["花前", "0", "false"]
171
+ };
172
+ const drawConfig = {
173
+ color: "",
174
+ band: "",
175
+ starType: "",
176
+ starNum: 0,
177
+ border: ""
178
+ };
179
+ if (options.color) {
180
+ for (const [type, aliases] of Object.entries(types)) {
181
+ if (aliases.includes(options.color.toLowerCase())) {
182
+ drawConfig.color = type;
183
+ break;
184
+ }
185
+ }
176
186
  }
187
+ if (options.band) {
188
+ for (const [band, aliases] of Object.entries(bands)) {
189
+ if (aliases.includes(options.band.toLowerCase())) {
190
+ drawConfig.band = band;
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ drawConfig.starNum = options.starNum ? parseInt(options.starNum) : 0;
196
+ if (drawConfig.starType) {
197
+ for (const [train, aliases] of Object.entries(trains)) {
198
+ if (aliases.includes(options.color.toLowerCase())) {
199
+ drawConfig.starType = train;
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ return drawConfig;
177
205
  }
178
- __name(initAssets, "initAssets");
206
+ __name(handleBanGDreamConfig, "handleBanGDreamConfig");
179
207
  async function drawLock(ctx, baseImage) {
180
208
  const image = await getImageFromUrl(ctx, baseImage);
181
209
  if (image === -1) {
@@ -245,6 +273,88 @@ async function getImageFromUrl(ctx, url) {
245
273
  return image;
246
274
  }
247
275
  __name(getImageFromUrl, "getImageFromUrl");
276
+ async function atNotSayReply(cfg, session, elements) {
277
+ if ((cfg.atNotSay || cfg.atNotSayOther) && elements.length === 1 && elements[0].type === "at") {
278
+ const isAtSelf = elements[0].attrs.id === session.selfId;
279
+ if (isAtSelf && cfg.atNotSay && import_koishi.Random.bool(cfg.atNotSayProperty)) {
280
+ await session.send(session.text("middleware.messages.atNotReply"));
281
+ } else if (!isAtSelf && cfg.atNotSayOther && import_koishi.Random.bool(cfg.atNotSayOtherProperty)) {
282
+ await session.send(session.text("middleware.messages.atNotReplyOther"));
283
+ }
284
+ }
285
+ }
286
+ __name(atNotSayReply, "atNotSayReply");
287
+ async function replyBot(cfg, session, elements) {
288
+ if (cfg.replyBot !== "关闭") {
289
+ const bots = ["bot", "机器人", "Bot", "BOT", "机器人!", "机器人!", "人机"];
290
+ const texts = elements?.filter((e) => e.type === "text").map((e) => e?.attrs?.content?.trim());
291
+ const ats = elements?.filter((e) => e.type === "at").map((e) => e?.attrs?.id);
292
+ const mentionedBot = texts?.some((t) => bots.includes(t));
293
+ const atMe = ats?.includes(session.selfId);
294
+ if (elements?.length === 1 && mentionedBot && cfg.replyBot === "无需at" || elements?.length === 2 && mentionedBot && atMe) {
295
+ await session.send(session.text("middleware.messages.notBot"));
296
+ }
297
+ }
298
+ }
299
+ __name(replyBot, "replyBot");
300
+ async function iLoveYou(cfg, session, elements) {
301
+ if (cfg.iLoveYou) {
302
+ const hasAtMe = elements?.some((e) => e.type === "at" && e?.attrs?.id === session.selfId);
303
+ const hasLoveMessage = elements?.some(
304
+ (e) => e.type === "text" && e?.attrs?.content?.trim() === session.text("middleware.messages.loveMessage")
305
+ );
306
+ if (elements?.length === 2 && hasAtMe && hasLoveMessage) {
307
+ await session.send(session.text("middleware.messages.iLoveU", {
308
+ at: import_koishi.h.at(session.userId),
309
+ quote: import_koishi.h.quote(session.messageId)
310
+ }));
311
+ }
312
+ }
313
+ }
314
+ __name(iLoveYou, "iLoveYou");
315
+ async function drawBanGDream(avatar, inputOptions) {
316
+ if (!avatar) {
317
+ return "";
318
+ }
319
+ const colors = ["cool", "pure", "happy", "powerful"];
320
+ const bands = ["ppp", "ag", "pp", "r", "hhw", "ras", "mnk", "go"];
321
+ const starTypes = ["normal_star", "color_star"];
322
+ const options = {
323
+ color: inputOptions.color || import_koishi.Random.pick(colors),
324
+ band: inputOptions.band || import_koishi.Random.pick(bands),
325
+ starNum: inputOptions.starNum || import_koishi.Random.pick([1, 2, 3, 4, 5]),
326
+ starType: inputOptions.starType || "",
327
+ border: inputOptions.border || ""
328
+ };
329
+ options.starType ||= options.starNum < 3 ? starTypes[0] : import_koishi.Random.pick(starTypes);
330
+ options.border ||= `card-${options.starNum}${options.starNum == 1 ? `-${options.color}` : ""}`;
331
+ const [image, colorImage, bandImage, starImage, borderImage] = await Promise.all([
332
+ import_jimp.Jimp.read(avatar),
333
+ import_jimp.Jimp.read(`${assetsDir}/bangborder/${options.color}.png`),
334
+ import_jimp.Jimp.read(`${assetsDir}/bangborder/${options.band}.png`),
335
+ import_jimp.Jimp.read(`${assetsDir}/bangborder/${options.starType}.png`),
336
+ import_jimp.Jimp.read(`${assetsDir}/bangborder/${options.border}.png`)
337
+ ]);
338
+ const zoom = 2;
339
+ image.cover({ w: 500 * zoom, h: 500 * zoom });
340
+ borderImage.cover({ w: 500 * zoom, h: 500 * zoom });
341
+ image.composite(borderImage);
342
+ colorImage.cover({ w: 130 * zoom, h: 130 * zoom });
343
+ image.composite(colorImage, image.width - colorImage.width - 3 * zoom, 5.5);
344
+ bandImage.width > bandImage.height ? bandImage.resize({ w: 120 * zoom }) : bandImage.resize({ h: 120 * zoom });
345
+ image.composite(bandImage, 15 * zoom, 15 * zoom);
346
+ starImage.resize({ w: 90 * zoom });
347
+ const step = 60 * zoom;
348
+ let hei = 410 * zoom;
349
+ let times = options.starNum;
350
+ while (times > 0) {
351
+ image.composite(starImage, 10 * zoom, hei);
352
+ hei -= step;
353
+ times--;
354
+ }
355
+ return `data:image/png;base64,${(await image.getBuffer("image/jpeg")).toString("base64")}`;
356
+ }
357
+ __name(drawBanGDream, "drawBanGDream");
248
358
  // Annotate the CommonJS export names for ESM import in node:
249
359
  0 && (module.exports = {
250
360
  Config,
@@ -254,6 +364,7 @@ __name(getImageFromUrl, "getImageFromUrl");
254
364
  drawLock,
255
365
  drawSold,
256
366
  getImageSrc,
367
+ handleBanGDreamConfig,
257
368
  name,
258
369
  usage
259
370
  });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "contributors": [
5
5
  "StarFreedomX <starfreedomx@outlook.com>"
6
6
  ],
7
- "version": "0.4.2",
7
+ "version": "0.5.0",
8
8
  "main": "lib/index.js",
9
9
  "typings": "lib/index.d.ts",
10
10
  "files": [
@@ -36,6 +36,7 @@
36
36
  "koishi": "^4.18.7"
37
37
  },
38
38
  "dependencies": {
39
+ "jimp": "^1.6.0",
39
40
  "sharp": "^0.34.1"
40
41
  }
41
42
  }
package/readme.md CHANGED
@@ -25,3 +25,4 @@ StarFreedomX机器人的小功能,自用
25
25
  | `0.3.6` | 添加"艾特我/他又不说话"的概率配置 |
26
26
  | `0.4.0` | 更改处理库为sharp |
27
27
  | `0.4.1` | 修复sharp处理w>h的图报错的bug |
28
+ | `0.5.0` | 加入BanG Dream!边框功能 |