koishi-plugin-cat-raising 1.3.9 → 1.4.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  import { Context, Schema } from 'koishi';
2
2
  export declare const name = "cat-raising";
3
+ export declare const inject: {
4
+ required: string[];
5
+ optional: any[];
6
+ };
7
+ declare module 'koishi' {
8
+ interface Tables {
9
+ cat_raising_forward_history: CatRaisingForwardHistory;
10
+ }
11
+ }
12
+ export interface CatRaisingForwardHistory {
13
+ id: number;
14
+ roomId: string;
15
+ originalMessageId: string;
16
+ forwardTime: Date;
17
+ shenjinCount: number;
18
+ }
3
19
  /** B站 access_key 配置项 */
4
20
  export interface BiliAccessKeyConfig {
5
21
  /** Bilibili access_key */
package/lib/index.js CHANGED
@@ -32,13 +32,19 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  Config: () => Config,
34
34
  apply: () => apply,
35
+ inject: () => inject,
35
36
  name: () => name
36
37
  });
37
38
  module.exports = __toCommonJS(src_exports);
38
39
  var import_koishi = require("koishi");
39
40
  var crypto = __toESM(require("crypto"));
41
+ var net = __toESM(require("net"));
40
42
  var import_url = require("url");
41
43
  var name = "cat-raising";
44
+ var inject = {
45
+ required: ["database"],
46
+ optional: []
47
+ };
42
48
  var Config = import_koishi.Schema.intersect([
43
49
  import_koishi.Schema.object({
44
50
  targetQQ: import_koishi.Schema.string().description("转发目标:填 QQ 或 群号").role("link").required(),
@@ -314,11 +320,97 @@ async function fetchBilibiliInfo(ctx, roomId) {
314
320
  }
315
321
  __name(fetchBilibiliInfo, "fetchBilibiliInfo");
316
322
  function apply(ctx, config) {
323
+ ctx.model.extend("cat_raising_forward_history", {
324
+ id: "unsigned",
325
+ roomId: "string",
326
+ originalMessageId: "string",
327
+ forwardTime: "timestamp",
328
+ shenjinCount: "double"
329
+ }, {
330
+ autoInc: true
331
+ });
317
332
  const forwardedHistory = [];
318
333
  const warningMessageMap = /* @__PURE__ */ new Map();
319
334
  const pendingDanmakuTimersByMessage = /* @__PURE__ */ new Map();
320
335
  const pendingDanmakuTimersByRoom = /* @__PURE__ */ new Map();
321
336
  const pendingDanmakuRoomMap = /* @__PURE__ */ new Map();
337
+ ctx.command("cat", "🐱喵喵喵");
338
+ ctx.command("cat.status", "查看插件状态").action(async () => {
339
+ let latencyMsg = "";
340
+ try {
341
+ const ms = await tcpPing("api.live.bilibili.com", 80);
342
+ latencyMsg = `B站API延迟: ${ms}ms`;
343
+ } catch (e) {
344
+ latencyMsg = `B站API延迟: 失败 (${e.message || "Unknown"})`;
345
+ }
346
+ return `🐱喵喵喵
347
+ ${latencyMsg}`;
348
+ });
349
+ ctx.command("cat.total", "统计最近24小时内的神金数量").action(async () => {
350
+ const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1e3);
351
+ const records = await ctx.database.select("cat_raising_forward_history").where((row) => import_koishi.$.gte(row.forwardTime, oneDayAgo)).execute();
352
+ const count = records.length;
353
+ const stats = /* @__PURE__ */ new Map();
354
+ const now = /* @__PURE__ */ new Date();
355
+ for (let i = 23; i >= 0; i--) {
356
+ const d = new Date(now.getTime() - i * 60 * 60 * 1e3);
357
+ const key = `${d.getHours().toString().padStart(2, "0")}:00`;
358
+ stats.set(key, 0);
359
+ }
360
+ for (const record of records) {
361
+ const d = new Date(record.forwardTime);
362
+ const key = `${d.getHours().toString().padStart(2, "0")}:00`;
363
+ if (stats.has(key)) {
364
+ stats.set(key, stats.get(key) + 1);
365
+ }
366
+ }
367
+ const labels = Array.from(stats.keys());
368
+ const data = Array.from(stats.values());
369
+ const chartConfig = {
370
+ type: "line",
371
+ data: {
372
+ labels,
373
+ datasets: [{
374
+ label: "转发数量",
375
+ data,
376
+ borderColor: "rgb(75, 192, 192)",
377
+ tension: 0.1,
378
+ fill: false
379
+ }]
380
+ },
381
+ options: {
382
+ title: {
383
+ display: true,
384
+ text: `最近24小时内的神金数: ${count}`
385
+ },
386
+ scales: {
387
+ yAxes: [{
388
+ ticks: {
389
+ beginAtZero: true,
390
+ stepSize: 1
391
+ }
392
+ }]
393
+ }
394
+ }
395
+ };
396
+ try {
397
+ const response = await ctx.http.post("https://quickchart.io/chart", {
398
+ chart: chartConfig,
399
+ width: 800,
400
+ height: 400,
401
+ backgroundColor: "white"
402
+ }, {
403
+ responseType: "arraybuffer"
404
+ });
405
+ return (0, import_koishi.h)("message", {}, [
406
+ import_koishi.h.text(`最近24小时内的神金数: ${count}`),
407
+ import_koishi.h.image(response, "image/png")
408
+ ]);
409
+ } catch (err) {
410
+ ctx.logger.error("Error generating chart:", err);
411
+ return `最近24小时内的神金数: ${count} (图表生成失败)`;
412
+ }
413
+ });
322
414
  ctx.on("message", async (session) => {
323
415
  const groupConfig = config.monitorGroups.find((g) => g.groupId === session.channelId);
324
416
  if (!groupConfig) return;
@@ -379,9 +471,17 @@ function apply(ctx, config) {
379
471
  helperMessageId,
380
472
  // 存储辅助消息ID用于撤回联动
381
473
  roomId,
382
- dateTime
474
+ dateTime,
475
+ forwardTime: Date.now()
383
476
  });
384
477
  if (forwardedHistory.length > config.historySize) forwardedHistory.shift();
478
+ const shenjinCount = parsedEvent.rewards.reduce((sum, r) => sum + r.amount, 0);
479
+ ctx.database.create("cat_raising_forward_history", {
480
+ roomId,
481
+ originalMessageId: session.messageId,
482
+ forwardTime: /* @__PURE__ */ new Date(),
483
+ shenjinCount
484
+ });
385
485
  } catch (error) {
386
486
  session.send("🐱 - 转发失败,请检查目标QQ/群号配置是否正确");
387
487
  ctx.logger.error("[转发] 失败:", error);
@@ -460,6 +560,7 @@ function apply(ctx, config) {
460
560
  ctx.logger.warn(`[撤回] 转发消息 (ID: ${entry.forwardedMessageId}) 失败:`, e);
461
561
  } finally {
462
562
  forwardedHistory.splice(entryIndex, 1);
563
+ ctx.database.remove("cat_raising_forward_history", { originalMessageId }).catch((err) => ctx.logger.warn(`[撤回] 删除数据库记录失败:`, err));
463
564
  ctx.logger.info(`[撤回] 已联动撤回与源消息 ${originalMessageId} (直播间: ${entry.roomId}) 相关的转发。`);
464
565
  }
465
566
  }
@@ -481,9 +582,30 @@ function sleep(ms) {
481
582
  return new Promise((resolve) => setTimeout(resolve, ms));
482
583
  }
483
584
  __name(sleep, "sleep");
585
+ function tcpPing(host, port = 80, timeout = 2e3) {
586
+ return new Promise((resolve, reject) => {
587
+ const start = Date.now();
588
+ const socket = new net.Socket();
589
+ socket.setTimeout(timeout, () => {
590
+ socket.destroy();
591
+ reject(new Error("Timeout"));
592
+ });
593
+ socket.connect(port, host, () => {
594
+ const ms = Date.now() - start;
595
+ socket.destroy();
596
+ resolve(ms);
597
+ });
598
+ socket.on("error", (err) => {
599
+ socket.destroy();
600
+ reject(err);
601
+ });
602
+ });
603
+ }
604
+ __name(tcpPing, "tcpPing");
484
605
  // Annotate the CommonJS export names for ESM import in node:
485
606
  0 && (module.exports = {
486
607
  Config,
487
608
  apply,
609
+ inject,
488
610
  name
489
611
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-cat-raising",
3
3
  "description": "",
4
- "version": "1.3.9",
4
+ "version": "1.4.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [