koishi-plugin-node-async-bot-all 2.20.2 → 2.22.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/commands.d.ts CHANGED
@@ -23,6 +23,27 @@ export interface APIUserInfo {
23
23
  reg_time: string;
24
24
  last_updated: string;
25
25
  }
26
+ export interface APINews {
27
+ appnews: AppNews;
28
+ }
29
+ interface AppNews {
30
+ appid: number;
31
+ newsitems: NewsItem[];
32
+ count: number;
33
+ }
34
+ interface NewsItem {
35
+ gid: string;
36
+ title: string;
37
+ url: string;
38
+ is_external_url: boolean;
39
+ author: string;
40
+ contents: string;
41
+ feedlabel: string;
42
+ date: number;
43
+ feedname: string;
44
+ feed_type: number;
45
+ appid: number;
46
+ }
26
47
  export declare function getServer(ctx: Context, session: Session): Promise<Object>;
27
48
  export declare function getStatus(ctx: Context, session: Session): Promise<Object>;
28
49
  export declare function getRandom(ctx: Context, session: Session, min: number, max: number): Promise<Object>;
@@ -34,3 +55,9 @@ export declare function getMeme(ctx: Context, session: Session, count: number):
34
55
  export declare function getCat(ctx: Context, session: Session): Promise<Number>;
35
56
  export declare function getQQInfo(ctx: Context, session: Session, qq: string): Promise<number>;
36
57
  export declare function getMsg(ctx: Context, session: Session): Promise<number>;
58
+ export declare function getNewsMsg(ctx: Context, type: number): Promise<{
59
+ success: boolean;
60
+ data: string;
61
+ msg?: string;
62
+ }>;
63
+ export {};
package/lib/fun.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import { HttpResponse } from "./index";
2
2
  import { Context } from "koishi";
3
- import { APIUserInfo } from "./commands";
3
+ import { APINews, APIUserInfo } from "./commands";
4
+ export type serverInfo = {
5
+ players: string;
6
+ protocol: number;
7
+ version: string;
8
+ bots: number;
9
+ port: number;
10
+ success: true;
11
+ } | {
12
+ success: false;
13
+ error: any;
14
+ };
4
15
  export declare function getSystemUsage(): Promise<Object>;
5
16
  export declare function getHongKongTime(): string;
6
17
  export declare function readInfoFile(ctx: Context): Promise<string>;
@@ -17,3 +28,5 @@ export declare function random(type: number | undefined, data: any, data2?: any)
17
28
  export declare function request<T = any>(url: string, options?: RequestInit, timeout?: number, log?: any): Promise<HttpResponse<T>>;
18
29
  export declare function readUserCardFile(userInfo: APIUserInfo): Promise<string>;
19
30
  export declare function readUserMsgFile(userName: string, userAvatar: string, msg: string): Promise<string>;
31
+ export declare function queryA2S(host: string, log: any): Promise<serverInfo>;
32
+ export declare function readNewsFile(info: APINews): Promise<string>;
package/lib/index.d.ts CHANGED
@@ -13,6 +13,9 @@ declare module 'koishi' {
13
13
  interface Tables {
14
14
  botData: botDataTables;
15
15
  }
16
+ interface Events {
17
+ "node-async/news"(): void;
18
+ }
16
19
  }
17
20
  interface botDataTables {
18
21
  id: string;
@@ -20,13 +23,17 @@ interface botDataTables {
20
23
  }
21
24
  export declare const name = "node-async-bot-all";
22
25
  export declare const usage = "\u8FD9\u662F\u4E00\u4E2A\u79C1\u6709\u63D2\u4EF6\u3002";
23
- export interface ConfigCxV2 {
26
+ export interface ConfigCxV3 {
24
27
  id: string;
25
- api: Array<string>;
26
- note: Array<string>;
28
+ server: Array<ConfigV3Server>;
29
+ }
30
+ export interface ConfigV3Server {
31
+ api: string;
32
+ note: string;
33
+ type: "mc" | "a2s" | null | undefined;
27
34
  }
28
35
  export interface Config {
29
- cxV2: Array<ConfigCxV2>;
36
+ cxV3: Array<ConfigCxV3>;
30
37
  rwAPI: string;
31
38
  timeout: number;
32
39
  baAPI: string[];
@@ -35,6 +42,7 @@ export interface Config {
35
42
  memesAPI: Dict<string>;
36
43
  catAPI: string;
37
44
  qqAPI: string;
45
+ slNews: string[];
38
46
  }
39
47
  export declare const Config: Schema<Config>;
40
48
  export declare function apply(ctx: Context): void;
package/lib/index.js CHANGED
@@ -34,7 +34,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  // src/locales/zh-CN.yml
35
35
  var require_zh_CN = __commonJS({
36
36
  "src/locales/zh-CN.yml"(exports2, module2) {
37
- module2.exports = { commands: { cxgame: { description: "查询服务器当前人数。", messages: { msg: "{time}{list}\n进服指南请在群公告中查看。", list: "【MC 服务器 {count}】\n➣ {version}:{players}\n➣ 玩家列表:{list}\n➣ 备注:{note}", listNoPlayer: "【MC 服务器 {count}】\n➣ {version}:{players}\n➣ 备注:{note}", listFailed: "【MC 服务器 {count}】\n➣ 查询失败:{data}\n➣ 请稍后重试。", forbidden: "{time}\n此指令不允许在本群使用。", failed: "{time}\n查询失败:{data}", timeout: "请求超时。", timeout2: "响应超时。", fewData: "服务端返回的数据过少。", close: "服务器已关闭。", error: "执行错误。", host: "没有到主机的路由。" } }, status: { description: "查询机器人状态。", messages: { msg: "{time}\n--- 系统状态 ---\n系统名称:{name}\nCPU使用率:{cpu}\n内存使用率:{memory}\n--- 机器人状态 ---\n昨日收/发消息数量:{msgCount}\n机器人版本:{version}\n运行时间:{online}", failed: "{time}\n状态获取失败。" } }, random: { description: "随机数生成器。", usage: "缺少参数时默认生成 0-10000 的随机数。\n使用示例:", examples: "random 1 128 生成1到128范围的随机数", messages: { msg: "{time}\n生成的随机数:{data}" } }, info: { description: "查询机器人信息。", messages: { msg: "{data}", failed: "{time}\n读取信息失败。" } }, rw: { description: "随机名言名句。", messages: { msg: "{time}\n{data}", error: "执行错误。", failed: "{time}\n获取失败({data})。" } }, randomba: { description: "随机BA图。", messages: { msg: "{quote}{image}", wait: "{quote}{time}\n请等待图片上传(可能较慢)。" } }, servertest: { description: "Ping服务器。", messages: { msg: "{time}\n== Ping {host} ==\n状态:{alive}\n丢包率:{packetLoss}\n返回IP:{ip}", forbidden: "{time}\n此指令不允许在本群使用。", failed: "{time}\nPing 失败:{data}" } }, meme: { description: "群友的怪话!", messages: { msg: "{quote}{time}\n{image}\n{title}", failed: "{quote}{time}\n获取失败:{data}", forbidden: "{quote}{time}\n此指令不允许在本群使用。", error: "执行错误。" } }, randomcat: { description: "随机猫猫图。", messages: { msg: "{quote}{image}", wait: "{quote}{time}\n请等待图片上传(可能较慢)。", failed: "{quote}{time}\n获取失败:{data}" } }, getqqinfo: { description: "获取 QQ 号的信息。", messages: { msg: "{quote}{image}", failed: "{quote}{time}\n获取失败:{data}", command: "QQ 号不正确。" } }, msg2img: { description: "引用一个消息并使用此指令,即可将消息转图。", messages: { msg: "{quote}{image}", failed: "{quote}{time}\n获取失败:{data}", null: "未引用任何消息。", matroska: "{quote}禁止套娃!" } } } };
37
+ module2.exports = { commands: { cxgame: { description: "查询服务器当前人数。", messages: { msg: "{time}{list}\n进服指南请在群公告中查看。", list: "【MC 服务器 {count}】\n➣ {version}:{players}\n➣ 玩家列表:{list}\n➣ 备注:{note}", listNoPlayer: "【MC 服务器 {count}】\n➣ {version}:{players}\n➣ 备注:{note}", listFailed: "【MC 服务器 {count}】\n➣ 查询失败:{data}\n➣ 请稍后重试。\n➣ 备注:{note}", listA2S: "【A2S 服务器 {count}】\n➣ {version}:{players}\n➣ 机器人:{bots}\n➣ 备注:{note}", listFailedA2S: "【A2S 服务器 {count}】\n➣ 查询失败:{data}\n➣ 请稍后重试。\n➣ 备注:{note}", forbidden: "{time}\n此指令不允许在本群使用。", failed: "{time}\n查询失败:{data}", timeout: "请求超时。", timeout2: "响应超时。", fewData: "服务端返回的数据过少。", close: "服务器已关闭。", error: "执行错误。", host: "没有到主机的路由。" } }, status: { description: "查询机器人状态。", messages: { msg: "{time}\n--- 系统状态 ---\n系统名称:{name}\nCPU使用率:{cpu}\n内存使用率:{memory}\n--- 机器人状态 ---\n昨日收/发消息数量:{msgCount}\n机器人版本:{version}\n运行时间:{online}", failed: "{time}\n状态获取失败。" } }, random: { description: "随机数生成器。", usage: "缺少参数时默认生成 0-10000 的随机数。\n使用示例:", examples: "random 1 128 生成1到128范围的随机数", messages: { msg: "{time}\n生成的随机数:{data}" } }, info: { description: "查询机器人信息。", messages: { msg: "{data}", failed: "{time}\n读取信息失败。" } }, rw: { description: "随机名言名句。", messages: { msg: "{time}\n{data}", error: "执行错误。", failed: "{time}\n获取失败({data})。" } }, randomba: { description: "随机BA图。", messages: { msg: "{quote}{image}", wait: "{quote}{time}\n请等待图片上传(可能较慢)。" } }, servertest: { description: "Ping服务器。", messages: { msg: "{time}\n== Ping {host} ==\n状态:{alive}\n丢包率:{packetLoss}\n返回IP:{ip}", forbidden: "{time}\n此指令不允许在本群使用。", failed: "{time}\nPing 失败:{data}" } }, meme: { description: "群友的怪话!", messages: { msg: "{quote}{time}\n{image}\n{title}", failed: "{quote}{time}\n获取失败:{data}", forbidden: "{quote}{time}\n此指令不允许在本群使用。", error: "执行错误。" } }, randomcat: { description: "随机猫猫图。", messages: { msg: "{quote}{image}", wait: "{quote}{time}\n请等待图片上传(可能较慢)。", failed: "{quote}{time}\n获取失败:{data}" } }, getqqinfo: { description: "获取 QQ 号的信息。", messages: { msg: "{quote}{image}", failed: "{quote}{time}\n获取失败:{data}", command: "QQ 号不正确。" } }, msg2img: { description: "引用一个消息并使用此指令,即可将消息转图。", messages: { msg: "{quote}{image}", failed: "{quote}{time}\n获取失败:{data}", null: "未引用任何消息。", matroska: "{quote}禁止套娃!" } } } };
38
38
  }
39
39
  });
40
40
 
@@ -57,8 +57,11 @@ var import_koishi2 = require("koishi");
57
57
  var import_os = __toESM(require("os"));
58
58
  var import_fs = __toESM(require("fs"));
59
59
  var import_ping = __toESM(require("ping"));
60
+ var import_steam_server_query = require("steam-server-query");
60
61
  var import_path = __toESM(require("path"));
61
62
  var import_koishi = require("koishi");
63
+ var import_html = __toESM(require("@bbob/html"));
64
+ var import_preset_html5 = __toESM(require("@bbob/preset-html5"));
62
65
  function getSystemName() {
63
66
  return import_os.default.type() + " " + import_os.default.release();
64
67
  }
@@ -281,20 +284,55 @@ async function readUserMsgFile(userName, userAvatar, msg) {
281
284
  return html;
282
285
  }
283
286
  __name(readUserMsgFile, "readUserMsgFile");
287
+ async function queryA2S(host, log) {
288
+ try {
289
+ const playerResponse = await (0, import_steam_server_query.queryGameServerInfo)(host);
290
+ log?.info("Server Info:", playerResponse);
291
+ return {
292
+ players: playerResponse.players + "/" + playerResponse.maxPlayers,
293
+ protocol: playerResponse.protocol,
294
+ version: playerResponse.version,
295
+ bots: playerResponse.bots,
296
+ port: playerResponse.port,
297
+ success: true
298
+ };
299
+ } catch (e) {
300
+ log?.error("A2S Error:", e);
301
+ return {
302
+ error: e,
303
+ success: false
304
+ };
305
+ }
306
+ }
307
+ __name(queryA2S, "queryA2S");
308
+ async function readNewsFile(info) {
309
+ let html;
310
+ try {
311
+ const aPath = import_path.default.resolve(__dirname, "..") + import_path.default.sep + "res" + import_path.default.sep + "slNews.html";
312
+ html = await import_fs.default.promises.readFile(aPath, "utf8");
313
+ const content = (0, import_html.default)(info.appnews.newsitems[0].contents, (0, import_preset_html5.default)());
314
+ const date = Number(info.appnews.newsitems[0].date + "000");
315
+ html = html.toString().replace("{date}", new Date(date).toLocaleString()).replace("{title}", info.appnews.newsitems[0].title).replace("{content}", content);
316
+ } catch (error) {
317
+ html = error.message;
318
+ }
319
+ return html;
320
+ }
321
+ __name(readNewsFile, "readNewsFile");
284
322
 
285
323
  // src/commands.ts
286
324
  async function getServer(ctx, session) {
287
325
  const log = ctx.logger("cx");
288
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
326
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
289
327
  let msg;
290
328
  const time = getHongKongTime();
291
- const index = ctx.config.cxV2.findIndex((item) => item.id === session.event.guild?.id);
329
+ const index = ctx.config.cxV3.findIndex((item) => item.id === session.event.guild?.id);
292
330
  if (index !== -1) {
293
- const api = ctx.config.cxV2[index]["api"];
294
- if (api == void 0) {
331
+ const server = ctx.config.cxV3[index].server;
332
+ if (server == void 0) {
295
333
  msg = {
296
334
  "time": time,
297
- "data": "未指定查询 API",
335
+ "data": "未指定查询 服务器",
298
336
  "success": 2
299
337
  };
300
338
  log.warn("Sent:");
@@ -303,58 +341,92 @@ async function getServer(ctx, session) {
303
341
  }
304
342
  let count = 0;
305
343
  let list = "";
306
- for (const item of api) {
307
- const note = ctx.config.cxV2[index]["note"][count];
344
+ for (const item of server) {
345
+ const note = item.note;
346
+ const type = item.type;
347
+ const api = item.api;
308
348
  count++;
309
- const response = await request(item, {}, ctx.config.timeout, log);
310
- if (response.success) {
311
- if (response.data.list == null) {
349
+ if (type == "a2s") {
350
+ const info = await queryA2S(api, log);
351
+ if (info.success) {
312
352
  const temp = {
313
353
  "count": count,
314
- "players": response.data.players,
315
- "version": response.data.version,
354
+ "players": info.players,
355
+ "version": info.version,
356
+ "bots": info.bots,
316
357
  "note": note ?? "无"
317
358
  };
318
359
  log.info(`Server ${count}:`);
319
360
  log.info(temp);
320
- list = list + "\n" + session.text(".listNoPlayer", temp);
361
+ list = list + "\n" + session.text(".listA2S", temp);
321
362
  } else {
363
+ let err;
364
+ if (info.error.toString().includes("Timeout reached. Possible reasons: You are being rate limited; Timeout too short; Wrong server host configured")) {
365
+ err = "请求超时。";
366
+ } else {
367
+ err = "未知错误。";
368
+ }
322
369
  const temp = {
323
370
  "count": count,
324
- "players": response.data.players,
325
- "version": response.data.version,
326
- "list": response.data.list.join(", "),
327
- "note": note ?? "无"
371
+ "data": err,
372
+ "note": note
328
373
  };
329
- log.info(`Server ${count}:`);
330
- log.info(temp);
331
- list = list + "\n" + session.text(".list", temp);
374
+ log.error(`Server ${count}:`);
375
+ log.error(temp);
376
+ list = list + "\n" + session.text(".listFailedA2S", temp);
332
377
  }
333
378
  } else {
334
- let err;
335
- if (response.code) {
336
- err = response.isJson ? response.error["data"] : response.error;
337
- if (err.includes("Connection refused")) {
338
- err = session.text(".close");
339
- } else if (err.includes("No route to host")) {
340
- err = session.text(".host");
341
- } else if (err.includes("Connection timed out")) {
342
- err = session.text(".timeout");
343
- } else if (err.includes("Server returned too few data")) {
344
- err = session.text(".fewData");
345
- } else if (err.includes("Server read timed out")) {
346
- err = session.text(".timeout2");
379
+ const response = await request(api, {}, ctx.config.timeout, log);
380
+ if (response.success) {
381
+ if (response.data.list == null) {
382
+ const temp = {
383
+ "count": count,
384
+ "players": response.data.players,
385
+ "version": response.data.version,
386
+ "note": note ?? ""
387
+ };
388
+ log.info(`Server ${count}:`);
389
+ log.info(temp);
390
+ list = list + "\n" + session.text(".listNoPlayer", temp);
391
+ } else {
392
+ const temp = {
393
+ "count": count,
394
+ "players": response.data.players,
395
+ "version": response.data.version,
396
+ "list": response.data.list.join(", "),
397
+ "note": note ?? "无"
398
+ };
399
+ log.info(`Server ${count}:`);
400
+ log.info(temp);
401
+ list = list + "\n" + session.text(".list", temp);
347
402
  }
348
403
  } else {
349
- err = response.error.message;
404
+ let err;
405
+ if (response.code) {
406
+ err = response.isJson ? response.error["data"] : response.error;
407
+ if (err.includes("Connection refused")) {
408
+ err = session.text(".close");
409
+ } else if (err.includes("No route to host")) {
410
+ err = session.text(".host");
411
+ } else if (err.includes("Connection timed out")) {
412
+ err = session.text(".timeout");
413
+ } else if (err.includes("Server returned too few data")) {
414
+ err = session.text(".fewData");
415
+ } else if (err.includes("Server read timed out")) {
416
+ err = session.text(".timeout2");
417
+ }
418
+ } else {
419
+ err = response.error.message;
420
+ }
421
+ const temp = {
422
+ "count": count,
423
+ "data": err,
424
+ "note": note
425
+ };
426
+ log.error(`Server ${count}:`);
427
+ log.error(temp);
428
+ list = list + "\n" + session.text(".listFailed", temp);
350
429
  }
351
- const temp = {
352
- "count": count,
353
- "data": err
354
- };
355
- log.error(`Server ${count}:`);
356
- log.error(temp);
357
- list = list + "\n" + session.text(".listFailed", temp);
358
430
  }
359
431
  }
360
432
  msg = {
@@ -375,7 +447,7 @@ async function getServer(ctx, session) {
375
447
  __name(getServer, "getServer");
376
448
  async function getStatus(ctx, session) {
377
449
  const log = ctx.logger("status");
378
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
450
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
379
451
  const time = getHongKongTime();
380
452
  let msg;
381
453
  const vMsg = await getSystemUsage();
@@ -409,7 +481,7 @@ async function getStatus(ctx, session) {
409
481
  __name(getStatus, "getStatus");
410
482
  async function getRandom(ctx, session, min, max) {
411
483
  const log = ctx.logger("random");
412
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
484
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
413
485
  const time = getHongKongTime();
414
486
  let msg;
415
487
  let data;
@@ -432,7 +504,7 @@ async function getRandom(ctx, session, min, max) {
432
504
  __name(getRandom, "getRandom");
433
505
  async function getInfo(ctx, session) {
434
506
  const log = ctx.logger("info");
435
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
507
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
436
508
  const time = getHongKongTime();
437
509
  let msg;
438
510
  let data = await readInfoFile(ctx);
@@ -458,7 +530,7 @@ async function getInfo(ctx, session) {
458
530
  __name(getInfo, "getInfo");
459
531
  async function getRandomWord(ctx, session) {
460
532
  const log = ctx.logger("rw");
461
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
533
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
462
534
  let msg;
463
535
  const time = getHongKongTime();
464
536
  if (ctx.config.rwAPI == void 0) {
@@ -500,7 +572,7 @@ async function getRandomWord(ctx, session) {
500
572
  __name(getRandomWord, "getRandomWord");
501
573
  async function getBlueArchive(ctx, session) {
502
574
  const log = ctx.logger("ba");
503
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
575
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
504
576
  const time = getHongKongTime();
505
577
  if (ctx.config.baAPI == void 0) {
506
578
  await session.send(session.text(".msg", { "quote": import_koishi2.h.quote(session.messageId), "image": "未指定 API" }));
@@ -519,7 +591,7 @@ async function getBlueArchive(ctx, session) {
519
591
  __name(getBlueArchive, "getBlueArchive");
520
592
  async function serverTest(ctx, session) {
521
593
  const log = ctx.logger("serverTest");
522
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
594
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
523
595
  const time = getHongKongTime();
524
596
  const host = ctx.config.serverPing[`${session.event.guild?.id}`];
525
597
  if (host == void 0) {
@@ -556,7 +628,7 @@ async function serverTest(ctx, session) {
556
628
  __name(serverTest, "serverTest");
557
629
  async function getMeme(ctx, session, count) {
558
630
  const log = ctx.logger("getMeme");
559
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
631
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
560
632
  let msg;
561
633
  const time = getHongKongTime();
562
634
  if (ctx.config.memesAPI[`${session.event.guild?.id}`] == void 0) {
@@ -605,7 +677,7 @@ async function getMeme(ctx, session, count) {
605
677
  __name(getMeme, "getMeme");
606
678
  async function getCat(ctx, session) {
607
679
  const log = ctx.logger("cat");
608
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
680
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
609
681
  const time = getHongKongTime();
610
682
  if (ctx.config.catAPI == void 0) {
611
683
  await session.send(session.text(".failed", { "quote": import_koishi2.h.quote(session.messageId), "data": "未指定 API", "time": time }));
@@ -636,7 +708,7 @@ async function getCat(ctx, session) {
636
708
  __name(getCat, "getCat");
637
709
  async function getQQInfo(ctx, session, qq) {
638
710
  const log = ctx.logger("getQQInfo");
639
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
711
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
640
712
  const time = getHongKongTime();
641
713
  if (ctx.config.qqAPI == void 0) {
642
714
  await session.send(session.text(".failed", { "quote": import_koishi2.h.quote(session.messageId), "data": "未指定 API", "time": time }));
@@ -684,7 +756,7 @@ async function getQQInfo(ctx, session, qq) {
684
756
  __name(getQQInfo, "getQQInfo");
685
757
  async function getMsg(ctx, session) {
686
758
  const log = ctx.logger("getQQInfo");
687
- log.debug(`Got: {"form":"${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
759
+ log.debug(`Got: {"form":"${session.platform}:${session.event.guild?.id}","user":"${session.event.user?.id}","timestamp":${session.event.timestamp},"messageId":"${session.event.message?.id}"}`);
688
760
  const time = getHongKongTime();
689
761
  if (!session.quote || !session.quote.user) {
690
762
  await session.send(session.text(".null"));
@@ -740,12 +812,55 @@ async function getMsg(ctx, session) {
740
812
  return 0;
741
813
  }
742
814
  __name(getMsg, "getMsg");
815
+ async function getNewsMsg(ctx, type) {
816
+ const log = ctx.logger("getNewsMsg");
817
+ const response = await request("https://api.steampowered.com/ISteamNews/GetNewsForApp/v2/?appid=700330&count=1", {}, ctx.config.timeout, log);
818
+ if (response.success) {
819
+ if ((await ctx.database.get("botData", "newsId"))[0]?.data == response.data.appnews.newsitems[0].gid) {
820
+ log.debug("无新闻");
821
+ return { success: false, data: "" };
822
+ }
823
+ const page = await ctx.puppeteer.page();
824
+ const html = await readNewsFile(response.data);
825
+ try {
826
+ await page.setViewport({
827
+ width: 800,
828
+ height: 800,
829
+ deviceScaleFactor: 2
830
+ });
831
+ await page.setContent(html, { waitUntil: "networkidle0" });
832
+ const { width, height } = await page.evaluate(() => ({
833
+ width: document.body.scrollWidth,
834
+ height: document.body.scrollHeight
835
+ }));
836
+ await page.setViewport({ width, height, deviceScaleFactor: 2 });
837
+ const image = await page.screenshot({
838
+ type: "png",
839
+ fullPage: true,
840
+ omitBackground: true
841
+ // 使得 CSS 中未定义的背景部分透明
842
+ });
843
+ if (type == 0) await ctx.database.upsert("botData", [
844
+ { id: "newsId", data: response.data.appnews.newsitems[0].gid }
845
+ ]);
846
+ return { success: true, data: Buffer.from(image).toString("base64"), msg: "NW 发布了一个新闻(原文英语):" + response.data.appnews.newsitems[0].title };
847
+ } catch (err) {
848
+ log.error("图片渲染失败:", err);
849
+ return { success: false, data: "图片渲染失败" };
850
+ } finally {
851
+ if (page && !page.isClosed()) await page.close();
852
+ }
853
+ } else {
854
+ return { success: false, data: "请求 Steam API 失败" };
855
+ }
856
+ }
857
+ __name(getNewsMsg, "getNewsMsg");
743
858
 
744
859
  // package.json
745
- var version = "2.20.2";
860
+ var version = "2.22.0";
746
861
 
747
862
  // src/index.ts
748
- var inject = ["database", "installer", "puppeteer"];
863
+ var inject = ["database", "installer", "puppeteer", "cron"];
749
864
  var name = "node-async-bot-all";
750
865
  var usage = "这是一个私有插件。";
751
866
  var Config = import_koishi3.Schema.intersect([
@@ -753,13 +868,18 @@ var Config = import_koishi3.Schema.intersect([
753
868
  timeout: import_koishi3.Schema.number().default(8e3).description("超时时间(毫秒)")
754
869
  }).description("基础"),
755
870
  import_koishi3.Schema.object({
756
- cxV2: import_koishi3.Schema.array(
871
+ cxV3: import_koishi3.Schema.array(
757
872
  import_koishi3.Schema.object({
758
- id: import_koishi3.Schema.string().required().description("查询 群"),
759
- api: import_koishi3.Schema.array(String).description("查询 API"),
760
- note: import_koishi3.Schema.array(String).description("查询 备注")
873
+ id: import_koishi3.Schema.string().description("查询 群"),
874
+ server: import_koishi3.Schema.array(
875
+ import_koishi3.Schema.object({
876
+ api: import_koishi3.Schema.string().description("查询 API | HOST"),
877
+ note: import_koishi3.Schema.string().description("查询 备注"),
878
+ type: import_koishi3.Schema.union(["mc", "a2s"]).description("查询 类型")
879
+ })
880
+ ).description("查询 服务器")
761
881
  })
762
- ).default([]).description("查询的 API 和 群")
882
+ ).default([]).description("查询的群")
763
883
  }).description("查询"),
764
884
  import_koishi3.Schema.object({
765
885
  rwAPI: import_koishi3.Schema.string().default("https://api.tasaed.top/rw/").description("随机文本 API")
@@ -781,7 +901,10 @@ var Config = import_koishi3.Schema.intersect([
781
901
  }).description("随机猫猫图"),
782
902
  import_koishi3.Schema.object({
783
903
  qqAPI: import_koishi3.Schema.string().default("https://uapis.cn/api/v1/social/qq/userinfo").description("获取 QQ 信息 API")
784
- }).description("获取 QQ 信息")
904
+ }).description("获取 QQ 信息"),
905
+ import_koishi3.Schema.object({
906
+ slNews: import_koishi3.Schema.array(String).default([""]).description("{platform}:{channelId}")
907
+ }).description("SL新闻列表")
785
908
  ]).description("基础设置");
786
909
  function apply(ctx) {
787
910
  ctx.i18n.define("zh-CN", require_zh_CN());
@@ -797,6 +920,33 @@ function apply(ctx) {
797
920
  { id: "version", data: version }
798
921
  ]);
799
922
  });
923
+ ctx.command("slnews", "手动触发slnews发送到当前会话").action(async ({ session }) => {
924
+ const outMsg = await getNewsMsg(ctx, 1);
925
+ if (outMsg.success) {
926
+ if (outMsg.msg) session?.send(outMsg.msg);
927
+ return (0, import_koishi3.h)("image", { url: `data:image/jpg;base64,${outMsg.data}` });
928
+ } else {
929
+ if (outMsg.data == "") return "无可用新闻";
930
+ return outMsg.data;
931
+ }
932
+ });
933
+ ctx.cron("0 * * * *", async () => {
934
+ ctx.emit("node-async/news");
935
+ });
936
+ ctx.cron("5 * * * *", async () => {
937
+ ctx.emit("node-async/news");
938
+ });
939
+ ctx.on("node-async/news", async () => {
940
+ const outMsg = await getNewsMsg(ctx, 0);
941
+ if (outMsg.success) {
942
+ if (outMsg.msg) await ctx.broadcast(ctx.config.slNews, outMsg.msg);
943
+ await (0, import_koishi3.sleep)(100);
944
+ await ctx.broadcast(ctx.config.slNews, (0, import_koishi3.h)("image", { url: `data:image/jpg;base64,${outMsg.data}` }));
945
+ } else {
946
+ if (outMsg.data == "") return;
947
+ await ctx.broadcast(ctx.config.slNews, outMsg.data);
948
+ }
949
+ });
800
950
  ctx.command("cxGame").action(async ({ session }) => {
801
951
  const cx = await getServer(ctx, session);
802
952
  if (cx["success"] == 0) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-node-async-bot-all",
3
3
  "description": "NodeAsync Bot插件(自用)",
4
- "version": "2.20.2",
4
+ "version": "2.22.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "contributors": [
@@ -33,9 +33,14 @@
33
33
  "peerDependencies": {
34
34
  "@koishijs/plugin-database-sqlite": "^4.6.0",
35
35
  "@koishijs/plugin-help": "^2.4.5",
36
- "koishi": "^4.18.7"
36
+ "@koishijs/plugin-market": "^2.11.8",
37
+ "koishi": "^4.18.7",
38
+ "koishi-plugin-puppeteer": "^3.9.0"
37
39
  },
38
40
  "dependencies": {
39
- "ping": "^1.0.0"
41
+ "@bbob/html": "^4.3.1",
42
+ "@bbob/preset-html5": "^4.3.1",
43
+ "ping": "^1.0.0",
44
+ "steam-server-query": "^1.1.3"
40
45
  }
41
46
  }
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <style>
6
+ body {
7
+ margin: 0;
8
+ padding: 0;
9
+ background-color: #1b2838; /* Steam 经典深蓝背景 */
10
+ font-family: "Motiva Sans", Arial, Helvetica, sans-serif;
11
+ color: #acb2b8;
12
+ display: flex;
13
+ justify-content: center;
14
+ }
15
+ .container {
16
+ width: 100%;
17
+ max-width: 800px;
18
+ background-color: #1b2838;
19
+ }
20
+ .content-padding {
21
+ padding: 30px;
22
+ }
23
+ .date {
24
+ color: #808589;
25
+ font-size: 13px;
26
+ text-transform: uppercase;
27
+ letter-spacing: 1px;
28
+ margin-bottom: 10px;
29
+ }
30
+ .title {
31
+ color: #ffffff;
32
+ font-size: 32px;
33
+ font-weight: bold;
34
+ line-height: 1.2;
35
+ margin-bottom: 20px;
36
+ text-shadow: 0 0 10px rgba(0,0,0,0.5);
37
+ }
38
+ .body-text {
39
+ font-size: 16px;
40
+ line-height: 1.6;
41
+ color: #d1d1d1;
42
+ }
43
+ .body-text p {
44
+ margin-bottom: 20px;
45
+ }
46
+ .update-box h3 {
47
+ color: #1a9fff;
48
+ margin-top: 0;
49
+ }
50
+ ul {
51
+ padding-left: 20px;
52
+ }
53
+ li {
54
+ margin-bottom: 10px;
55
+ }
56
+ </style>
57
+ <title>News</title>
58
+ </head>
59
+ <body>
60
+ <div class="container">
61
+ <div class="content-padding">
62
+ <div class="date">{date}</div>
63
+ <div class="title">{title}</div>
64
+
65
+ <div class="body-text">
66
+ {content}
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </body>
71
+ </html>