llonebot-dist 7.12.11 → 7.12.14

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/llbot.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createRequire } from "node:module";
2
2
  import * as path$4 from "node:path";
3
3
  import path, { dirname, join } from "node:path";
4
- import fsPromise, { access, copyFile, mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
5
- import fs, { existsSync } from "fs";
6
- import * as fs$5 from "node:fs";
7
- import fs$1, { appendFile, appendFileSync, createReadStream, existsSync as existsSync$1, mkdirSync, promises, stat as stat$1, statSync, watch } from "node:fs";
4
+ import fs, { copyFile, mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
5
+ import fs$1, { existsSync } from "fs";
6
+ import * as fs$6 from "node:fs";
7
+ import fs$2, { appendFile, appendFileSync, createReadStream, existsSync as existsSync$1, mkdirSync, promises, stat as stat$1, statSync, watch } from "node:fs";
8
8
  import os from "node:os";
9
9
  import { Binary, Time, camelize, clone, deduplicate, deepEqual, defineProperty, difference, filterKeys, hyphenate, is, isNonNullable, isNullable, isPlainObject, makeArray, mapValues, noop, omit, pick, remove, valueMap } from "cosmokit";
10
10
  import { Exporter, Factory } from "reggol";
@@ -21,7 +21,7 @@ import http, { STATUS_CODES, createServer, request } from "node:http";
21
21
  import { Http2ServerRequest, constants as constants$1 } from "node:http2";
22
22
  import { Readable, Transform } from "node:stream";
23
23
  import { deflateSync, gunzipSync, gzipSync, inflateSync } from "node:zlib";
24
- import fsPromise$1, { stat as stat$2, unlink as unlink$1 } from "fs/promises";
24
+ import fsPromise, { stat as stat$2, unlink as unlink$1 } from "fs/promises";
25
25
  import { inspect, isDeepStrictEqual } from "node:util";
26
26
  import net, { connect } from "node:net";
27
27
  import https from "node:https";
@@ -3973,7 +3973,7 @@ var require_utils$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
3973
3973
  //#endregion
3974
3974
  //#region node_modules/qrcode/lib/renderer/png.js
3975
3975
  var require_png = /* @__PURE__ */ __commonJSMin(((exports) => {
3976
- var fs$10 = __require("fs");
3976
+ var fs$11 = __require("fs");
3977
3977
  var PNG = require_png$1().PNG;
3978
3978
  var Utils = require_utils$1();
3979
3979
  exports.render = function render(qrData, options) {
@@ -4025,7 +4025,7 @@ var require_png = /* @__PURE__ */ __commonJSMin(((exports) => {
4025
4025
  called = true;
4026
4026
  cb.apply(null, args);
4027
4027
  };
4028
- const stream = fs$10.createWriteStream(path);
4028
+ const stream = fs$11.createWriteStream(path);
4029
4029
  stream.on("error", done);
4030
4030
  stream.on("close", done);
4031
4031
  exports.renderToFileStream(stream, qrData, options);
@@ -6475,19 +6475,6 @@ var ChatType = /* @__PURE__ */ function(ChatType) {
6475
6475
  ChatType[ChatType["TempC2CFromGroup"] = 100] = "TempC2CFromGroup";
6476
6476
  return ChatType;
6477
6477
  }({});
6478
- var RMBizType = /* @__PURE__ */ function(RMBizType) {
6479
- RMBizType[RMBizType["Unknown"] = 0] = "Unknown";
6480
- RMBizType[RMBizType["C2CFile"] = 1] = "C2CFile";
6481
- RMBizType[RMBizType["GroupFile"] = 2] = "GroupFile";
6482
- RMBizType[RMBizType["C2CPic"] = 3] = "C2CPic";
6483
- RMBizType[RMBizType["GroupPic"] = 4] = "GroupPic";
6484
- RMBizType[RMBizType["DiscPic"] = 5] = "DiscPic";
6485
- RMBizType[RMBizType["C2CVideo"] = 6] = "C2CVideo";
6486
- RMBizType[RMBizType["GroupVideo"] = 7] = "GroupVideo";
6487
- RMBizType[RMBizType["C2CPtt"] = 8] = "C2CPtt";
6488
- RMBizType[RMBizType["GroupPtt"] = 9] = "GroupPtt";
6489
- return RMBizType;
6490
- }({});
6491
6478
  var MsgType = /* @__PURE__ */ function(MsgType) {
6492
6479
  MsgType[MsgType["ArkStruct"] = 11] = "ArkStruct";
6493
6480
  MsgType[MsgType["FaceBubble"] = 24] = "FaceBubble";
@@ -6624,7 +6611,7 @@ async function logSummaryMessage(ctx, message) {
6624
6611
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6625
6612
  module.exports = isexe;
6626
6613
  isexe.sync = sync;
6627
- var fs$9 = __require("fs");
6614
+ var fs$10 = __require("fs");
6628
6615
  function checkPathExt(path, options) {
6629
6616
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
6630
6617
  if (!pathext) return true;
@@ -6641,12 +6628,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6641
6628
  return checkPathExt(path, options);
6642
6629
  }
6643
6630
  function isexe(path, options, cb) {
6644
- fs$9.stat(path, function(er, stat) {
6631
+ fs$10.stat(path, function(er, stat) {
6645
6632
  cb(er, er ? false : checkStat(stat, path, options));
6646
6633
  });
6647
6634
  }
6648
6635
  function sync(path, options) {
6649
- return checkStat(fs$9.statSync(path), path, options);
6636
+ return checkStat(fs$10.statSync(path), path, options);
6650
6637
  }
6651
6638
  }));
6652
6639
  //#endregion
@@ -6654,14 +6641,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6654
6641
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6655
6642
  module.exports = isexe;
6656
6643
  isexe.sync = sync;
6657
- var fs$8 = __require("fs");
6644
+ var fs$9 = __require("fs");
6658
6645
  function isexe(path, options, cb) {
6659
- fs$8.stat(path, function(er, stat) {
6646
+ fs$9.stat(path, function(er, stat) {
6660
6647
  cb(er, er ? false : checkStat(stat, options));
6661
6648
  });
6662
6649
  }
6663
6650
  function sync(path, options) {
6664
- return checkStat(fs$8.statSync(path), options);
6651
+ return checkStat(fs$9.statSync(path), options);
6665
6652
  }
6666
6653
  function checkStat(stat, options) {
6667
6654
  return stat.isFile() && checkMode(stat, options);
@@ -9153,7 +9140,7 @@ var require_processor = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9153
9140
  //#endregion
9154
9141
  //#region node_modules/fluent-ffmpeg/lib/capabilities.js
9155
9142
  var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9156
- var fs$7 = __require("fs");
9143
+ var fs$8 = __require("fs");
9157
9144
  var path$7 = __require("path");
9158
9145
  var async = require_async();
9159
9146
  var utils = require_utils();
@@ -9229,7 +9216,7 @@ var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9229
9216
  proto._getFfmpegPath = function(callback) {
9230
9217
  if ("ffmpegPath" in cache) return callback(null, cache.ffmpegPath);
9231
9218
  async.waterfall([function(cb) {
9232
- if (process.env.FFMPEG_PATH) fs$7.exists(process.env.FFMPEG_PATH, function(exists) {
9219
+ if (process.env.FFMPEG_PATH) fs$8.exists(process.env.FFMPEG_PATH, function(exists) {
9233
9220
  if (exists) cb(null, process.env.FFMPEG_PATH);
9234
9221
  else cb(null, "");
9235
9222
  });
@@ -9260,7 +9247,7 @@ var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9260
9247
  if ("ffprobePath" in cache) return callback(null, cache.ffprobePath);
9261
9248
  async.waterfall([
9262
9249
  function(cb) {
9263
- if (process.env.FFPROBE_PATH) fs$7.exists(process.env.FFPROBE_PATH, function(exists) {
9250
+ if (process.env.FFPROBE_PATH) fs$8.exists(process.env.FFPROBE_PATH, function(exists) {
9264
9251
  cb(null, exists ? process.env.FFPROBE_PATH : "");
9265
9252
  });
9266
9253
  else cb(null, "");
@@ -9278,7 +9265,7 @@ var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9278
9265
  else if (ffmpeg.length) {
9279
9266
  var name = utils.isWindows ? "ffprobe.exe" : "ffprobe";
9280
9267
  var ffprobe = path$7.join(path$7.dirname(ffmpeg), name);
9281
- fs$7.exists(ffprobe, function(exists) {
9268
+ fs$8.exists(ffprobe, function(exists) {
9282
9269
  cb(null, exists ? ffprobe : "");
9283
9270
  });
9284
9271
  } else cb(null, "");
@@ -9303,14 +9290,14 @@ var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9303
9290
  if ("flvtoolPath" in cache) return callback(null, cache.flvtoolPath);
9304
9291
  async.waterfall([
9305
9292
  function(cb) {
9306
- if (process.env.FLVMETA_PATH) fs$7.exists(process.env.FLVMETA_PATH, function(exists) {
9293
+ if (process.env.FLVMETA_PATH) fs$8.exists(process.env.FLVMETA_PATH, function(exists) {
9307
9294
  cb(null, exists ? process.env.FLVMETA_PATH : "");
9308
9295
  });
9309
9296
  else cb(null, "");
9310
9297
  },
9311
9298
  function(flvtool, cb) {
9312
9299
  if (flvtool.length) return cb(null, flvtool);
9313
- if (process.env.FLVTOOL2_PATH) fs$7.exists(process.env.FLVTOOL2_PATH, function(exists) {
9300
+ if (process.env.FLVTOOL2_PATH) fs$8.exists(process.env.FLVTOOL2_PATH, function(exists) {
9314
9301
  cb(null, exists ? process.env.FLVTOOL2_PATH : "");
9315
9302
  });
9316
9303
  else cb(null, "");
@@ -9815,7 +9802,7 @@ var require_ffprobe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9815
9802
  //#endregion
9816
9803
  //#region node_modules/fluent-ffmpeg/lib/recipes.js
9817
9804
  var require_recipes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9818
- var fs$6 = __require("fs");
9805
+ var fs$7 = __require("fs");
9819
9806
  var path$6 = __require("path");
9820
9807
  var PassThrough$4 = __require("stream").PassThrough;
9821
9808
  var async = require_async();
@@ -10021,8 +10008,8 @@ var require_recipes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
10021
10008
  next(null, filenames);
10022
10009
  },
10023
10010
  function createDirectory(filenames, next) {
10024
- fs$6.exists(config.folder, function(exists) {
10025
- if (!exists) fs$6.mkdir(config.folder, function(err) {
10011
+ fs$7.exists(config.folder, function(exists) {
10012
+ if (!exists) fs$7.mkdir(config.folder, function(err) {
10026
10013
  if (err) next(err);
10027
10014
  else next(null, filenames);
10028
10015
  });
@@ -10270,7 +10257,7 @@ function setFFMpegPath(ffmpegPath) {
10270
10257
  path.join(import.meta.dirname, "ffmpeg.exe"),
10271
10258
  process.env["FFMPEG_PATH"] || ""
10272
10259
  ];
10273
- for (const p of paths) if (fs$1.existsSync(p)) {
10260
+ for (const p of paths) if (fs$2.existsSync(p)) {
10274
10261
  import_fluent_ffmpeg.default.setFfmpegPath(p);
10275
10262
  console.log("set ffmpeg successfully", p);
10276
10263
  break;
@@ -10801,7 +10788,7 @@ function encodeCQCode(input) {
10801
10788
  }
10802
10789
  //#endregion
10803
10790
  //#region src/onebot11/transform/message/incoming.ts
10804
- async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
10791
+ async function transformIncomingSegments$1(ctx, message) {
10805
10792
  const segments = [];
10806
10793
  let cqCode = "";
10807
10794
  for (const element of message.elements) {
@@ -10873,28 +10860,22 @@ async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
10873
10860
  data: {
10874
10861
  file: picElement.fileName,
10875
10862
  subType: picElement.picSubType,
10876
- url: await ctx.ntFileApi.getImageUrl(picElement),
10863
+ url: await ctx.ntFileApi.getImageUrl(picElement.originImageUrl, picElement.md5HexStr),
10877
10864
  file_size: fileSize
10878
10865
  }
10879
10866
  };
10880
10867
  ctx.store.addFileCache({
10881
- peerUid: message.peerUid,
10882
- msgId: message.msgId,
10883
10868
  msgTime: +message.msgTime,
10884
10869
  chatType: message.chatType,
10885
- elementId: element.elementId,
10886
10870
  elementType: element.elementType,
10887
10871
  fileName: picElement.fileName,
10888
10872
  fileUuid: picElement.fileUuid,
10889
- fileSize
10890
- }).then();
10873
+ fileSize,
10874
+ md5HexStr: picElement.md5HexStr
10875
+ });
10891
10876
  } else if (element.videoElement) {
10892
10877
  const { videoElement } = element;
10893
- const videoUrl = await ctx.ntFileApi.getVideoUrl(peer ?? {
10894
- chatType: message.chatType,
10895
- peerUid: message.peerUid,
10896
- guildId: ""
10897
- }, rootMsgID ?? message.msgId, element.elementId);
10878
+ const videoUrl = await ctx.ntFileApi.getVideoUrl(videoElement.fileUuid, message.chatType === ChatType.Group);
10898
10879
  const fileSize = videoElement.fileSize ?? "0";
10899
10880
  messageSegment = {
10900
10881
  type: OB11MessageDataType.Video,
@@ -10906,16 +10887,14 @@ async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
10906
10887
  }
10907
10888
  };
10908
10889
  ctx.store.addFileCache({
10909
- peerUid: message.peerUid,
10910
- msgId: message.msgId,
10911
10890
  msgTime: +message.msgTime,
10912
10891
  chatType: message.chatType,
10913
- elementId: element.elementId,
10914
10892
  elementType: element.elementType,
10915
10893
  fileName: videoElement.fileName,
10916
10894
  fileUuid: videoElement.fileUuid,
10917
- fileSize
10918
- }).then();
10895
+ fileSize,
10896
+ md5HexStr: videoElement.videoMd5
10897
+ });
10919
10898
  } else if (element.fileElement) {
10920
10899
  const { fileElement } = element;
10921
10900
  const fileSize = fileElement.fileSize ?? "0";
@@ -10930,16 +10909,14 @@ async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
10930
10909
  }
10931
10910
  };
10932
10911
  ctx.store.addFileCache({
10933
- peerUid: message.peerUid,
10934
- msgId: message.msgId,
10935
10912
  msgTime: +message.msgTime,
10936
10913
  chatType: message.chatType,
10937
- elementId: element.elementId,
10938
10914
  elementType: element.elementType,
10939
10915
  fileName: fileElement.fileName,
10940
10916
  fileUuid: fileElement.fileUuid,
10941
- fileSize
10942
- }).then();
10917
+ fileSize,
10918
+ md5HexStr: fileElement.fileMd5
10919
+ });
10943
10920
  } else if (element.pttElement) {
10944
10921
  const { pttElement } = element;
10945
10922
  const fileSize = pttElement.fileSize ?? "0";
@@ -10953,16 +10930,14 @@ async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
10953
10930
  }
10954
10931
  };
10955
10932
  ctx.store.addFileCache({
10956
- peerUid: message.peerUid,
10957
- msgId: message.msgId,
10958
10933
  msgTime: +message.msgTime,
10959
10934
  chatType: message.chatType,
10960
- elementId: element.elementId,
10961
10935
  elementType: element.elementType,
10962
10936
  fileName: pttElement.fileName,
10963
10937
  fileUuid: pttElement.fileUuid,
10964
- fileSize
10965
- }).then();
10938
+ fileSize,
10939
+ md5HexStr: pttElement.md5HexStr
10940
+ });
10966
10941
  } else if (element.arkElement) {
10967
10942
  const { arkElement } = element;
10968
10943
  try {
@@ -11081,11 +11056,11 @@ async function transformIncomingSegments$1(ctx, message, rootMsgID, peer) {
11081
11056
  //#region src/onebot11/entities.ts
11082
11057
  var OB11Entities;
11083
11058
  (function(_OB11Entities) {
11084
- async function message(ctx, msg, rootMsgID, peer, config) {
11059
+ async function message(ctx, msg, config) {
11085
11060
  if (!msg.senderUin || msg.senderUin === "0" || msg.msgType === 1) return;
11086
11061
  const selfUin = selfInfo.uin;
11087
11062
  const msgShortId = ctx.store.createMsgShortId(msg);
11088
- const { segments, cqCode } = await transformIncomingSegments$1(ctx, msg, rootMsgID, peer);
11063
+ const { segments, cqCode } = await transformIncomingSegments$1(ctx, msg);
11089
11064
  const resMsg = {
11090
11065
  self_id: Number(selfUin),
11091
11066
  user_id: Number(msg.senderUin),
@@ -11251,16 +11226,16 @@ var OB11Entities;
11251
11226
  _OB11Entities.recallEvent = recallEvent;
11252
11227
  function friend(raw) {
11253
11228
  return {
11254
- user_id: +raw.coreInfo.uin,
11255
- nickname: raw.coreInfo.nick,
11256
- remark: raw.coreInfo.remark || raw.coreInfo.nick,
11257
- sex: sex(raw.baseInfo.sex),
11258
- birthday_year: raw.baseInfo.birthday_year,
11259
- birthday_month: raw.baseInfo.birthday_month,
11260
- birthday_day: raw.baseInfo.birthday_day,
11261
- age: raw.baseInfo.age,
11262
- qid: raw.baseInfo.qid,
11263
- long_nick: raw.baseInfo.longNick
11229
+ user_id: raw.uin,
11230
+ nickname: raw.nick,
11231
+ remark: raw.remark,
11232
+ sex: sex(raw.sex),
11233
+ birthday_year: raw.birthdayYear,
11234
+ birthday_month: raw.birthdayMonth,
11235
+ birthday_day: raw.birthdayDay,
11236
+ age: raw.age,
11237
+ qid: raw.qid,
11238
+ long_nick: raw.longNick
11264
11239
  };
11265
11240
  }
11266
11241
  _OB11Entities.friend = friend;
@@ -11389,7 +11364,7 @@ var OB11HeartbeatEvent = class extends OB11BaseMetaEvent {
11389
11364
  };
11390
11365
  //#endregion
11391
11366
  //#region src/version.ts
11392
- var version$2 = "7.12.11";
11367
+ var version$2 = "7.12.14";
11393
11368
  //#endregion
11394
11369
  //#region node_modules/sift/es5m/index.js
11395
11370
  /******************************************************************************
@@ -12223,7 +12198,6 @@ var OB11WebSocket = class {
12223
12198
  }
12224
12199
  const disposeHeartBeat = this.ctx.interval(() => {
12225
12200
  const event = new OB11HeartbeatEvent(selfInfo.online, true, this.config.heartInterval);
12226
- if (!matchEventFilter(this.config.filter, event)) return;
12227
12201
  this.reply(socket, event);
12228
12202
  }, this.config.heartInterval);
12229
12203
  socket.on("close", () => {
@@ -12346,7 +12320,6 @@ var OB11WebSocketReverse = class {
12346
12320
  const disposeHeartBeat = this.ctx.interval(() => {
12347
12321
  if (this.wsClient) {
12348
12322
  const event = new OB11HeartbeatEvent(selfInfo.online, true, this.config.heartInterval);
12349
- if (!matchEventFilter(this.config.filter, event)) return;
12350
12323
  this.reply(this.wsClient, event);
12351
12324
  }
12352
12325
  }, this.config.heartInterval);
@@ -17049,7 +17022,7 @@ var processQueue = async () => {
17049
17022
  const promises = queue.splice(0, concurrency).map(async ({ filePath, resolve, reject }) => {
17050
17023
  let handle;
17051
17024
  try {
17052
- handle = await fs$5.promises.open(path$4.resolve(filePath), "r");
17025
+ handle = await fs$6.promises.open(path$4.resolve(filePath), "r");
17053
17026
  } catch (err) {
17054
17027
  return reject(err);
17055
17028
  }
@@ -17096,7 +17069,7 @@ function checkUriType(uri) {
17096
17069
  if (uri.startsWith("data:")) return { type: FileUriType.DataURL };
17097
17070
  if (uri.startsWith("http://") || uri.startsWith("https://")) return { type: FileUriType.RemoteURL };
17098
17071
  if (uri.startsWith("file://")) return { type: FileUriType.FileURL };
17099
- if (fs$1.existsSync(uri)) return { type: FileUriType.Path };
17072
+ if (fs$2.existsSync(uri)) return { type: FileUriType.Path };
17100
17073
  return { type: FileUriType.Unknown };
17101
17074
  }
17102
17075
  async function fetchFile(url, headersInit) {
@@ -17126,7 +17099,7 @@ async function uri2local(ctx, uri, needExt) {
17126
17099
  const { type } = checkUriType(uri);
17127
17100
  if (type === FileUriType.FileURL) {
17128
17101
  const filePath = fileURLToPath(uri);
17129
- if (!fs$1.existsSync(filePath)) return {
17102
+ if (!fs$2.existsSync(filePath)) return {
17130
17103
  success: false,
17131
17104
  errMsg: "路径不存在",
17132
17105
  fileName: "",
@@ -17152,12 +17125,12 @@ async function uri2local(ctx, uri, needExt) {
17152
17125
  const res = await fetchFile(uri);
17153
17126
  let fileName = randomUUID();
17154
17127
  let filePath = path.join(TEMP_DIR, fileName);
17155
- await fsPromise.writeFile(filePath, res.data);
17128
+ await fs.writeFile(filePath, res.data);
17156
17129
  if (needExt) {
17157
- const ext = (await ctx.ntFileApi.getFileType(filePath)).ext;
17130
+ const ext = (await getFileType(filePath)).ext;
17158
17131
  fileName += `.${ext}`;
17159
17132
  const newPath = `${filePath}.${ext}`;
17160
- await fsPromise.rename(filePath, newPath);
17133
+ await fs.rename(filePath, newPath);
17161
17134
  filePath = newPath;
17162
17135
  }
17163
17136
  return {
@@ -17180,11 +17153,11 @@ async function uri2local(ctx, uri, needExt) {
17180
17153
  let filename = randomUUID();
17181
17154
  let filePath = path.join(TEMP_DIR, filename);
17182
17155
  const base64 = uri.replace(/^base64:\/\//, "");
17183
- await fsPromise.writeFile(filePath, base64, "base64");
17156
+ await fs.writeFile(filePath, base64, "base64");
17184
17157
  if (needExt) {
17185
- const ext = (await ctx.ntFileApi.getFileType(filePath)).ext;
17158
+ const ext = (await getFileType(filePath)).ext;
17186
17159
  filename += `.${ext}`;
17187
- await fsPromise.rename(filePath, `${filePath}.${ext}`);
17160
+ await fs.rename(filePath, `${filePath}.${ext}`);
17188
17161
  filePath = `${filePath}.${ext}`;
17189
17162
  }
17190
17163
  return {
@@ -17201,11 +17174,11 @@ async function uri2local(ctx, uri, needExt) {
17201
17174
  let filename = randomUUID();
17202
17175
  const [, _type, base64] = capture;
17203
17176
  let filePath = path.join(TEMP_DIR, filename);
17204
- await fsPromise.writeFile(filePath, base64, "base64");
17177
+ await fs.writeFile(filePath, base64, "base64");
17205
17178
  if (needExt) {
17206
- const ext = (await ctx.ntFileApi.getFileType(filePath)).ext;
17179
+ const ext = (await getFileType(filePath)).ext;
17207
17180
  filename += `.${ext}`;
17208
- await fsPromise.rename(filePath, `${filePath}.${ext}`);
17181
+ await fs.rename(filePath, `${filePath}.${ext}`);
17209
17182
  filePath = `${filePath}.${ext}`;
17210
17183
  }
17211
17184
  return {
@@ -17221,13 +17194,20 @@ async function uri2local(ctx, uri, needExt) {
17221
17194
  let fileCache = await ctx.store.getFileCacheById(uri);
17222
17195
  if (!fileCache?.length) fileCache = await ctx.store.getFileCacheByName(uri);
17223
17196
  if (fileCache?.length) {
17224
- const downloadPath = await ctx.ntFileApi.downloadMedia(fileCache[0].msgId, fileCache[0].chatType, fileCache[0].peerUid, fileCache[0].elementId, "", "");
17225
- return {
17226
- success: true,
17227
- errMsg: "",
17228
- fileName: fileCache[0].fileName,
17229
- path: downloadPath,
17230
- isLocal: true
17197
+ const isGroup = fileCache[0].chatType === ChatType.Group;
17198
+ let url;
17199
+ if (fileCache[0].elementType === ElementType.Pic) {
17200
+ const originImageUrl = `/download?appid=${isGroup ? 1407 : 1406}&fileid=${fileCache[0].fileUuid}&spec=0`;
17201
+ url = await ctx.ntFileApi.getImageUrl(originImageUrl, fileCache[0].md5HexStr);
17202
+ } else if (fileCache[0].elementType === ElementType.Video) url = await ctx.ntFileApi.getVideoUrl(fileCache[0].fileUuid, isGroup);
17203
+ else if (fileCache[0].elementType === ElementType.Ptt) url = await ctx.ntFileApi.getPttUrl(fileCache[0].fileUuid, isGroup);
17204
+ if (url) return await uri2local(ctx, url, needExt);
17205
+ else return {
17206
+ success: false,
17207
+ errMsg: `不支持的文件类型: ${fileCache[0].elementType}`,
17208
+ fileName: "",
17209
+ path: "",
17210
+ isLocal: false
17231
17211
  };
17232
17212
  }
17233
17213
  }
@@ -17269,13 +17249,13 @@ function getSha1HexFromBuffer(buf) {
17269
17249
  }
17270
17250
  async function getMd5HexFromFile(filePath) {
17271
17251
  const hash = createHash("md5");
17272
- const stream = fs$1.createReadStream(filePath);
17252
+ const stream = fs$2.createReadStream(filePath);
17273
17253
  for await (const chunk of stream) hash.update(chunk);
17274
17254
  return hash.digest("hex");
17275
17255
  }
17276
17256
  async function getSha1HexFromFile(filePath) {
17277
17257
  const hash = createHash("sha1");
17278
- const stream = fs$1.createReadStream(filePath);
17258
+ const stream = fs$2.createReadStream(filePath);
17279
17259
  for await (const chunk of stream) hash.update(chunk);
17280
17260
  return hash.digest("hex");
17281
17261
  }
@@ -17284,13 +17264,13 @@ function getMd5BufferFromBuffer(buf) {
17284
17264
  }
17285
17265
  async function getMd5BufferFromFile(filePath) {
17286
17266
  const hash = createHash("md5");
17287
- const stream = fs$1.createReadStream(filePath);
17267
+ const stream = fs$2.createReadStream(filePath);
17288
17268
  for await (const chunk of stream) hash.update(chunk);
17289
17269
  return hash.digest();
17290
17270
  }
17291
17271
  async function getSha1BufferFromFile(filePath) {
17292
17272
  const hash = createHash("sha1");
17293
- const stream = fs$1.createReadStream(filePath);
17273
+ const stream = fs$2.createReadStream(filePath);
17294
17274
  for await (const chunk of stream) hash.update(chunk);
17295
17275
  return hash.digest();
17296
17276
  }
@@ -17526,7 +17506,7 @@ async function calculateSha1StreamBytes(filePath) {
17526
17506
  let bytesRead = 0;
17527
17507
  let nextBlockBoundary = blockSize;
17528
17508
  const byteArrayList = [];
17529
- const readable = fs$1.createReadStream(filePath);
17509
+ const readable = fs$2.createReadStream(filePath);
17530
17510
  for await (const chunk of readable) {
17531
17511
  let buf;
17532
17512
  if (tail.length > 0) {
@@ -17551,7 +17531,7 @@ async function calculateSha1StreamBytes(filePath) {
17551
17531
  }
17552
17532
  async function readAndHash10M(filePath) {
17553
17533
  const maxSize = 10002432;
17554
- const fd = await fsPromise.open(filePath, "r");
17534
+ const fd = await fs.open(filePath, "r");
17555
17535
  const buffer = Buffer.allocUnsafe(maxSize);
17556
17536
  const { bytesRead } = await fd.read(buffer, 0, maxSize, 0);
17557
17537
  await fd.close();
@@ -17593,13 +17573,13 @@ var TriSha1 = class {
17593
17573
  };
17594
17574
  async function calculateTriSha1(filePath, fileSize) {
17595
17575
  const hash = new TriSha1(fileSize);
17596
- const stream = fs$1.createReadStream(filePath);
17576
+ const stream = fs$2.createReadStream(filePath);
17597
17577
  for await (const chunk of stream) hash.update(chunk);
17598
17578
  return hash.finalize();
17599
17579
  }
17600
17580
  var defaultVideoThumb = Buffer.from("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", "base64");
17601
17581
  async function getVideoInfo(filePath) {
17602
- const size = fs$1.statSync(filePath).size;
17582
+ const size = fs$2.statSync(filePath).size;
17603
17583
  return new Promise((resolve, reject) => {
17604
17584
  (0, import_fluent_ffmpeg.default)(filePath).ffprobe((err, metadata) => {
17605
17585
  if (err) reject(err);
@@ -17676,7 +17656,7 @@ function convert(ctx, input, options, outputPath) {
17676
17656
  });
17677
17657
  }
17678
17658
  async function encodeSilk(ctx, filePath) {
17679
- const file = await fsPromise.readFile(filePath);
17659
+ const file = await fs.readFile(filePath);
17680
17660
  if (!isSilk(file)) {
17681
17661
  ctx.logger.info(`语音文件${filePath}需要转换成silk`);
17682
17662
  let result;
@@ -17695,7 +17675,7 @@ async function encodeSilk(ctx, filePath) {
17695
17675
  "-f s16le"
17696
17676
  ] }), 24e3);
17697
17677
  const pttPath = path.join(TEMP_DIR, randomUUID());
17698
- await fsPromise.writeFile(pttPath, result.data);
17678
+ await fs.writeFile(pttPath, result.data);
17699
17679
  ctx.logger.info(`语音文件${filePath}转换成功!`, pttPath, `时长:`, result.duration);
17700
17680
  return {
17701
17681
  converted: true,
@@ -17718,11 +17698,11 @@ async function encodeSilk(ctx, filePath) {
17718
17698
  }
17719
17699
  }
17720
17700
  async function decodeSilk(ctx, inputFilePath, outFormat) {
17721
- const { data } = await decode(await fsPromise.readFile(inputFilePath), 24e3);
17701
+ const { data } = await decode(await fs.readFile(inputFilePath), 24e3);
17722
17702
  const tmpPath = path.join(TEMP_DIR, path.basename(inputFilePath));
17723
17703
  const outFilePath = tmpPath + `.${outFormat}`;
17724
17704
  const pcmFilePath = tmpPath + ".pcm";
17725
- await fsPromise.writeFile(pcmFilePath, data);
17705
+ await fs.writeFile(pcmFilePath, data);
17726
17706
  return convert(ctx, pcmFilePath, { input: [
17727
17707
  "-f s16le",
17728
17708
  "-ar 24000",
@@ -17778,16 +17758,17 @@ var SendElement;
17778
17758
  const fileSize = (await stat(picPath)).size;
17779
17759
  if (fileSize === 0) throw new Error(`文件异常,大小为 0: ${picPath}`);
17780
17760
  const { md5, fileName, path } = await ctx.ntFileApi.uploadFile(picPath, ElementType.Pic, subType);
17781
- const imageSize = await ctx.ntFileApi.getImageSize(picPath);
17761
+ const fileType = await getFileType(picPath);
17762
+ const size = await getImageSize(picPath);
17782
17763
  const picElement = {
17783
17764
  md5HexStr: md5,
17784
17765
  fileSize: fileSize.toString(),
17785
- picWidth: imageSize.width,
17786
- picHeight: imageSize.height,
17766
+ picWidth: size.width,
17767
+ picHeight: size.height,
17787
17768
  fileName,
17788
17769
  sourcePath: path,
17789
17770
  original: true,
17790
- picType: imageSize.type === "gif" ? PicType.GIF : PicType.JPEG,
17771
+ picType: fileType.ext === "gif" ? PicType.GIF : PicType.JPEG,
17791
17772
  picSubType: subType,
17792
17773
  fileUuid: "",
17793
17774
  fileSubId: "",
@@ -18068,6 +18049,9 @@ function uint32ToIPV4Addr(value) {
18068
18049
  function sleep(ms = 0) {
18069
18050
  return new Promise((resolve) => setTimeout(resolve, ms));
18070
18051
  }
18052
+ function isHttpUrl(str) {
18053
+ return /^https?:\/\/.+/.test(str);
18054
+ }
18071
18055
  //#endregion
18072
18056
  //#region src/common/utils/sign.ts
18073
18057
  var MusicSign = class {
@@ -18200,7 +18184,7 @@ async function createSendElements(ctx, messageData, peer, ignoreTypes = []) {
18200
18184
  case OB11MessageDataType.Contact:
18201
18185
  {
18202
18186
  const { type, id } = segment.data;
18203
- const data = type === "qq" ? ctx.ntFriendApi.getBuddyRecommendContact(id) : ctx.ntGroupApi.getGroupRecommendContact(id);
18187
+ const data = type === "qq" ? ctx.ntFriendApi.getFriendRecommendContactArk(+id) : ctx.ntGroupApi.getGroupRecommendContact(id);
18204
18188
  sendElements.push(SendElement.ark(await data));
18205
18189
  }
18206
18190
  break;
@@ -18316,7 +18300,7 @@ async function createPeer(ctx, payload, mode = CreatePeerMode.Normal) {
18316
18300
  if ((mode === CreatePeerMode.Private || mode === CreatePeerMode.Normal) && payload.user_id) {
18317
18301
  const uid = await ctx.ntUserApi.getUidByUin(payload.user_id.toString(), payload.group_id?.toString());
18318
18302
  if (!uid) throw new Error("无法获取用户信息");
18319
- if (!await ctx.ntFriendApi.isBuddy(uid)) {
18303
+ if (!await ctx.ntFriendApi.isFriend(uid)) {
18320
18304
  if ((await ctx.ntMsgApi.getTempChatInfo(ChatType.TempC2CFromGroup, uid)).tmpChatInfo.groupCode) return {
18321
18305
  chatType: ChatType.TempC2CFromGroup,
18322
18306
  peerUid: uid,
@@ -18393,12 +18377,8 @@ async function handleMsg(ctx, msg, quickAction) {
18393
18377
  }
18394
18378
  async function handleFriendRequest$1(ctx, request, quickAction) {
18395
18379
  if (!isNullable(quickAction.approve)) {
18396
- const data = request.flag.split("|");
18397
- if (data.length < 2) return;
18398
- const uid = data[0];
18399
- const reqTime = data[1];
18400
- await ctx.ntFriendApi.handleFriendRequest(uid, reqTime, quickAction.approve).catch((e) => ctx.logger.error(e));
18401
- if (!isNullable(quickAction.remark)) ctx.ntFriendApi.setBuddyRemark(uid, quickAction.remark).catch((e) => ctx.logger.error(e));
18380
+ await ctx.ntFriendApi.approvalFriendRequest(request.flag, quickAction.approve).catch((e) => ctx.logger.error(e));
18381
+ if (!isNullable(quickAction.remark)) ctx.ntFriendApi.setBuddyRemark(request.flag, quickAction.remark).catch((e) => ctx.logger.error(e));
18402
18382
  }
18403
18383
  }
18404
18384
  async function handleGroupRequest(ctx, request, quickAction) {
@@ -21236,10 +21216,31 @@ var CloseEvent = globalThis.CloseEvent ?? class extends Event {
21236
21216
  var generateConnectionSymbol = () => Symbol("connection");
21237
21217
  var CONNECTION_SYMBOL_KEY = Symbol("CONNECTION_SYMBOL_KEY");
21238
21218
  var WAIT_FOR_WEBSOCKET_SYMBOL = Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
21239
- var rejectUpgradeRequest = (socket, status) => {
21240
- socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r\nConnection: close\r
21241
- Content-Length: 0\r
21242
- \r
21219
+ var responseHeadersToSkip = new Set([
21220
+ "connection",
21221
+ "content-length",
21222
+ "keep-alive",
21223
+ "proxy-authenticate",
21224
+ "proxy-authorization",
21225
+ "te",
21226
+ "trailer",
21227
+ "transfer-encoding",
21228
+ "upgrade",
21229
+ "sec-websocket-accept",
21230
+ "sec-websocket-extensions",
21231
+ "sec-websocket-protocol"
21232
+ ]);
21233
+ var appendResponseHeaders = (headers, responseHeaders) => {
21234
+ if (!responseHeaders) return;
21235
+ responseHeaders.forEach((value, key) => {
21236
+ if (responseHeadersToSkip.has(key.toLowerCase())) return;
21237
+ headers.push(`${key}: ${value}`);
21238
+ });
21239
+ };
21240
+ var rejectUpgradeRequest = (socket, status, responseHeaders) => {
21241
+ const responseLines = ["Connection: close", "Content-Length: 0"];
21242
+ appendResponseHeaders(responseLines, responseHeaders);
21243
+ socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r\n${responseLines.join("\r\n")}\r\n\r
21243
21244
  `);
21244
21245
  };
21245
21246
  var createUpgradeRequest = (request) => {
@@ -21280,9 +21281,13 @@ var setupWebSocket = (options) => {
21280
21281
  [WAIT_FOR_WEBSOCKET_SYMBOL]: waitForWebSocket
21281
21282
  };
21282
21283
  let status = 400;
21284
+ let responseHeaders;
21283
21285
  try {
21284
21286
  const response = await fetchCallback(createUpgradeRequest(request), env);
21285
- if (response instanceof Response) status = response.status;
21287
+ if (response instanceof Response) {
21288
+ status = response.status;
21289
+ responseHeaders = response.headers;
21290
+ }
21286
21291
  } catch {
21287
21292
  if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
21288
21293
  return;
@@ -21290,12 +21295,20 @@ var setupWebSocket = (options) => {
21290
21295
  const waiter = waiterMap.get(request);
21291
21296
  if (!waiter || waiter.connectionSymbol !== env[CONNECTION_SYMBOL_KEY]) {
21292
21297
  waiterMap.delete(request);
21293
- if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, status);
21298
+ if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, status, responseHeaders);
21294
21299
  return;
21295
21300
  }
21296
- wss.handleUpgrade(request, socket, head, (ws) => {
21297
- wss.emit("connection", ws, request);
21298
- });
21301
+ const addResponseHeaders = (headers) => {
21302
+ appendResponseHeaders(headers, responseHeaders);
21303
+ };
21304
+ wss.on("headers", addResponseHeaders);
21305
+ try {
21306
+ wss.handleUpgrade(request, socket, head, (ws) => {
21307
+ wss.emit("connection", ws, request);
21308
+ });
21309
+ } finally {
21310
+ wss.off("headers", addResponseHeaders);
21311
+ }
21299
21312
  });
21300
21313
  server.on("close", () => {
21301
21314
  wss.close();
@@ -21775,7 +21788,7 @@ var GetMsg = class extends BaseAction {
21775
21788
  status = "deleted";
21776
21789
  }
21777
21790
  } else msg = res.msgList[0];
21778
- const retMsg = await OB11Entities.message(this.ctx, msg, void 0, void 0, config);
21791
+ const retMsg = await OB11Entities.message(this.ctx, msg, config);
21779
21792
  if (!retMsg) throw new Error("消息为空");
21780
21793
  retMsg.real_id = retMsg.message_seq;
21781
21794
  retMsg.status = status;
@@ -21804,8 +21817,8 @@ var GetLoginInfo$1 = class extends BaseAction {
21804
21817
  var GetFriendList$1 = class extends BaseAction {
21805
21818
  actionName = ActionName.GetFriendList;
21806
21819
  async _handle() {
21807
- const buddyList = await this.ctx.ntFriendApi.getBuddyList();
21808
- return OB11Entities.friends(buddyList);
21820
+ const result = await this.ctx.ntFriendApi.getFriendList(true);
21821
+ return OB11Entities.friends(result.friends);
21809
21822
  }
21810
21823
  };
21811
21824
  //#endregion
@@ -23671,6 +23684,103 @@ var Oidb;
23671
23684
  allFileCount: ProtoField(7, "uint32"),
23672
23685
  nextIndex: ProtoField(13, "uint32")
23673
23686
  }) });
23687
+ _Oidb.ImageOcrReq = ProtoMessage.of({
23688
+ version: ProtoField(1, "uint32"),
23689
+ client: ProtoField(2, "uint32"),
23690
+ entrance: ProtoField(3, "uint32"),
23691
+ ocrReqBody: ProtoField(10, {
23692
+ imageUrl: ProtoField(1, "string"),
23693
+ languageType: ProtoField(2, "uint32"),
23694
+ scene: ProtoField(3, "uint32"),
23695
+ originMd5: ProtoField(10, "string"),
23696
+ afterCompressMd5: ProtoField(11, "string"),
23697
+ afterCompressFileSize: ProtoField(12, "string"),
23698
+ afterCompressWeight: ProtoField(13, "string"),
23699
+ afterCompressHeight: ProtoField(14, "string"),
23700
+ isCut: ProtoField(15, "bool")
23701
+ })
23702
+ });
23703
+ _Oidb.ImageOcrResp = ProtoMessage.of({
23704
+ retCode: ProtoField(1, "int32", "optional"),
23705
+ errMsg: ProtoField(2, "string"),
23706
+ wording: ProtoField(3, "string", "optional"),
23707
+ ocrRspBody: ProtoField(10, {
23708
+ textDetections: ProtoField(1, {
23709
+ detectedText: ProtoField(1, "string"),
23710
+ confidence: ProtoField(2, "uint32"),
23711
+ polygon: ProtoField(3, { coordinates: ProtoField(1, {
23712
+ x: ProtoField(1, "int32"),
23713
+ y: ProtoField(2, "int32")
23714
+ }, "repeated") }),
23715
+ advancedInfo: ProtoField(4, "string")
23716
+ }, "repeated"),
23717
+ language: ProtoField(2, "string"),
23718
+ requestId: ProtoField(3, "string"),
23719
+ ocrLanguageList: ProtoField(101, "string", "repeated"),
23720
+ dstTranslateLanguageList: ProtoField(102, "string", "repeated"),
23721
+ languageList: ProtoField(103, {
23722
+ languageCode: ProtoField(1, "string"),
23723
+ languageDesc: ProtoField(2, "string")
23724
+ }, "repeated"),
23725
+ afterCompressWeight: ProtoField(111, "uint32"),
23726
+ afterCompressHeight: ProtoField(112, "uint32")
23727
+ })
23728
+ });
23729
+ _Oidb.SetFriendRequestReq = ProtoMessage.of({
23730
+ accept: ProtoField(1, "uint32"),
23731
+ targetUid: ProtoField(2, "string")
23732
+ });
23733
+ _Oidb.SetFilteredFriendRequestReq = ProtoMessage.of({
23734
+ selfUid: ProtoField(1, "string"),
23735
+ requestUid: ProtoField(2, "string")
23736
+ });
23737
+ _Oidb.IncPullReq = ProtoMessage.of({
23738
+ reqCount: ProtoField(2, "uint32"),
23739
+ time: ProtoField(3, "uint32"),
23740
+ localSeq: ProtoField(4, "uint32"),
23741
+ cookie: ProtoField(5, "bytes", "optional"),
23742
+ flag: ProtoField(6, "int32"),
23743
+ proxySeq: ProtoField(7, "uint32"),
23744
+ requestBiz: ProtoField(10001, {
23745
+ bizType: ProtoField(1, "int32"),
23746
+ bizData: ProtoField(2, { extBusi: ProtoField(1, "int32", "repeated") })
23747
+ }, "repeated"),
23748
+ extSnsFlagKey: ProtoField(10002, "uint32", "repeated"),
23749
+ extPrivateIdListKey: ProtoField(10003, "uint32", "repeated")
23750
+ });
23751
+ _Oidb.IncPullResp = ProtoMessage.of({
23752
+ seq: ProtoField(1, "uint32"),
23753
+ cookie: ProtoField(2, "bytes", "optional"),
23754
+ isEnd: ProtoField(3, "bool"),
23755
+ time: ProtoField(6, "uint32"),
23756
+ selfUin: ProtoField(7, "uint32"),
23757
+ smallSeq: ProtoField(8, "uint32"),
23758
+ friendList: ProtoField(101, {
23759
+ uid: ProtoField(1, "string"),
23760
+ categoryId: ProtoField(2, "int32"),
23761
+ uin: ProtoField(3, "uint32"),
23762
+ subBiz: ProtoField(10001, ["int32", {
23763
+ numData: ProtoField(1, ["int32", "int32"]),
23764
+ data: ProtoField(2, ["int32", "bytes"])
23765
+ }])
23766
+ }, "repeated"),
23767
+ category: ProtoField(102, {
23768
+ categoryId: ProtoField(1, "int32"),
23769
+ categoryName: ProtoField(2, "string"),
23770
+ categoryMemberCount: ProtoField(3, "int32"),
23771
+ categorySortId: ProtoField(4, "int32")
23772
+ }, "repeated")
23773
+ });
23774
+ _Oidb.FetchPinsResp = ProtoMessage.of({
23775
+ friends: ProtoField(1, { uid: ProtoField(1, "string") }, "repeated"),
23776
+ groups: ProtoField(3, { groupCode: ProtoField(1, "uint32") }, "repeated")
23777
+ });
23778
+ _Oidb.GetFriendRecommendContactArkReq = ProtoMessage.of({
23779
+ uin: ProtoField(1, "uint32"),
23780
+ phoneNumber: ProtoField(2, "string"),
23781
+ jumpUrl: ProtoField(3, "string")
23782
+ });
23783
+ _Oidb.GetFriendRecommendContactArkResp = ProtoMessage.of({ ark: ProtoField(1, "string") });
23674
23784
  })(Oidb || (Oidb = {}));
23675
23785
  //#endregion
23676
23786
  //#region src/ntqqapi/proto/msg.ts
@@ -23958,53 +24068,10 @@ var MessageEncoder$1 = class MessageEncoder$1 {
23958
24068
  this.content = void 0;
23959
24069
  this.preview = "";
23960
24070
  }
23961
- async packImage(data, busiType) {
23962
- const imageSize = await this.ctx.ntFileApi.getImageSize(data.filePath);
24071
+ async packImage(msgInfo) {
23963
24072
  return { commonElem: {
23964
24073
  serviceType: 48,
23965
- pbElem: Media.MsgInfo.encode({
23966
- msgInfoBody: [{
23967
- index: {
23968
- info: {
23969
- fileSize: +data.commonFileInfo.fileSize,
23970
- md5HexStr: data.commonFileInfo.md5,
23971
- sha1HexStr: data.commonFileInfo.sha,
23972
- fileName: data.commonFileInfo.fileName,
23973
- fileType: {
23974
- type: 1,
23975
- picFormat: imageSize.type === "gif" ? 2e3 : 1e3
23976
- },
23977
- width: imageSize.width,
23978
- height: imageSize.height,
23979
- time: 0,
23980
- original: 1
23981
- },
23982
- fileUuid: data.fileId,
23983
- storeID: 1,
23984
- expire: this.isGroup ? 2678400 : 15768e4
23985
- },
23986
- pic: {
23987
- urlPath: `/download?appid=${this.isGroup ? 1407 : 1406}&fileid=${data.fileId}`,
23988
- ext: {
23989
- originalParam: "&spec=0",
23990
- bigParam: "&spec=720",
23991
- thumbParam: "&spec=198"
23992
- },
23993
- domain: "multimedia.nt.qq.com.cn"
23994
- },
23995
- fileExist: true
23996
- }],
23997
- extBizInfo: {
23998
- pic: {
23999
- bizType: 0,
24000
- summary: "",
24001
- fromScene: this.isGroup ? 2 : 1,
24002
- toScene: this.isGroup ? 2 : 1,
24003
- oldFileId: this.isGroup ? 574859779 : void 0
24004
- },
24005
- busiType
24006
- }
24007
- }),
24074
+ pbElem: Media.MsgInfo.encode(msgInfo),
24008
24075
  businessType: this.isGroup ? 20 : 10
24009
24076
  } };
24010
24077
  }
@@ -24086,11 +24153,11 @@ var MessageEncoder$1 = class MessageEncoder$1 {
24086
24153
  const busiType = Number(segment.data.subType) || 0;
24087
24154
  const { path: picPath } = await handleOb11RichMedia(this.ctx, segment, this.deleteAfterSentFiles);
24088
24155
  if ((await stat(picPath)).size === 0) throw new Error(`文件异常,大小为 0: ${picPath}`);
24089
- const { path } = await this.ctx.ntFileApi.uploadFile(picPath, ElementType.Pic, busiType);
24090
- const data = await this.ctx.ntFileApi.uploadRMFileWithoutMsg(path, this.isGroup ? 4 : 3, this.isGroup ? this.peer.peerUid : selfInfo.uid);
24091
- this.children.push(await this.packImage(data, busiType));
24156
+ let data;
24157
+ if (this.isGroup) data = await this.ctx.ntFileApi.uploadGroupImage(this.peer.peerUid, picPath);
24158
+ else data = await this.ctx.ntFileApi.uploadC2CImage(this.peer.peerUid, picPath);
24159
+ this.children.push(await this.packImage(data.msgInfo));
24092
24160
  this.preview += busiType === 1 ? "[动画表情]" : "[图片]";
24093
- this.deleteAfterSentFiles.push(path);
24094
24161
  } else if (type === OB11MessageDataType.Forward) {
24095
24162
  const forwardData = data;
24096
24163
  if (forwardData.id) this.children.push(this.packForwardMessage(forwardData.id, void 0, forwardData));
@@ -24609,14 +24676,9 @@ var SetFriendAddRequest = class extends BaseAction {
24609
24676
  remark: lib_default$1.string()
24610
24677
  });
24611
24678
  async _handle(payload) {
24612
- const data = payload.flag.split("|");
24613
- if (data.length < 2) throw new Error("无效的flag");
24614
- const uid = data[0];
24615
- const reqTime = data[1];
24616
- const res = await this.ctx.ntFriendApi.handleFriendRequest(uid, reqTime, payload.approve);
24617
- if (res.result !== 0) throw new Error(res.errMsg);
24679
+ await this.ctx.ntFriendApi.approvalFriendRequest(payload.flag, payload.approve);
24618
24680
  if (payload.remark) {
24619
- const res = await this.ctx.ntFriendApi.setBuddyRemark(uid, payload.remark);
24681
+ const res = await this.ctx.ntFriendApi.setBuddyRemark(payload.flag, payload.remark);
24620
24682
  if (res.result !== 0) throw new Error(res.errMsg);
24621
24683
  }
24622
24684
  return null;
@@ -24742,26 +24804,23 @@ var GetFileBase = class extends BaseAction {
24742
24804
  if (!fileCache?.length) fileCache = await this.ctx.store.getFileCacheByName(payload.file);
24743
24805
  if (fileCache?.length) {
24744
24806
  let downloadPath = "";
24745
- if (payload.download) downloadPath = await this.ctx.ntFileApi.downloadMedia(fileCache[0].msgId, fileCache[0].chatType, fileCache[0].peerUid, fileCache[0].elementId, "", "");
24807
+ if (payload.download) {
24808
+ const file = await uri2local(this.ctx, fileCache[0].fileUuid, true);
24809
+ if (file.errMsg) throw new Error(file.errMsg);
24810
+ downloadPath = file.path;
24811
+ }
24746
24812
  const res = {
24747
24813
  file: downloadPath,
24748
24814
  url: "",
24749
24815
  file_size: fileCache[0].fileSize,
24750
24816
  file_name: fileCache[0].fileName
24751
24817
  };
24752
- const peer = {
24753
- chatType: fileCache[0].chatType,
24754
- peerUid: fileCache[0].peerUid,
24755
- guildId: ""
24756
- };
24818
+ const isGroup = fileCache[0].chatType === ChatType.Group;
24757
24819
  if (fileCache[0].elementType === ElementType.Pic) {
24758
- const msgList = await this.ctx.ntMsgApi.getMsgsByMsgId(peer, [fileCache[0].msgId]);
24759
- if (msgList.msgList.length === 0) throw new Error("msg not found");
24760
- const findEle = msgList.msgList[0].elements.find((e) => e.elementId === fileCache[0].elementId);
24761
- if (!findEle) throw new Error("element not found");
24762
- res.url = await this.ctx.ntFileApi.getImageUrl(findEle.picElement);
24763
- } else if (fileCache[0].elementType === ElementType.Video) res.url = await this.ctx.ntFileApi.getVideoUrl(peer, fileCache[0].msgId, fileCache[0].elementId);
24764
- else if (fileCache[0].elementType === ElementType.Ptt) res.url = await this.ctx.ntFileApi.getPttUrl(fileCache[0].fileUuid, peer.chatType === 2);
24820
+ const originImageUrl = `/download?appid=${isGroup ? 1407 : 1406}&fileid=${fileCache[0].fileUuid}&spec=0`;
24821
+ res.url = await this.ctx.ntFileApi.getImageUrl(originImageUrl, fileCache[0].md5HexStr);
24822
+ } else if (fileCache[0].elementType === ElementType.Video) res.url = await this.ctx.ntFileApi.getVideoUrl(fileCache[0].fileUuid, isGroup);
24823
+ else if (fileCache[0].elementType === ElementType.Ptt) res.url = await this.ctx.ntFileApi.getPttUrl(fileCache[0].fileUuid, isGroup);
24765
24824
  if (enableLocalFile2Url && downloadPath && (res.file === res.url || res.url === void 0)) try {
24766
24825
  res.base64 = await readFile(downloadPath, "base64");
24767
24826
  } catch (e) {
@@ -24809,8 +24868,9 @@ var GetRecord = class extends BaseAction {
24809
24868
  async _handle(payload) {
24810
24869
  const fileCache = await this.ctx.store.getFileCacheByName(payload.file);
24811
24870
  if (fileCache?.length) {
24812
- const downloadPath = await this.ctx.ntFileApi.downloadMedia(fileCache[0].msgId, fileCache[0].chatType, fileCache[0].peerUid, fileCache[0].elementId, "", "");
24813
- const file = await decodeSilk(this.ctx, downloadPath, payload.out_format);
24871
+ const originFile = await uri2local(this.ctx, fileCache[0].fileUuid, true);
24872
+ if (originFile.errMsg) throw new Error(originFile.errMsg);
24873
+ const file = await decodeSilk(this.ctx, originFile.path, payload.out_format);
24814
24874
  const res = {
24815
24875
  file,
24816
24876
  file_name: path.basename(file),
@@ -24909,17 +24969,17 @@ var DownloadFile = class extends BaseAction {
24909
24969
  const isRandomName = !payload.name;
24910
24970
  const name = payload.name ? path.basename(payload.name) : randomUUID();
24911
24971
  const filePath = path.join(TEMP_DIR, name);
24912
- if (payload.base64) await fsPromise$1.writeFile(filePath, payload.base64, "base64");
24972
+ if (payload.base64) await fsPromise.writeFile(filePath, payload.base64, "base64");
24913
24973
  else if (payload.url) {
24914
24974
  const headers = this.getHeaders(payload.headers);
24915
24975
  const res = await fetchFile(payload.url, headers);
24916
- await fsPromise$1.writeFile(filePath, res.data);
24976
+ await fsPromise.writeFile(filePath, res.data);
24917
24977
  } else throw new Error("不存在任何文件, 无法下载");
24918
- if (fs.existsSync(filePath)) {
24978
+ if (fs$1.existsSync(filePath)) {
24919
24979
  if (isRandomName) {
24920
24980
  const md5 = await getMd5HexFromFile(filePath);
24921
24981
  const newPath = path.join(TEMP_DIR, md5);
24922
- await fsPromise$1.rename(filePath, newPath);
24982
+ await fsPromise.rename(filePath, newPath);
24923
24983
  return { file: newPath };
24924
24984
  }
24925
24985
  return { file: filePath };
@@ -24962,7 +25022,7 @@ var GetGroupMsgHistory = class extends BaseAction {
24962
25022
  const msg = this.ctx.store.getMsgCache(rawMsg.msgId);
24963
25023
  if (msg) rawMsg = msg;
24964
25024
  }
24965
- return OB11Entities.message(this.ctx, rawMsg, void 0, void 0, config);
25025
+ return OB11Entities.message(this.ctx, rawMsg, config);
24966
25026
  }))),
24967
25027
  seq: +msgList[0].msgSeq
24968
25028
  };
@@ -24999,24 +25059,40 @@ async function decodeMultiMessage(ctx, items, messageFormat) {
24999
25059
  type: OB11MessageDataType.Text,
25000
25060
  data: { text: element.text.str }
25001
25061
  };
25002
- else if (element.commonElem && element.commonElem.serviceType === 48) {
25003
- const richMediaInfo = Media.MsgInfo.decode(element.commonElem.pbElem);
25004
- const infoBody = richMediaInfo.msgInfoBody[0];
25005
- const parsedUrl = new URL("https://" + infoBody.pic.domain + infoBody.pic.urlPath + infoBody.pic.ext.originalParam);
25006
- const imageAppid = parsedUrl.searchParams.get("appid");
25007
- const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey();
25008
- const url = parsedUrl.href + (imageAppid === "1406" ? rkeyData.private_rkey : rkeyData.group_rkey);
25009
- const { info } = richMediaInfo.msgInfoBody[0].index;
25010
- const { pic } = richMediaInfo.extBizInfo;
25011
- segment = {
25012
- type: OB11MessageDataType.Image,
25013
- data: {
25014
- file: info.fileName,
25015
- subType: pic.bizType,
25016
- url,
25017
- file_size: info.fileSize.toString()
25018
- }
25019
- };
25062
+ else if (element.commonElem) {
25063
+ const { businessType, serviceType, pbElem } = element.commonElem;
25064
+ if (serviceType === 48 && (businessType === 10 || businessType === 20)) {
25065
+ const richMediaInfo = Media.MsgInfo.decode(pbElem);
25066
+ const infoBody = richMediaInfo.msgInfoBody[0];
25067
+ const parsedUrl = new URL("https://" + infoBody.pic.domain + infoBody.pic.urlPath + infoBody.pic.ext.originalParam);
25068
+ const imageAppid = parsedUrl.searchParams.get("appid");
25069
+ const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey();
25070
+ const url = parsedUrl.href + (imageAppid === "1406" ? rkeyData.private_rkey : rkeyData.group_rkey);
25071
+ const { info } = richMediaInfo.msgInfoBody[0].index;
25072
+ const { pic } = richMediaInfo.extBizInfo;
25073
+ segment = {
25074
+ type: OB11MessageDataType.Image,
25075
+ data: {
25076
+ file: info.fileName,
25077
+ subType: pic.bizType,
25078
+ url,
25079
+ file_size: info.fileSize.toString()
25080
+ }
25081
+ };
25082
+ } else if (serviceType === 48 && (businessType === 11 || businessType === 21)) {
25083
+ const { msgInfoBody } = Media.MsgInfo.decode(pbElem);
25084
+ const { index } = msgInfoBody[0];
25085
+ const url = await ctx.ntFileApi.getVideoUrl(index.fileUuid, businessType === 21);
25086
+ segment = {
25087
+ type: OB11MessageDataType.Video,
25088
+ data: {
25089
+ file: index.info.fileName,
25090
+ url,
25091
+ path: "",
25092
+ file_size: index.info.fileSize.toString()
25093
+ }
25094
+ };
25095
+ }
25020
25096
  }
25021
25097
  if (segment) if (typeof content === "string") content += encodeCQCode(segment);
25022
25098
  else content.push(segment);
@@ -25073,7 +25149,7 @@ var GetForwardMsg = class extends BaseAction {
25073
25149
  throw new Error(data.errMsg);
25074
25150
  }
25075
25151
  return { messages: filterNullable(await Promise.all(data.msgList.map(async (msg) => {
25076
- const res = await OB11Entities.message(this.ctx, msg, rootMsgId, peer, config);
25152
+ const res = await OB11Entities.message(this.ctx, msg, config);
25077
25153
  if (res) {
25078
25154
  const segments = message2List(res.message);
25079
25155
  for (const item of segments) if (item.type === OB11MessageDataType.Forward) this.ctx.store.addMultiMsgInfo(rootMsgId, item.data.id, peer);
@@ -25523,7 +25599,7 @@ var GetFriendMsgHistory = class extends BaseAction {
25523
25599
  const msg = this.ctx.store.getMsgCache(rawMsg.msgId);
25524
25600
  if (msg) rawMsg = msg;
25525
25601
  }
25526
- return OB11Entities.message(this.ctx, rawMsg, void 0, void 0, config);
25602
+ return OB11Entities.message(this.ctx, rawMsg, config);
25527
25603
  }))),
25528
25604
  seq: +msgList[0].msgSeq
25529
25605
  };
@@ -25532,7 +25608,7 @@ var GetFriendMsgHistory = class extends BaseAction {
25532
25608
  const uid = await this.ctx.ntUserApi.getUidByUin(payload.user_id.toString());
25533
25609
  if (!uid) throw new Error(`无法获取用户信息`);
25534
25610
  const peer = {
25535
- chatType: await this.ctx.ntFriendApi.isBuddy(uid) ? ChatType.C2C : ChatType.TempC2CFromGroup,
25611
+ chatType: await this.ctx.ntFriendApi.isFriend(uid) ? ChatType.C2C : ChatType.TempC2CFromGroup,
25536
25612
  peerUid: uid,
25537
25613
  guildId: ""
25538
25614
  };
@@ -25595,32 +25671,16 @@ var GetGroupFilesByFolder = class extends BaseAction {
25595
25671
  var GetFriendWithCategory = class extends BaseAction {
25596
25672
  actionName = ActionName.GetFriendsWithCategory;
25597
25673
  async _handle() {
25598
- const res = await this.ctx.ntFriendApi.getBuddyV2(true);
25599
- if (res.result !== 0) throw new Error(res.errMsg);
25600
- const buddyList = await this.ctx.ntFriendApi.getBuddyList();
25601
- const buddyMap = /* @__PURE__ */ new Map();
25602
- for (const buddy of buddyList) buddyMap.set(buddy.uid, buddy);
25603
- const category = [];
25604
- for (const item of res.data) {
25605
- const buddyList = [];
25606
- for (const uid of item.buddyUids) buddyList.push(buddyMap.get(uid));
25607
- category.push({
25608
- ...item,
25609
- buddyList
25610
- });
25611
- }
25612
- return category.map((item) => {
25613
- return {
25614
- categoryId: item.categoryId,
25615
- categorySortId: item.categorySortId,
25616
- categoryName: item.categroyName,
25617
- categoryMbCount: item.categroyMbCount,
25618
- onlineCount: item.onlineCount,
25619
- buddyList: item.buddyList.map((buddy) => {
25620
- return OB11Entities.friend(buddy);
25621
- })
25622
- };
25623
- });
25674
+ const result = await this.ctx.ntFriendApi.getFriendList(true);
25675
+ return result.categories.values().map((item) => ({
25676
+ categoryId: item.categoryId,
25677
+ categorySortId: item.categorySortId,
25678
+ categoryName: item.categoryName,
25679
+ categoryMbCount: item.categoryMemberCount,
25680
+ buddyList: result.friends.filter((friend) => friend.categoryId === item.categoryId).map((friend) => {
25681
+ return OB11Entities.friend(friend);
25682
+ })
25683
+ })).toArray();
25624
25684
  }
25625
25685
  };
25626
25686
  //#endregion
@@ -25778,29 +25838,24 @@ var OCRImage = class extends BaseAction {
25778
25838
  actionName = ActionName.GoCQHTTP_OCRImage;
25779
25839
  payloadSchema = lib_default$1.object({ image: lib_default$1.string().required() });
25780
25840
  async _handle(payload) {
25781
- const { errMsg, isLocal, path, success } = await uri2local(this.ctx, payload.image, true);
25782
- if (!success) throw new Error(errMsg);
25783
- await access(path);
25784
- const data = await this.ctx.ntFileApi.ocrImage(path);
25785
- if (!isLocal) unlink(path).catch(noop);
25786
- if (data.code !== 0) throw new Error(data.errMsg);
25841
+ let url;
25842
+ if (isHttpUrl(payload.image)) url = payload.image;
25843
+ else {
25844
+ const { errMsg, isLocal, path, success } = await uri2local(this.ctx, payload.image);
25845
+ if (!success) throw new Error(errMsg);
25846
+ const { msgInfo } = await this.ctx.ntFileApi.uploadC2CImage(selfInfo.uid, path);
25847
+ if (!isLocal) unlink(path).catch(noop);
25848
+ const { pic, index } = msgInfo.msgInfoBody[0];
25849
+ url = await this.ctx.ntFileApi.getImageUrl(pic.urlPath + pic.ext.originalParam, index.info.md5HexStr);
25850
+ }
25851
+ const { textDetections, language } = await this.ctx.ntFileApi.ocrImage(url);
25787
25852
  return {
25788
- texts: data.result.map((item) => {
25789
- const ret = {
25790
- text: item.text,
25791
- confidence: 1,
25792
- coordinates: []
25793
- };
25794
- for (let i = 0; i < 4; i++) {
25795
- const pt = item[`pt${i + 1}`];
25796
- ret.coordinates.push({
25797
- x: +pt.x,
25798
- y: +pt.y
25799
- });
25800
- }
25801
- return ret;
25802
- }),
25803
- language: ""
25853
+ texts: textDetections.map((item) => ({
25854
+ text: item.detectedText,
25855
+ confidence: item.confidence,
25856
+ coordinates: item.polygon.coordinates
25857
+ })),
25858
+ language
25804
25859
  };
25805
25860
  }
25806
25861
  };
@@ -26469,8 +26524,7 @@ var SetDoubtFriendsAddRequest = class extends BaseAction {
26469
26524
  actionName = ActionName.SetDoubtFriendsAddRequest;
26470
26525
  payloadSchema = lib_default$1.object({ flag: lib_default$1.string().required() });
26471
26526
  async _handle(payload) {
26472
- const res = await this.ctx.ntFriendApi.approvalDoubtBuddyReq(payload.flag);
26473
- if (res.result !== 0) throw new Error(res.errMsg);
26527
+ await this.ctx.ntFriendApi.approvalDoubtFriendRequest(payload.flag);
26474
26528
  return null;
26475
26529
  }
26476
26530
  };
@@ -26914,7 +26968,6 @@ var Onebot11Adapter = class extends Service {
26914
26968
  static inject = [
26915
26969
  "ntMsgApi",
26916
26970
  "ntFileApi",
26917
- "ntFileCacheApi",
26918
26971
  "ntFriendApi",
26919
26972
  "ntGroupApi",
26920
26973
  "ntUserApi",
@@ -27049,7 +27102,7 @@ var Onebot11Adapter = class extends Service {
27049
27102
  }
27050
27103
  async handleFriendRequest(req) {
27051
27104
  const uin = await this.ctx.ntUserApi.getUinByUid(req.friendUid);
27052
- const flag = req.friendUid + "|" + req.reqTime;
27105
+ const flag = req.friendUid;
27053
27106
  const friendRequestEvent = new OB11FriendRequestEvent(+uin, req.extWords, flag, req.addSource ?? "");
27054
27107
  this.dispatch(friendRequestEvent);
27055
27108
  }
@@ -27999,10 +28052,10 @@ var robotUinRanges = [
27999
28052
  ];
28000
28053
  function decodeUser(user) {
28001
28054
  return {
28002
- id: user.uin,
28055
+ id: user.uin.toString(),
28003
28056
  name: user.nick,
28004
28057
  avatar: `http://q.qlogo.cn/headimg_dl?dst_uin=${user.uin}&spec=640`,
28005
- is_bot: robotUinRanges.some((e) => user.uin >= e.minUin && user.uin <= e.maxUin)
28058
+ is_bot: robotUinRanges.some((e) => +user.uin >= +e.minUin && +user.uin <= +e.maxUin)
28006
28059
  };
28007
28060
  }
28008
28061
  function decodeGuildChannelId(data) {
@@ -28045,7 +28098,7 @@ async function decodeElement(ctx, data, quoted = false) {
28045
28098
  ctx.logger.error("获取不到引用的消息", e, v.replyElement, e.stack);
28046
28099
  }
28047
28100
  } else if (v.picElement) {
28048
- const src = await ctx.ntFileApi.getImageUrl(v.picElement);
28101
+ const src = await ctx.ntFileApi.getImageUrl(v.picElement.originImageUrl, v.picElement.md5HexStr);
28049
28102
  buffer.push(lib_default.img(src, {
28050
28103
  width: v.picElement.picWidth,
28051
28104
  height: v.picElement.picHeight,
@@ -28055,11 +28108,7 @@ async function decodeElement(ctx, data, quoted = false) {
28055
28108
  const src = await ctx.ntFileApi.getPttUrl(v.pttElement.fileUuid, data.chatType === ChatType.Group);
28056
28109
  buffer.push(lib_default.audio(src, { duration: v.pttElement.duration }));
28057
28110
  } else if (v.videoElement) {
28058
- const src = await ctx.ntFileApi.getVideoUrl({
28059
- chatType: data.chatType,
28060
- peerUid: data.peerUid,
28061
- guildId: ""
28062
- }, data.msgId, v.elementId) || pathToFileURL(v.videoElement.filePath).href;
28111
+ const src = await ctx.ntFileApi.getVideoUrl(v.videoElement.fileUuid, data.chatType === ChatType.Group);
28063
28112
  buffer.push(lib_default.video(src));
28064
28113
  } else if (v.marketFaceElement) {
28065
28114
  const { emojiId, supportSize } = v.marketFaceElement;
@@ -28152,7 +28201,7 @@ async function getPeer(ctx, channelId) {
28152
28201
  const uin = channelId.replace("private:", "");
28153
28202
  const uid = await ctx.ntUserApi.getUidByUin(uin);
28154
28203
  if (!uid) throw new Error("无法获取用户信息");
28155
- if (!await ctx.ntFriendApi.isBuddy(uid)) {
28204
+ if (!await ctx.ntFriendApi.isFriend(uid)) {
28156
28205
  if ((await ctx.ntMsgApi.getTempChatInfo(ChatType.TempC2CFromGroup, uid)).tmpChatInfo.groupCode) return {
28157
28206
  chatType: ChatType.TempC2CFromGroup,
28158
28207
  peerUid: uid,
@@ -28658,53 +28707,13 @@ async function ntToProto(ctx, input, peer) {
28658
28707
  else if (input.elementType === ElementType.Pic) {
28659
28708
  const isGroup = peer.chatType === ChatType.Group;
28660
28709
  const path = input.picElement.sourcePath;
28661
- const data = await ctx.ntFileApi.uploadRMFileWithoutMsg(path, isGroup ? 4 : 3, peer.peerUid);
28710
+ let data;
28711
+ if (isGroup) data = await ctx.ntFileApi.uploadGroupImage(peer.peerUid, path);
28712
+ else data = await ctx.ntFileApi.uploadC2CImage(peer.peerUid, path);
28662
28713
  return {
28663
28714
  element: { commonElem: {
28664
28715
  serviceType: 48,
28665
- pbElem: Media.MsgInfo.encode({
28666
- msgInfoBody: [{
28667
- index: {
28668
- info: {
28669
- fileSize: +data.commonFileInfo.fileSize,
28670
- md5HexStr: data.commonFileInfo.md5,
28671
- sha1HexStr: data.commonFileInfo.sha,
28672
- fileName: data.commonFileInfo.fileName,
28673
- fileType: {
28674
- type: 1,
28675
- picFormat: input.picElement.picType
28676
- },
28677
- width: input.picElement.picWidth,
28678
- height: input.picElement.picHeight,
28679
- time: 0,
28680
- original: 1
28681
- },
28682
- fileUuid: data.fileId,
28683
- storeID: 1,
28684
- expire: isGroup ? 2678400 : 15768e4
28685
- },
28686
- pic: {
28687
- urlPath: `/download?appid=${isGroup ? 1407 : 1406}&fileid=${data.fileId}`,
28688
- ext: {
28689
- originalParam: "&spec=0",
28690
- bigParam: "&spec=720",
28691
- thumbParam: "&spec=198"
28692
- },
28693
- domain: "multimedia.nt.qq.com.cn"
28694
- },
28695
- fileExist: true
28696
- }],
28697
- extBizInfo: {
28698
- pic: {
28699
- bizType: 0,
28700
- summary: "",
28701
- fromScene: isGroup ? 2 : 1,
28702
- toScene: isGroup ? 2 : 1,
28703
- oldFileId: isGroup ? 574859779 : void 0
28704
- },
28705
- busiType: input.picElement.picSubType
28706
- }
28707
- }),
28716
+ pbElem: Media.MsgInfo.encode(data.msgInfo),
28708
28717
  businessType: isGroup ? 20 : 10
28709
28718
  } },
28710
28719
  preview: input.picElement.picSubType === 1 ? "[动画表情]" : "[图片]"
@@ -28884,20 +28893,15 @@ var getUser = async (ctx, payload) => {
28884
28893
  //#endregion
28885
28894
  //#region src/satori/api/friend/list.ts
28886
28895
  var getFriendList = async (ctx) => {
28887
- return { data: (await ctx.ntFriendApi.getBuddyList()).map((e) => ({
28888
- user: decodeUser(e.coreInfo),
28889
- nick: e.coreInfo.remark
28896
+ return { data: (await ctx.ntFriendApi.getFriendList(true)).friends.map((e) => ({
28897
+ user: decodeUser(e),
28898
+ nick: e.remark
28890
28899
  })) };
28891
28900
  };
28892
28901
  //#endregion
28893
28902
  //#region src/satori/api/friend/approve.ts
28894
28903
  var handleFriendRequest = async (ctx, payload) => {
28895
- const data = payload.message_id.split("|");
28896
- if (data.length < 2) throw new Error("无效的 message_id");
28897
- const uid = data[0];
28898
- const reqTime = data[1];
28899
- const res = await ctx.ntFriendApi.handleFriendRequest(uid, reqTime, payload.approve);
28900
- if (res.result !== 0) throw new Error(res.errMsg);
28904
+ await ctx.ntFriendApi.approvalFriendRequest(payload.message_id, payload.approve);
28901
28905
  return {};
28902
28906
  };
28903
28907
  //#endregion
@@ -29195,7 +29199,7 @@ async function parseGuildMemberRequest(bot, input, doubt) {
29195
29199
  //#endregion
29196
29200
  //#region src/satori/event/user.ts
29197
29201
  async function parseFriendRequest(bot, input) {
29198
- const flag = input.friendUid + "|" + input.reqTime;
29202
+ const flag = input.friendUid;
29199
29203
  const user = await bot.ctx.ntUserApi.getUserSimpleInfo(input.friendUid);
29200
29204
  return bot.event("friend-request", {
29201
29205
  user: decodeUser(user.coreInfo),
@@ -29265,7 +29269,6 @@ var SatoriAdapter = class extends Service {
29265
29269
  static inject = [
29266
29270
  "ntMsgApi",
29267
29271
  "ntFileApi",
29268
- "ntFileCacheApi",
29269
29272
  "ntFriendApi",
29270
29273
  "ntGroupApi",
29271
29274
  "ntUserApi",
@@ -40897,7 +40900,7 @@ function _null(params) {
40897
40900
  var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
40898
40901
  $ZodAny.init(inst, def);
40899
40902
  ZodType.init(inst, def);
40900
- inst._zod.processJSONSchema = (ctx, json, params) => anyProcessor(inst, ctx, json, params);
40903
+ inst._zod.processJSONSchema = (ctx, json, params) => void 0;
40901
40904
  });
40902
40905
  function any() {
40903
40906
  return /* @__PURE__ */ _any(ZodAny);
@@ -40905,7 +40908,7 @@ function any() {
40905
40908
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
40906
40909
  $ZodUnknown.init(inst, def);
40907
40910
  ZodType.init(inst, def);
40908
- inst._zod.processJSONSchema = (ctx, json, params) => unknownProcessor(inst, ctx, json, params);
40911
+ inst._zod.processJSONSchema = (ctx, json, params) => void 0;
40909
40912
  });
40910
40913
  function unknown() {
40911
40914
  return /* @__PURE__ */ _unknown(ZodUnknown);
@@ -42399,14 +42402,14 @@ function transformGender(gender) {
42399
42402
  }
42400
42403
  function transformFriend(friend, category) {
42401
42404
  return {
42402
- user_id: +friend.uin,
42403
- nickname: friend.coreInfo.nick,
42404
- sex: transformGender(friend.baseInfo.sex),
42405
- qid: friend.baseInfo.qid,
42406
- remark: friend.coreInfo.remark,
42405
+ user_id: friend.uin,
42406
+ nickname: friend.nick,
42407
+ sex: transformGender(friend.sex),
42408
+ qid: friend.qid,
42409
+ remark: friend.remark,
42407
42410
  category: {
42408
42411
  category_id: category.categoryId,
42409
- category_name: category.categroyName
42412
+ category_name: category.categoryName
42410
42413
  }
42411
42414
  };
42412
42415
  }
@@ -43470,7 +43473,7 @@ async function download(url, headers) {
43470
43473
  return Buffer.from(bytes);
43471
43474
  }
43472
43475
  async function resolveMilkyUri(uri) {
43473
- if (uri.startsWith("file://")) return await fsPromise.readFile(fileURLToPath(uri));
43476
+ if (uri.startsWith("file://")) return await fs.readFile(fileURLToPath(uri));
43474
43477
  if (uri.startsWith("http://") || uri.startsWith("https://")) return await download(uri);
43475
43478
  if (uri.startsWith("base64://")) return Buffer.from(uri.slice(9), "base64");
43476
43479
  throw new Error(`Unsupported URI scheme: ${uri}`);
@@ -43513,22 +43516,16 @@ var SystemApi = [
43513
43516
  school: info.school
43514
43517
  });
43515
43518
  }),
43516
- defineApi("get_friend_list", GetFriendListInput, GetFriendListOutput, async (ctx) => {
43517
- const friends = await ctx.ntFriendApi.getBuddyList();
43518
- const category = /* @__PURE__ */ new Map();
43519
+ defineApi("get_friend_list", GetFriendListInput, GetFriendListOutput, async (ctx, payload) => {
43520
+ const result = await ctx.ntFriendApi.getFriendList(payload.no_cache);
43519
43521
  const friendList = [];
43520
- for (const friend of friends) {
43521
- const { categoryId } = friend.baseInfo;
43522
- if (!category.has(categoryId)) category.set(categoryId, await ctx.ntFriendApi.getCategoryById(categoryId));
43523
- friendList.push(transformFriend(friend, category.get(categoryId)));
43524
- }
43522
+ for (const friend of result.friends) friendList.push(transformFriend(friend, result.categories.get(friend.categoryId)));
43525
43523
  return Ok({ friends: friendList });
43526
43524
  }),
43527
43525
  defineApi("get_friend_info", GetFriendInfoInput, GetFriendInfoOutput, async (ctx, payload) => {
43528
- const uid = await ctx.ntUserApi.getUidByUin(payload.user_id.toString());
43529
- if (!uid) return Failed(-404, "User not found");
43530
- const friend = await ctx.ntUserApi.getUserSimpleInfo(uid, payload.no_cache);
43531
- return Ok({ friend: transformFriend(friend, await ctx.ntFriendApi.getCategoryById(friend.baseInfo.categoryId)) });
43526
+ const result = await ctx.ntFriendApi.getFriendInfoByUin(payload.user_id, payload.no_cache);
43527
+ if (!result) return Failed(-404, "Friend not found");
43528
+ return Ok({ friend: transformFriend(result.friend, result.category) });
43532
43529
  }),
43533
43530
  defineApi("get_group_list", GetGroupListInput, GetGroupListOutput, async (ctx) => {
43534
43531
  const { groups } = await ctx.pmhq.fetchGroups();
@@ -43584,28 +43581,15 @@ var SystemApi = [
43584
43581
  return Ok({ member: transformGroupMember(await ctx.ntGroupApi.getGroupMember(groupCode, memberUid, payload.no_cache), payload.group_id) });
43585
43582
  }),
43586
43583
  defineApi("get_peer_pins", zod_default.object({}), GetPeerPinsOutput, async (ctx) => {
43587
- const friends = await ctx.ntFriendApi.getBuddyList();
43588
- const category = /* @__PURE__ */ new Map();
43589
- const { groups } = await ctx.pmhq.fetchGroups();
43584
+ const result = await ctx.ntSystemApi.getPins();
43590
43585
  return Ok({
43591
- friends: await Promise.all(friends.filter((e) => e.relationFlags && e.relationFlags.topTime !== "0").map(async (e) => {
43592
- const { categoryId } = e.baseInfo;
43593
- if (!category.has(categoryId)) category.set(categoryId, await ctx.ntFriendApi.getCategoryById(categoryId));
43594
- return transformFriend(e, category.get(categoryId));
43586
+ friends: await Promise.all(result.friends.map(async (e) => {
43587
+ const info = await ctx.ntFriendApi.getFriendInfoByUid(e.uid, false);
43588
+ return transformFriend(info.friend, info.category);
43595
43589
  })),
43596
- groups: groups.filter((e) => e.info.topTime).map((e) => {
43597
- return {
43598
- group_id: e.groupCode,
43599
- group_name: e.info.groupName,
43600
- member_count: e.info.memberCount,
43601
- max_member_count: e.info.memberMax,
43602
- remark: e.customInfo.remark ?? "",
43603
- created_time: e.info.createdTime,
43604
- description: e.info.richDescription ?? "",
43605
- question: e.info.question ?? "",
43606
- announcement: e.info.announcement ?? ""
43607
- };
43608
- })
43590
+ groups: await Promise.all(result.groups.map(async (e) => {
43591
+ return transformGroup(await ctx.ntGroupApi.getGroupDetailInfo(e.groupCode.toString()));
43592
+ }))
43609
43593
  });
43610
43594
  }),
43611
43595
  defineApi("set_peer_pin", SetPeerPinInput, zod_default.object({}), async (ctx, payload) => {
@@ -43859,53 +43843,10 @@ var ForwardMessageEncoder = class ForwardMessageEncoder {
43859
43843
  this.children = [];
43860
43844
  this.preview = "";
43861
43845
  }
43862
- async packImage(data, busiType) {
43863
- const imageSize = await this.ctx.ntFileApi.getImageSize(data.filePath);
43846
+ async packImage(msgInfo) {
43864
43847
  return { commonElem: {
43865
43848
  serviceType: 48,
43866
- pbElem: Media.MsgInfo.encode({
43867
- msgInfoBody: [{
43868
- index: {
43869
- info: {
43870
- fileSize: +data.commonFileInfo.fileSize,
43871
- md5HexStr: data.commonFileInfo.md5,
43872
- sha1HexStr: data.commonFileInfo.sha,
43873
- fileName: data.commonFileInfo.fileName,
43874
- fileType: {
43875
- type: 1,
43876
- picFormat: imageSize.type === "gif" ? 2e3 : 1e3
43877
- },
43878
- width: imageSize.width,
43879
- height: imageSize.height,
43880
- time: 0,
43881
- original: 1
43882
- },
43883
- fileUuid: data.fileId,
43884
- storeID: 1,
43885
- expire: this.isGroup ? 2678400 : 15768e4
43886
- },
43887
- pic: {
43888
- urlPath: `/download?appid=${this.isGroup ? 1407 : 1406}&fileid=${data.fileId}`,
43889
- ext: {
43890
- originalParam: "&spec=0",
43891
- bigParam: "&spec=720",
43892
- thumbParam: "&spec=198"
43893
- },
43894
- domain: "multimedia.nt.qq.com.cn"
43895
- },
43896
- fileExist: true
43897
- }],
43898
- extBizInfo: {
43899
- pic: {
43900
- bizType: 0,
43901
- summary: "",
43902
- fromScene: this.isGroup ? 2 : 1,
43903
- toScene: this.isGroup ? 2 : 1,
43904
- oldFileId: this.isGroup ? 574859779 : void 0
43905
- },
43906
- busiType
43907
- }
43908
- }),
43849
+ pbElem: Media.MsgInfo.encode(msgInfo),
43909
43850
  businessType: this.isGroup ? 20 : 10
43910
43851
  } };
43911
43852
  }
@@ -43962,9 +43903,11 @@ var ForwardMessageEncoder = class ForwardMessageEncoder {
43962
43903
  const imageBuffer = await resolveMilkyUri(segment.data.uri);
43963
43904
  const tempPath = path.join(TEMP_DIR, `image-${randomUUID()}`);
43964
43905
  await writeFile(tempPath, imageBuffer);
43965
- const data = await this.ctx.ntFileApi.uploadRMFileWithoutMsg(tempPath, this.isGroup ? RMBizType.GroupPic : RMBizType.C2CPic, this.isGroup ? this.peerUid : selfInfo.uid);
43906
+ let data;
43907
+ if (this.isGroup) data = await this.ctx.ntFileApi.uploadGroupImage(this.peerUid, tempPath);
43908
+ else data = await this.ctx.ntFileApi.uploadC2CImage(this.peerUid, tempPath);
43966
43909
  const busiType = segment.data.sub_type === "sticker" ? 1 : 0;
43967
- this.children.push(await this.packImage(data, busiType));
43910
+ this.children.push(await this.packImage(data.msgInfo));
43968
43911
  this.preview += busiType === 1 ? "[动画表情]" : "[图片]";
43969
43912
  unlink(tempPath).catch(noop);
43970
43913
  } else if (type === "forward") {
@@ -47577,7 +47520,7 @@ function readStopNodeData(xmlData, tagName, i) {
47577
47520
  else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) i = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed.");
47578
47521
  else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) i = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
47579
47522
  else {
47580
- const tagData = readTagExp(xmlData, i, ">");
47523
+ const tagData = readTagExp(xmlData, i, false);
47581
47524
  if (tagData) {
47582
47525
  if ((tagData && tagData.tagName) === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== "/") openTagCount++;
47583
47526
  i = tagData.closeIndex;
@@ -47662,6 +47605,7 @@ function compress(arr, options, matcher, readonlyMatcher) {
47662
47605
  else if (tagObj[property]) {
47663
47606
  let val = compress(tagObj[property], options, matcher, readonlyMatcher);
47664
47607
  const isLeaf = isLeafTag(val, options);
47608
+ if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) val[options.textNodeName] = "";
47665
47609
  if (tagObj[":@"]) assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
47666
47610
  else if (Object.keys(val).length === 1 && val[options.textNodeName] !== void 0 && !options.alwaysCreateTextNode) val = val[options.textNodeName];
47667
47611
  else if (Object.keys(val).length === 0) if (options.alwaysCreateTextNode) val[options.textNodeName] = "";
@@ -47770,7 +47714,25 @@ async function transformIncomingPrivateMessage(ctx, friend, category, message) {
47770
47714
  sender_id: +message.senderUin,
47771
47715
  time: +message.msgTime,
47772
47716
  segments: await transformIncomingSegments(ctx, message),
47773
- friend: transformFriend(friend, category)
47717
+ friend: transformFriend({
47718
+ uid: friend.uid,
47719
+ uin: +friend.uin,
47720
+ categoryId: friend.baseInfo.categoryId,
47721
+ nick: friend.coreInfo.nick,
47722
+ longNick: friend.baseInfo.longNick,
47723
+ remark: friend.coreInfo.remark,
47724
+ qid: friend.baseInfo.qid,
47725
+ age: friend.baseInfo.age,
47726
+ sex: friend.baseInfo.sex,
47727
+ birthdayYear: friend.baseInfo.birthday_year,
47728
+ birthdayMonth: friend.baseInfo.birthday_month,
47729
+ birthdayDay: friend.baseInfo.birthday_day
47730
+ }, {
47731
+ categoryId: category.categoryId,
47732
+ categoryName: category.categroyName,
47733
+ categoryMemberCount: category.categroyMbCount,
47734
+ categorySortId: category.categorySortId
47735
+ })
47774
47736
  };
47775
47737
  }
47776
47738
  async function transformIncomingGroupMessage(ctx, group, member, message) {
@@ -47841,7 +47803,7 @@ async function transformIncomingSegments(ctx, message) {
47841
47803
  type: "image",
47842
47804
  data: {
47843
47805
  resource_id: element.picElement.fileUuid,
47844
- temp_url: await ctx.ntFileApi.getImageUrl(element.picElement),
47806
+ temp_url: await ctx.ntFileApi.getImageUrl(element.picElement.originImageUrl, element.picElement.md5HexStr),
47845
47807
  width: element.picElement.picWidth,
47846
47808
  height: element.picElement.picHeight,
47847
47809
  summary: element.picElement.summary || "[图片]",
@@ -47864,7 +47826,7 @@ async function transformIncomingSegments(ctx, message) {
47864
47826
  type: "video",
47865
47827
  data: {
47866
47828
  resource_id: element.videoElement.fileUuid,
47867
- temp_url: await ctx.ntFileApi.getVideoUrlByPacket(element.videoElement.fileUuid, message.chatType === ChatType.Group),
47829
+ temp_url: await ctx.ntFileApi.getVideoUrl(element.videoElement.fileUuid, message.chatType === ChatType.Group),
47868
47830
  width: element.videoElement.thumbWidth,
47869
47831
  height: element.videoElement.thumbHeight,
47870
47832
  duration: element.videoElement.fileTime
@@ -47908,20 +47870,22 @@ async function transformIncomingSegments(ctx, message) {
47908
47870
  break;
47909
47871
  case ElementType.Ark: {
47910
47872
  const { arkElement } = element;
47911
- const data = JSON.parse(arkElement.bytesData);
47912
- if (data.app === "com.tencent.multimsg" && data.meta.detail.resid) segments.push({
47913
- type: "forward",
47914
- data: {
47915
- forward_id: data.meta.detail.resid,
47916
- title: data.meta.detail.source,
47917
- preview: data.meta.detail.news.map((item) => item.text),
47918
- summary: data.meta.detail.summary
47919
- }
47920
- });
47921
- else segments.push({
47873
+ const match = arkElement.bytesData.match(/"app"\s*:\s*"([^"]*)"/);
47874
+ if (match?.[1]) if (match[1] === "com.tencent.multimsg") {
47875
+ const data = JSON.parse(arkElement.bytesData);
47876
+ segments.push({
47877
+ type: "forward",
47878
+ data: {
47879
+ forward_id: data.meta.detail.resid,
47880
+ title: data.meta.detail.source,
47881
+ preview: data.meta.detail.news.map((item) => item.text),
47882
+ summary: data.meta.detail.summary
47883
+ }
47884
+ });
47885
+ } else segments.push({
47922
47886
  type: "light_app",
47923
47887
  data: {
47924
- app_name: data.app,
47888
+ app_name: match[1],
47925
47889
  json_payload: arkElement.bytesData
47926
47890
  }
47927
47891
  });
@@ -47969,7 +47933,7 @@ async function transformIncomingForwardedMessage(ctx, message) {
47969
47933
  } else if (serviceType === 48 && (businessType === 11 || businessType === 21)) {
47970
47934
  const { msgInfoBody } = Media.MsgInfo.decode(elem.commonElem.pbElem);
47971
47935
  const { index } = msgInfoBody[0];
47972
- const url = await ctx.ntFileApi.getVideoUrlByPacket(index.fileUuid, businessType === 21);
47936
+ const url = await ctx.ntFileApi.getVideoUrl(index.fileUuid, businessType === 21);
47973
47937
  segments.push({
47974
47938
  type: "video",
47975
47939
  data: {
@@ -48030,7 +47994,7 @@ var SendPrivateMessage = defineApi("send_private_message", SendPrivateMessageInp
48030
47994
  peerUid: uid,
48031
47995
  guildId: ""
48032
47996
  };
48033
- if (!await ctx.ntFriendApi.isBuddy(uid)) {
47997
+ if (!await ctx.ntFriendApi.isFriend(uid)) {
48034
47998
  if ((await ctx.ntMsgApi.getTempChatInfo(100, uid)).tmpChatInfo.groupCode) peer.chatType = 100;
48035
47999
  }
48036
48000
  const { elements, deleteAfterSentFiles } = await transformOutgoingMessage(ctx, payload.message, uid, false);
@@ -48062,7 +48026,7 @@ var RecallPrivateMessage = defineApi("recall_private_message", RecallPrivateMess
48062
48026
  peerUid: uid,
48063
48027
  guildId: ""
48064
48028
  };
48065
- if (!await ctx.ntFriendApi.isBuddy(uid)) {
48029
+ if (!await ctx.ntFriendApi.isFriend(uid)) {
48066
48030
  if ((await ctx.ntMsgApi.getTempChatInfo(100, uid)).tmpChatInfo.groupCode) peer.chatType = 100;
48067
48031
  }
48068
48032
  const msg = await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, payload.message_seq.toString(), 1, true, true);
@@ -48177,7 +48141,7 @@ var MessageApi = [
48177
48141
  const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey(true);
48178
48142
  const rkey = appid === 1406 ? rkeyData.private_rkey : rkeyData.group_rkey;
48179
48143
  return Ok({ url: `${IMAGE_HTTP_HOST_NT}/download?appid=${appid}&fileid=${payload.resource_id}&spec=0${rkey}` });
48180
- } else if (appid === 1413 || appid === 1415) return Ok({ url: await ctx.ntFileApi.getVideoUrlByPacket(payload.resource_id, appid === 1415) });
48144
+ } else if (appid === 1413 || appid === 1415) return Ok({ url: await ctx.ntFileApi.getVideoUrl(payload.resource_id, appid === 1415) });
48181
48145
  else {
48182
48146
  ctx.logger.warn(`GetResourceTempUrl: not yet supported appid: ${appid}`);
48183
48147
  return Ok({ url: "" });
@@ -48272,17 +48236,12 @@ var FriendApi = [
48272
48236
  }
48273
48237
  }),
48274
48238
  defineApi("accept_friend_request", AcceptFriendRequestInput, zod_default.object({}), async (ctx, payload) => {
48275
- let result;
48276
- if (payload.is_filtered) result = await ctx.ntFriendApi.approvalDoubtBuddyReq(payload.initiator_uid);
48277
- else result = await ctx.ntFriendApi.handleFriendRequest(payload.initiator_uid, "0", true);
48278
- if (result.result !== 0) return Failed(-500, result.errMsg);
48239
+ if (payload.is_filtered) await ctx.ntFriendApi.approvalDoubtFriendRequest(payload.initiator_uid);
48240
+ else await ctx.ntFriendApi.approvalFriendRequest(payload.initiator_uid, true);
48279
48241
  return Ok({});
48280
48242
  }),
48281
48243
  defineApi("reject_friend_request", RejectFriendRequestInput, zod_default.object({}), async (ctx, payload) => {
48282
- if (!payload.is_filtered) {
48283
- const result = await ctx.ntFriendApi.handleFriendRequest(payload.initiator_uid, "0", false);
48284
- if (result.result !== 0) return Failed(-500, result.errMsg);
48285
- }
48244
+ if (!payload.is_filtered) await ctx.ntFriendApi.approvalFriendRequest(payload.initiator_uid, false);
48286
48245
  return Ok({});
48287
48246
  })
48288
48247
  ];
@@ -52243,16 +52202,14 @@ var Store = class extends Service {
52243
52202
  uniqueMsgId: "string(64)",
52244
52203
  peerUid: "string(24)"
52245
52204
  }, { primary: "shortId" });
52246
- this.ctx.model.extend("file_v2", {
52205
+ this.ctx.model.extend("file", {
52247
52206
  fileName: "string",
52248
52207
  fileSize: "string",
52249
52208
  fileUuid: "string(128)",
52250
- msgId: "string(24)",
52251
52209
  msgTime: "unsigned(10)",
52252
- peerUid: "string(24)",
52253
52210
  chatType: "unsigned",
52254
- elementId: "string(24)",
52255
- elementType: "unsigned"
52211
+ elementType: "unsigned",
52212
+ md5HexStr: "string(32)"
52256
52213
  }, {
52257
52214
  primary: "fileUuid",
52258
52215
  indexes: ["fileName"]
@@ -52334,15 +52291,15 @@ var Store = class extends Service {
52334
52291
  return this.cache.getValue(cacheKey);
52335
52292
  }
52336
52293
  async addFileCache(data) {
52337
- const existingFile = await this.ctx.database.get("file_v2", { fileUuid: data.fileUuid });
52294
+ const existingFile = await this.ctx.database.get("file", { fileUuid: data.fileUuid });
52338
52295
  if (existingFile.length) return existingFile;
52339
- this.ctx.database.upsert("file_v2", [data], "fileUuid").then().catch((e) => this.ctx.logger.error("addFileCache database error:", e));
52296
+ this.ctx.database.upsert("file", [data], "fileUuid").then().catch((e) => this.ctx.logger.error("addFileCache database error:", e));
52340
52297
  }
52341
52298
  getFileCacheByName(fileName) {
52342
- return this.ctx.database.get("file_v2", { fileName }, { sort: { msgTime: "desc" } });
52299
+ return this.ctx.database.get("file", { fileName }, { sort: { msgTime: "desc" } });
52343
52300
  }
52344
52301
  getFileCacheById(fileUuid) {
52345
- return this.ctx.database.get("file_v2", { fileUuid });
52302
+ return this.ctx.database.get("file", { fileUuid });
52346
52303
  }
52347
52304
  async addMsgCache(msg) {
52348
52305
  const expire = this.config.msgCacheExpire;
@@ -52638,36 +52595,24 @@ var NTQQFileApi = class extends Service {
52638
52595
  this.ctx = ctx;
52639
52596
  this.rkeyManager = new RkeyManager(ctx, "https://llob.linyuchen.net/rkey");
52640
52597
  }
52641
- async getVideoUrlByPacket(fileUuid, isGroup) {
52642
- if (isGroup) return await this.ctx.pmhq.getGroupVideoUrl(fileUuid);
52643
- else return await this.ctx.pmhq.getPrivateVideoUrl(fileUuid);
52598
+ async getVideoUrl(fileUuid, isGroup) {
52599
+ if (isGroup) {
52600
+ const { download } = await this.ctx.pmhq.getGroupVideoUrl(fileUuid);
52601
+ return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
52602
+ } else {
52603
+ const { download } = await this.ctx.pmhq.getPrivateVideoUrl(fileUuid);
52604
+ return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
52605
+ }
52644
52606
  }
52645
52607
  async getPttUrl(fileUuid, isGroup) {
52646
- if (isGroup) return await this.ctx.pmhq.getGroupPttUrl(fileUuid);
52647
- else return await this.ctx.pmhq.getPrivatePttUrl(fileUuid);
52648
- }
52649
- async getVideoUrl(peer, msgId, elementId) {
52650
- try {
52651
- const data = await this.ctx.pmhq.invoke("nodeIKernelRichMediaService/getVideoPlayUrlV2", [
52652
- peer,
52653
- msgId,
52654
- elementId,
52655
- 0,
52656
- {
52657
- downSourceType: 1,
52658
- triggerType: 0
52659
- }
52660
- ]);
52661
- if (data.result !== 0) this.ctx.logger.warn("getVideoUrl", data);
52662
- return data.urlResult.domainUrl[0]?.url ?? "";
52663
- } catch (e) {
52664
- this.ctx.logger.warn("getVideoUrl error", e);
52665
- return "";
52608
+ if (isGroup) {
52609
+ const { download } = await this.ctx.pmhq.getGroupPttUrl(fileUuid);
52610
+ return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
52611
+ } else {
52612
+ const { download } = await this.ctx.pmhq.getPrivatePttUrl(fileUuid);
52613
+ return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
52666
52614
  }
52667
52615
  }
52668
- async getFileType(filePath) {
52669
- return await getFileType(filePath);
52670
- }
52671
52616
  async getRichMediaFilePath(md5HexStr, fileName, elementType, elementSubType = 0) {
52672
52617
  return await this.ctx.pmhq.invoke(NTMethod.MEDIA_FILE_PATH, [{
52673
52618
  md5HexStr,
@@ -52685,7 +52630,7 @@ var NTQQFileApi = class extends Service {
52685
52630
  const fileMd5 = await getMd5HexFromFile(filePath);
52686
52631
  let fileName = path.basename(filePath);
52687
52632
  if (!fileName.includes(".")) {
52688
- const ext = (await this.getFileType(filePath))?.ext;
52633
+ const ext = (await getFileType(filePath))?.ext;
52689
52634
  fileName += ext ? "." + ext : "";
52690
52635
  }
52691
52636
  const mediaPath = await this.getRichMediaFilePath(fileMd5, fileName, elementType, elementSubType);
@@ -52696,37 +52641,8 @@ var NTQQFileApi = class extends Service {
52696
52641
  path: mediaPath
52697
52642
  };
52698
52643
  }
52699
- async downloadMedia(msgId, chatType, peerUid, elementId, thumbPath = "", sourcePath = "", timeout = 1e3 * 60 * 30, force = false) {
52700
- if (sourcePath && existsSync$1(sourcePath)) if (force) unlink(sourcePath).catch(noop);
52701
- else return sourcePath;
52702
- return (await this.ctx.pmhq.invoke("nodeIKernelMsgService/downloadRichMedia", [{
52703
- fileModelId: "0",
52704
- downloadSourceType: 0,
52705
- triggerType: 1,
52706
- msgId,
52707
- chatType,
52708
- peerUid,
52709
- elementId,
52710
- thumbSize: 0,
52711
- downloadType: 1,
52712
- filePath: thumbPath
52713
- }], {
52714
- resultCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
52715
- resultCb: (payload) => payload.msgId === msgId,
52716
- timeout
52717
- })).filePath;
52718
- }
52719
- async getImageSize(filePath) {
52720
- const fileType = await getFileType(filePath);
52721
- const size = await getImageSize(filePath);
52722
- return {
52723
- type: fileType.ext,
52724
- ...size
52725
- };
52726
- }
52727
- async getImageUrl(element) {
52728
- const url = element.originImageUrl;
52729
- const md5HexStr = element.md5HexStr;
52644
+ async getImageUrl(originImageUrl, md5HexStr) {
52645
+ const url = originImageUrl;
52730
52646
  if (url) {
52731
52647
  const parsedUrl = new URL(IMAGE_HTTP_HOST + url);
52732
52648
  const imageAppid = parsedUrl.searchParams.get("appid");
@@ -52740,31 +52656,10 @@ var NTQQFileApi = class extends Service {
52740
52656
  else return IMAGE_HTTP_HOST + url;
52741
52657
  } else return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${md5HexStr.toUpperCase()}/0`;
52742
52658
  }
52743
- async downloadFileForModelId(peer, fileModelId, timeout = 2 * Time.minute) {
52744
- return (await this.ctx.pmhq.invoke("nodeIKernelRichMediaService/downloadFileForModelId", [
52745
- peer,
52746
- [fileModelId],
52747
- ""
52748
- ], {
52749
- resultCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
52750
- resultCb: (payload) => payload.fileModelId === fileModelId,
52751
- timeout
52752
- })).filePath;
52753
- }
52754
- async ocrImage(path) {
52755
- return await this.ctx.pmhq.invoke("nodeIKernelNodeMiscService/wantWinScreenOCR", [path], { timeout: 2 * Time.minute });
52756
- }
52757
- async uploadRMFileWithoutMsg(filePath, bizType, peerUid) {
52758
- return await this.ctx.pmhq.invoke("nodeIKernelRichMediaService/uploadRMFileWithoutMsg", [{
52759
- filePath,
52760
- bizType,
52761
- peerUid,
52762
- useNTV2: true
52763
- }], {
52764
- resultCmd: ReceiveCmdS.MEDIA_UPLOAD_COMPLETE,
52765
- resultCb: (payload) => payload.filePath === filePath,
52766
- timeout: 20 * Time.second
52767
- });
52659
+ async ocrImage(imageUrl) {
52660
+ const res = await this.ctx.pmhq.imageOcr(imageUrl);
52661
+ if (res.retCode) throw new Error(res.wording);
52662
+ return res.ocrRspBody;
52768
52663
  }
52769
52664
  async uploadFlashFile(title, filePaths) {
52770
52665
  return await this.ctx.pmhq.invoke("nodeIKernelFlashTransferService/createFlashTransferUploadTask", [(/* @__PURE__ */ new Date()).getTime(), {
@@ -53097,38 +52992,61 @@ var NTQQFileApi = class extends Service {
53097
52992
  crcMedia: result.crcMedia
53098
52993
  };
53099
52994
  }
53100
- };
53101
- var NTQQFileCacheApi = class extends Service {
53102
- static inject = ["pmhq"];
53103
- constructor(ctx) {
53104
- super(ctx, "ntFileCacheApi");
53105
- this.ctx = ctx;
53106
- }
53107
- async setCacheSilentScan(isSilent = true) {
53108
- return await this.ctx.pmhq.invoke(NTMethod.CACHE_SET_SILENCE, [{ isSilent }]);
53109
- }
53110
- getCacheSessionPathList() {}
53111
- scanCache() {
53112
- this.ctx.pmhq.invoke(ReceiveCmdS.CACHE_SCAN_FINISH, []);
53113
- return this.ctx.pmhq.invoke(NTMethod.CACHE_SCAN, [], { timeout: 300 * Time.second });
53114
- }
53115
- getHotUpdateCachePath() {}
53116
- getDesktopTmpPath() {}
53117
- getFileCacheInfo(fileType, pageSize = 1e3, lastRecord) {
53118
- const _lastRecord = lastRecord ? lastRecord : { fileType };
53119
- return this.ctx.pmhq.invoke(NTMethod.CACHE_FILE_GET, [{
53120
- fileType,
53121
- restart: true,
53122
- pageSize,
53123
- order: 1,
53124
- lastRecord: _lastRecord
53125
- }]);
52995
+ async uploadGroupImage(groupCode, filePath) {
52996
+ const result = await this.ctx.pmhq.getGroupImageUploadInfo(groupCode, filePath);
52997
+ const highwaySession = await this.ctx.pmhq.getHighwaySession();
52998
+ const maxBlockSize = 1024 * 1024;
52999
+ if (result.ext.uKey) {
53000
+ const { index } = result.ext.msgInfoBody[0];
53001
+ const trans = {
53002
+ uin: selfInfo.uin,
53003
+ cmd: 1004,
53004
+ readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
53005
+ sum: Buffer.from(index.info.md5HexStr, "hex"),
53006
+ size: index.info.fileSize,
53007
+ ticket: highwaySession.sigSession,
53008
+ ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
53009
+ server: highwaySession.highwayHostAndPorts[1][0].host,
53010
+ port: highwaySession.highwayHostAndPorts[1][0].port
53011
+ };
53012
+ try {
53013
+ await new HighwayTcpSession(trans).upload();
53014
+ } catch {
53015
+ await new HighwayHttpSession(trans).upload();
53016
+ }
53017
+ }
53018
+ return {
53019
+ msgInfo: result.info,
53020
+ compat: result.compat
53021
+ };
53126
53022
  }
53127
- async clearChatCache(chats = [], fileKeys = []) {
53128
- return await this.ctx.pmhq.invoke(NTMethod.CACHE_CHAT_CLEAR, [{
53129
- chats,
53130
- fileKeys
53131
- }]);
53023
+ async uploadC2CImage(peerUid, filePath) {
53024
+ const result = await this.ctx.pmhq.getC2CImageUploadInfo(peerUid, filePath);
53025
+ const highwaySession = await this.ctx.pmhq.getHighwaySession();
53026
+ const maxBlockSize = 1024 * 1024;
53027
+ if (result.ext.uKey) {
53028
+ const { index } = result.ext.msgInfoBody[0];
53029
+ const trans = {
53030
+ uin: selfInfo.uin,
53031
+ cmd: 1003,
53032
+ readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
53033
+ sum: Buffer.from(index.info.md5HexStr, "hex"),
53034
+ size: index.info.fileSize,
53035
+ ticket: highwaySession.sigSession,
53036
+ ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
53037
+ server: highwaySession.highwayHostAndPorts[1][0].host,
53038
+ port: highwaySession.highwayHostAndPorts[1][0].port
53039
+ };
53040
+ try {
53041
+ await new HighwayTcpSession(trans).upload();
53042
+ } catch {
53043
+ await new HighwayHttpSession(trans).upload();
53044
+ }
53045
+ }
53046
+ return {
53047
+ msgInfo: result.info,
53048
+ compat: result.compat
53049
+ };
53132
53050
  }
53133
53051
  };
53134
53052
  //#endregion
@@ -53139,37 +53057,81 @@ var NTQQFriendApi = class extends Service {
53139
53057
  "ntSystemApi",
53140
53058
  "pmhq"
53141
53059
  ];
53060
+ friendsCache = [];
53061
+ categoriesCache = /* @__PURE__ */ new Map();
53142
53062
  constructor(ctx) {
53143
53063
  super(ctx, "ntFriendApi");
53144
53064
  this.ctx = ctx;
53145
53065
  }
53146
- /** reqTime 可为 0 */
53147
- async handleFriendRequest(friendUid, reqTime, accept) {
53148
- return await this.ctx.pmhq.invoke(NTMethod.HANDLE_FRIEND_REQUEST, [{
53149
- friendUid,
53150
- reqTime,
53151
- accept
53152
- }]);
53066
+ async approvalFriendRequest(friendUid, accept) {
53067
+ await this.ctx.pmhq.setFriendRequest(friendUid, accept ? 3 : 5);
53068
+ }
53069
+ async getFriendList(forceUpdate) {
53070
+ if (forceUpdate || this.friendsCache.length === 0) {
53071
+ const res = await this.ctx.pmhq.fetchFriends();
53072
+ this.friendsCache = res.friendList.map((friend) => {
53073
+ const biz = friend.subBiz.get(1);
53074
+ return {
53075
+ uid: friend.uid,
53076
+ uin: friend.uin,
53077
+ categoryId: friend.categoryId,
53078
+ nick: biz.data.get(20002).toString(),
53079
+ longNick: biz.data.get(102).toString(),
53080
+ remark: biz.data.get(103).toString(),
53081
+ qid: biz.data.get(27394).toString(),
53082
+ age: biz.numData.get(20037),
53083
+ sex: biz.numData.get(20009),
53084
+ birthdayYear: biz.data.get(20031)[0] << 8 | biz.data.get(20031)[1],
53085
+ birthdayMonth: biz.data.get(20031)[2],
53086
+ birthdayDay: biz.data.get(20031)[3]
53087
+ };
53088
+ });
53089
+ this.categoriesCache.clear();
53090
+ for (const cat of res.category) this.categoriesCache.set(cat.categoryId, cat);
53091
+ }
53092
+ return {
53093
+ friends: this.friendsCache,
53094
+ categories: this.categoriesCache
53095
+ };
53153
53096
  }
53154
- async getBuddyList() {
53155
- return await this.ctx.pmhq.invoke("getBuddyList", [], {});
53097
+ async getFriendInfoByUin(uin, forceUpdate) {
53098
+ const result = await this.getFriendList(forceUpdate);
53099
+ let categories = result.categories;
53100
+ let friend = result.friends.find((e) => e.uin === uin);
53101
+ if (!friend) {
53102
+ const result = await this.getFriendList(true);
53103
+ categories = result.categories;
53104
+ friend = result.friends.find((e) => e.uin === uin);
53105
+ }
53106
+ if (!friend) return;
53107
+ const category = categories.get(friend.categoryId);
53108
+ return {
53109
+ friend,
53110
+ category
53111
+ };
53156
53112
  }
53157
- async getBuddyV2(forceRefresh) {
53158
- const version = +(await this.ctx.ntSystemApi.getDeviceInfo()).buildVer.split("-")[1];
53159
- let result;
53160
- if (version >= 41679) result = await this.ctx.pmhq.invoke("nodeIKernelBuddyService/getBuddyListV2", [
53161
- "",
53162
- forceRefresh,
53163
- 0
53164
- ]);
53165
- else result = await this.ctx.pmhq.invoke("nodeIKernelBuddyService/getBuddyListV2", [forceRefresh, 0]);
53166
- return result;
53113
+ async getFriendInfoByUid(uid, forceUpdate) {
53114
+ const result = await this.getFriendList(forceUpdate);
53115
+ let categories = result.categories;
53116
+ let friend = result.friends.find((e) => e.uid === uid);
53117
+ if (!friend) {
53118
+ const result = await this.getFriendList(true);
53119
+ categories = result.categories;
53120
+ friend = result.friends.find((e) => e.uid === uid);
53121
+ }
53122
+ if (!friend) return;
53123
+ const category = categories.get(friend.categoryId);
53124
+ return {
53125
+ friend,
53126
+ category
53127
+ };
53167
53128
  }
53168
- async isBuddy(uid) {
53169
- return await this.ctx.pmhq.invoke("nodeIKernelBuddyService/isBuddy", [uid]);
53129
+ async isFriend(uid) {
53130
+ return await this.getFriendInfoByUid(uid, false) !== void 0;
53170
53131
  }
53171
- async getBuddyRecommendContact(uin) {
53172
- return (await this.ctx.pmhq.invoke("nodeIKernelBuddyService/getBuddyRecommendContactArkJson", [uin, "-"])).arkMsg;
53132
+ async getFriendRecommendContactArk(uin) {
53133
+ const { ark } = await this.ctx.pmhq.getFriendRecommendContactArk(uin);
53134
+ return ark;
53173
53135
  }
53174
53136
  async setBuddyRemark(uid, remark = "") {
53175
53137
  return await this.ctx.pmhq.invoke("nodeIKernelBuddyService/setBuddyRemark", [{
@@ -53201,12 +53163,8 @@ var NTQQFriendApi = class extends Service {
53201
53163
  resultCb: (payload) => payload.reqId === reqId
53202
53164
  });
53203
53165
  }
53204
- async approvalDoubtBuddyReq(uid) {
53205
- return await this.ctx.pmhq.invoke("nodeIKernelBuddyService/approvalDoubtBuddyReq", [
53206
- uid,
53207
- "",
53208
- ""
53209
- ]);
53166
+ async approvalDoubtFriendRequest(requestUid) {
53167
+ return await this.ctx.pmhq.setFilteredFriendRequestReq(selfInfo.uid, requestUid);
53210
53168
  }
53211
53169
  async getBuddyReq() {
53212
53170
  return await this.ctx.pmhq.invoke("nodeIKernelBuddyService/getBuddyReq", [], { resultCmd: "nodeIKernelBuddyListener/onBuddyReqChange" });
@@ -54337,7 +54295,7 @@ var NTQQWebApi = class extends Service {
54337
54295
  const iBatchID = Math.floor(Date.now() / 1e3);
54338
54296
  for (let i = 0; i < filePathList.length; i++) {
54339
54297
  const filePath = filePathList[i];
54340
- const fileBuffer = await fsPromise.readFile(filePath);
54298
+ const fileBuffer = await fs.readFile(filePath);
54341
54299
  const fileSize = fileBuffer.length;
54342
54300
  const fileType = await fileTypeFromBuffer(fileBuffer);
54343
54301
  const timestamp = Math.floor(Date.now() / 1e3);
@@ -54522,7 +54480,7 @@ var NTQQWebApi = class extends Service {
54522
54480
  }
54523
54481
  if (sVid) {
54524
54482
  const filePath = await createThumb(this.ctx, filePathList[i]);
54525
- const fileBuffer = await fsPromise.readFile(filePath);
54483
+ const fileBuffer = await fs.readFile(filePath);
54526
54484
  const fileSize = fileBuffer.length;
54527
54485
  const timestamp = Math.floor(Date.now() / 1e3);
54528
54486
  const checksum = getMd5HexFromBuffer(fileBuffer);
@@ -54690,6 +54648,9 @@ var NTQQSystemApi = class extends Service {
54690
54648
  async scanQRCode(path) {
54691
54649
  return await this.ctx.pmhq.invoke("nodeIKernelNodeMiscService/scanQBar", [path]);
54692
54650
  }
54651
+ async getPins() {
54652
+ return await this.ctx.pmhq.fetchPins();
54653
+ }
54693
54654
  };
54694
54655
  //#endregion
54695
54656
  //#region node_modules/get-port/index.js
@@ -56014,7 +55975,7 @@ var Config = class extends Service {
56014
55975
  this.logger.info("配置文件位于", this.configPath);
56015
55976
  this.config = this.get();
56016
55977
  if (this.configPath) {
56017
- fs$1.watchFile(this.configPath, {
55978
+ fs$2.watchFile(this.configPath, {
56018
55979
  persistent: true,
56019
55980
  interval: 1e3
56020
55981
  }, () => {
@@ -56032,7 +55993,7 @@ var Config = class extends Service {
56032
55993
  }
56033
55994
  getDefaultConfig() {
56034
55995
  const _defaultConfig = { ...defaultConfig };
56035
- const defaultConfigFromFile = fs$1.readFileSync(this.defaultConfigPath, "utf-8");
55996
+ const defaultConfigFromFile = fs$2.readFileSync(this.defaultConfigPath, "utf-8");
56036
55997
  try {
56037
55998
  const parsedDefaultConfig = import_dist.default.parse(defaultConfigFromFile);
56038
55999
  Object.assign(_defaultConfig, parsedDefaultConfig);
@@ -56043,12 +56004,12 @@ var Config = class extends Service {
56043
56004
  }
56044
56005
  reloadConfig() {
56045
56006
  if (!this.configPath) return this.getDefaultConfig();
56046
- if (!fs$1.existsSync(this.configPath)) {
56007
+ if (!fs$2.existsSync(this.configPath)) {
56047
56008
  this.config = this.getDefaultConfig();
56048
56009
  this.set(this.config);
56049
56010
  return this.config;
56050
56011
  } else {
56051
- const data = fs$1.readFileSync(this.configPath, "utf-8");
56012
+ const data = fs$2.readFileSync(this.configPath, "utf-8");
56052
56013
  let jsonData = defaultConfig;
56053
56014
  try {
56054
56015
  jsonData = import_dist.default.parse(data);
@@ -56074,7 +56035,7 @@ var Config = class extends Service {
56074
56035
  writeConfig(config) {
56075
56036
  if (!this.configPath) return;
56076
56037
  this.watch = false;
56077
- fs$1.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8");
56038
+ fs$2.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8");
56078
56039
  setTimeout(() => {
56079
56040
  this.watch = true;
56080
56041
  }, 1500);
@@ -56180,13 +56141,13 @@ var WebUITokenUtil = class {
56180
56141
  }
56181
56142
  getToken() {
56182
56143
  if (!this.token) {
56183
- if (fs$1.existsSync(this.tokenPath)) this.token = fs$1.readFileSync(this.tokenPath, "utf-8").trim();
56144
+ if (fs$2.existsSync(this.tokenPath)) this.token = fs$2.readFileSync(this.tokenPath, "utf-8").trim();
56184
56145
  }
56185
56146
  return this.token;
56186
56147
  }
56187
56148
  setToken(token) {
56188
56149
  this.token = token.trim();
56189
- fs$1.writeFileSync(this.tokenPath, token, "utf-8");
56150
+ fs$2.writeFileSync(this.tokenPath, token, "utf-8");
56190
56151
  }
56191
56152
  };
56192
56153
  var webuiTokenUtil = new WebUITokenUtil(path.join(DATA_DIR, "webui_token.txt"));
@@ -56408,7 +56369,7 @@ function createDashboardRoutes(ctx) {
56408
56369
  success: false,
56409
56370
  message: "服务尚未就绪,请等待登录完成"
56410
56371
  }, 503);
56411
- const friends = await ctx.ntFriendApi.getBuddyList();
56372
+ const friends = await ctx.ntFriendApi.getFriendList(false);
56412
56373
  const groups = await ctx.ntGroupApi.getGroups(false);
56413
56374
  const qqInfo = await ctx.pmhq.getProcessInfo();
56414
56375
  const qqMemory = qqInfo?.memory?.rss || 0;
@@ -56425,7 +56386,7 @@ function createDashboardRoutes(ctx) {
56425
56386
  return c.json({
56426
56387
  success: true,
56427
56388
  data: {
56428
- friendCount: friends.length,
56389
+ friendCount: friends.friends.length,
56429
56390
  groupCount: groups.length,
56430
56391
  messageReceived: app.messageReceivedCount,
56431
56392
  messageSent: app.messageSentCount,
@@ -57191,7 +57152,7 @@ function createNotificationRoutes(ctx) {
57191
57152
  isDecide: reqItem.isDecide,
57192
57153
  reqType: reqItem.reqType,
57193
57154
  addSource: reqItem.addSource || "",
57194
- flag: `${reqItem.friendUid}|${reqItem.reqTime}`
57155
+ flag: reqItem.friendUid
57195
57156
  };
57196
57157
  }));
57197
57158
  return c.json({
@@ -57242,7 +57203,7 @@ function createNotificationRoutes(ctx) {
57242
57203
  success: false,
57243
57204
  message: "缺少必要参数"
57244
57205
  }, 400);
57245
- await ctx.ntFriendApi.approvalDoubtBuddyReq(uid);
57206
+ await ctx.ntFriendApi.approvalDoubtFriendRequest(uid);
57246
57207
  return c.json({ success: true });
57247
57208
  } catch (e) {
57248
57209
  ctx.logger.error("处理被过滤好友申请失败:", e);
@@ -57279,12 +57240,7 @@ function createNotificationRoutes(ctx) {
57279
57240
  success: false,
57280
57241
  message: "缺少必要参数"
57281
57242
  }, 400);
57282
- const [friendUid, reqTime] = flag.split("|");
57283
- if (!friendUid) return c.json({
57284
- success: false,
57285
- message: "无效的 flag 参数"
57286
- }, 400);
57287
- await ctx.ntFriendApi.handleFriendRequest(friendUid, reqTime || "0", action === "approve");
57243
+ await ctx.ntFriendApi.approvalFriendRequest(flag, action === "approve");
57288
57244
  return c.json({ success: true });
57289
57245
  } catch (e) {
57290
57246
  ctx.logger.error("处理好友申请失败:", e);
@@ -57483,6 +57439,65 @@ function createEmailRoutes(ctx) {
57483
57439
  return router;
57484
57440
  }
57485
57441
  //#endregion
57442
+ //#region node_modules/@hono/node-server/dist/utils/stream.mjs
57443
+ var pr54206Applied = () => {
57444
+ const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
57445
+ return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
57446
+ };
57447
+ var useReadableToWeb = pr54206Applied();
57448
+ var createStreamBody = (stream, useNativeReadableToWeb = useReadableToWeb) => {
57449
+ if (useNativeReadableToWeb) return Readable.toWeb(stream);
57450
+ let controller;
57451
+ let settled = false;
57452
+ const cleanup = () => {
57453
+ stream.off("data", onData);
57454
+ stream.off("error", onError);
57455
+ stream.off("end", onTerminate);
57456
+ stream.off("close", onTerminate);
57457
+ };
57458
+ const settle = (callback) => {
57459
+ if (settled) return;
57460
+ settled = true;
57461
+ cleanup();
57462
+ callback?.();
57463
+ };
57464
+ const onData = (chunk) => {
57465
+ if (settled || !controller) return;
57466
+ controller.enqueue(chunk);
57467
+ if ((controller.desiredSize ?? 0) <= 0) stream.pause();
57468
+ };
57469
+ const onError = (error) => {
57470
+ settle(() => {
57471
+ controller?.error(error);
57472
+ });
57473
+ };
57474
+ const onTerminate = () => {
57475
+ settle(() => {
57476
+ controller?.close();
57477
+ });
57478
+ };
57479
+ return new ReadableStream({
57480
+ start(streamController) {
57481
+ controller = streamController;
57482
+ stream.on("data", onData);
57483
+ stream.on("error", onError);
57484
+ stream.on("end", onTerminate);
57485
+ stream.on("close", onTerminate);
57486
+ stream.pause();
57487
+ },
57488
+ pull() {
57489
+ if (!settled) stream.resume();
57490
+ },
57491
+ cancel() {
57492
+ settle();
57493
+ const ignoreError = () => {};
57494
+ stream.on("error", ignoreError);
57495
+ stream.once("close", () => stream.off("error", ignoreError));
57496
+ stream.destroy();
57497
+ }
57498
+ });
57499
+ };
57500
+ //#endregion
57486
57501
  //#region node_modules/hono/dist/utils/mime.js
57487
57502
  var getMimeType = (filename, mimes = baseMimes) => {
57488
57503
  const match = filename.match(/\.([a-zA-Z0-9]+?)$/);
@@ -57558,30 +57573,6 @@ var ENCODINGS = {
57558
57573
  gzip: ".gz"
57559
57574
  };
57560
57575
  var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
57561
- var pr54206Applied = () => {
57562
- const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
57563
- return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
57564
- };
57565
- var useReadableToWeb = pr54206Applied();
57566
- var createStreamBody = (stream) => {
57567
- if (useReadableToWeb) return Readable.toWeb(stream);
57568
- return new ReadableStream({
57569
- start(controller) {
57570
- stream.on("data", (chunk) => {
57571
- controller.enqueue(chunk);
57572
- });
57573
- stream.on("error", (err) => {
57574
- controller.error(err);
57575
- });
57576
- stream.on("end", () => {
57577
- controller.close();
57578
- });
57579
- },
57580
- cancel() {
57581
- stream.destroy();
57582
- }
57583
- });
57584
- };
57585
57576
  var getStats = (path) => {
57586
57577
  let stats;
57587
57578
  try {
@@ -57648,6 +57639,7 @@ var serveStatic = (options = { root: "" }) => {
57648
57639
  let result;
57649
57640
  const size = stats.size;
57650
57641
  const range = c.req.header("range") || "";
57642
+ c.header("Last-Modified", stats.mtime.toUTCString());
57651
57643
  if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
57652
57644
  c.header("Content-Length", size.toString());
57653
57645
  c.status(200);
@@ -57657,7 +57649,6 @@ var serveStatic = (options = { root: "" }) => {
57657
57649
  result = c.body(createStreamBody(createReadStream(path)), 200);
57658
57650
  } else {
57659
57651
  c.header("Accept-Ranges", "bytes");
57660
- c.header("Date", stats.birthtime.toUTCString());
57661
57652
  const parts = range.replace(/bytes=/, "").split("-", 2);
57662
57653
  const start = parseInt(parts[0], 10) || 0;
57663
57654
  let end = parseInt(parts[1], 10) || size - 1;
@@ -57836,7 +57827,7 @@ var WebuiServer = class extends Service {
57836
57827
  isDecide: req.isDecide,
57837
57828
  reqType: req.reqType,
57838
57829
  addSource: req.addSource || "",
57839
- flag: `${req.friendUid}|${req.reqTime}`
57830
+ flag: req.friendUid
57840
57831
  }
57841
57832
  });
57842
57833
  } catch (e) {
@@ -58461,7 +58452,7 @@ var require_fetch = /* @__PURE__ */ __commonJSMin(((exports, module) => {
58461
58452
  var require_shared = /* @__PURE__ */ __commonJSMin(((exports, module) => {
58462
58453
  var urllib$2 = __require("url");
58463
58454
  var util$1 = __require("util");
58464
- var fs$4 = __require("fs");
58455
+ var fs$5 = __require("fs");
58465
58456
  var nmfetch = require_fetch();
58466
58457
  var dns$1 = __require("dns");
58467
58458
  var net$4 = __require("net");
@@ -58797,7 +58788,7 @@ var require_shared = /* @__PURE__ */ __commonJSMin(((exports, module) => {
58797
58788
  const parsedDataUri = module.exports.parseDataURI(content.path || content.href);
58798
58789
  if (!parsedDataUri || !parsedDataUri.data) return callback(null, Buffer.from(0));
58799
58790
  return callback(null, parsedDataUri.data);
58800
- } else if (content.path) return resolveStream(fs$4.createReadStream(content.path), callback);
58791
+ } else if (content.path) return resolveStream(fs$5.createReadStream(content.path), callback);
58801
58792
  }
58802
58793
  if (typeof data[key].content === "string" && ![
58803
58794
  "utf8",
@@ -62737,7 +62728,7 @@ var require_le_unix = /* @__PURE__ */ __commonJSMin(((exports, module) => {
62737
62728
  //#region node_modules/nodemailer/lib/mime-node/index.js
62738
62729
  var require_mime_node = /* @__PURE__ */ __commonJSMin(((exports, module) => {
62739
62730
  var crypto$8 = __require("crypto");
62740
- var fs$3 = __require("fs");
62731
+ var fs$4 = __require("fs");
62741
62732
  var punycode = require_punycode();
62742
62733
  var { PassThrough: PassThrough$2 } = __require("stream");
62743
62734
  var shared = require_shared();
@@ -63446,7 +63437,7 @@ var require_mime_node = /* @__PURE__ */ __commonJSMin(((exports, module) => {
63446
63437
  });
63447
63438
  return contentStream;
63448
63439
  }
63449
- return fs$3.createReadStream(content.path);
63440
+ return fs$4.createReadStream(content.path);
63450
63441
  }
63451
63442
  if (content && typeof content.href === "string") {
63452
63443
  if (this.disableUrlAccess) {
@@ -64285,7 +64276,7 @@ var require_dkim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
64285
64276
  var RelaxedBody = require_relaxed_body();
64286
64277
  var sign = require_sign();
64287
64278
  var { PassThrough: PassThrough$1 } = __require("stream");
64288
- var fs$2 = __require("fs");
64279
+ var fs$3 = __require("fs");
64289
64280
  var path$2 = __require("path");
64290
64281
  var crypto$5 = __require("crypto");
64291
64282
  var DKIM_ALGO = "sha256";
@@ -64318,10 +64309,10 @@ var require_dkim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
64318
64309
  }
64319
64310
  cleanup() {
64320
64311
  if (!this.cache || !this.cachePath) return;
64321
- fs$2.unlink(this.cachePath, () => false);
64312
+ fs$3.unlink(this.cachePath, () => false);
64322
64313
  }
64323
64314
  createReadCache() {
64324
- this.cache = fs$2.createReadStream(this.cachePath);
64315
+ this.cache = fs$3.createReadStream(this.cachePath);
64325
64316
  this.cache.once("error", (err) => {
64326
64317
  this.cleanup();
64327
64318
  this.output.emit("error", err);
@@ -64367,7 +64358,7 @@ var require_dkim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
64367
64358
  }
64368
64359
  createWriteCache() {
64369
64360
  this.output.usingCache = true;
64370
- this.cache = fs$2.createWriteStream(this.cachePath);
64361
+ this.cache = fs$3.createWriteStream(this.cachePath);
64371
64362
  this.cache.once("error", (err) => {
64372
64363
  this.cleanup();
64373
64364
  this.relaxedBody.unpipe(this.cache);
@@ -69648,6 +69639,71 @@ function FriendMixin(Base) {
69648
69639
  url: `https://${download.downloadDns}/ftn_handler/${download.downloadUrl.toString("hex")}/?fname=${encodeURIComponent(fileName)}`
69649
69640
  };
69650
69641
  }
69642
+ async setFriendRequest(targetUid, accept) {
69643
+ const body = Oidb.SetFriendRequestReq.encode({
69644
+ targetUid,
69645
+ accept
69646
+ });
69647
+ const data = Oidb.Base.encode({
69648
+ command: 2909,
69649
+ subCommand: 44,
69650
+ body
69651
+ });
69652
+ await this.httpSendPB("OidbSvcTrpcTcp.0xb5d_44", data);
69653
+ }
69654
+ async setFilteredFriendRequestReq(selfUid, requestUid) {
69655
+ const body = Oidb.SetFilteredFriendRequestReq.encode({
69656
+ selfUid,
69657
+ requestUid
69658
+ });
69659
+ const data = Oidb.Base.encode({
69660
+ command: 3442,
69661
+ subCommand: 0,
69662
+ body
69663
+ });
69664
+ await this.httpSendPB("OidbSvcTrpcTcp.0xd72_0", data);
69665
+ }
69666
+ async fetchFriends() {
69667
+ const body = Oidb.IncPullReq.encode({
69668
+ reqCount: 500,
69669
+ flag: 1,
69670
+ requestBiz: [{
69671
+ bizType: 1,
69672
+ bizData: { extBusi: [
69673
+ 102,
69674
+ 103,
69675
+ 20002,
69676
+ 20009,
69677
+ 20031,
69678
+ 20037,
69679
+ 27394
69680
+ ] }
69681
+ }]
69682
+ });
69683
+ const data = Oidb.Base.encode({
69684
+ command: 4052,
69685
+ subCommand: 1,
69686
+ body
69687
+ });
69688
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0xfd4_1", data);
69689
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
69690
+ return Oidb.IncPullResp.decode(oidbRespBody);
69691
+ }
69692
+ async getFriendRecommendContactArk(uin) {
69693
+ const body = Oidb.GetFriendRecommendContactArkReq.encode({
69694
+ uin,
69695
+ phoneNumber: "-",
69696
+ jumpUrl: `mqqapi://card/show_pslcard?src_type=internal&source=sharecard&version=1&uin=${uin}`
69697
+ });
69698
+ const data = Oidb.Base.encode({
69699
+ command: 4790,
69700
+ subCommand: 0,
69701
+ body
69702
+ });
69703
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0x12b6_0", data);
69704
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
69705
+ return Oidb.GetFriendRecommendContactArkResp.decode(oidbRespBody);
69706
+ }
69651
69707
  };
69652
69708
  }
69653
69709
  //#endregion
@@ -69859,7 +69915,7 @@ var NTV2RichMedia;
69859
69915
  network: convertIPv4(subFileInfo.ipv4s),
69860
69916
  msgInfoBody: upload.msgInfo.msgInfoBody,
69861
69917
  blockSize,
69862
- hash: { fileSha1: [] }
69918
+ hash: { fileSha1: [Buffer.alloc(0)] }
69863
69919
  };
69864
69920
  else return {
69865
69921
  fileUuid: index.fileUuid,
@@ -69867,7 +69923,7 @@ var NTV2RichMedia;
69867
69923
  network: convertIPv4(upload.ipv4s),
69868
69924
  msgInfoBody: upload.msgInfo.msgInfoBody,
69869
69925
  blockSize,
69870
- hash: { fileSha1: [] }
69926
+ hash: { fileSha1: [Buffer.alloc(0)] }
69871
69927
  };
69872
69928
  }
69873
69929
  _NTV2RichMedia.generateExt = generateExt;
@@ -69987,8 +70043,7 @@ function MediaMixin(Base) {
69987
70043
  });
69988
70044
  const res = await this.httpSendPB("OidbSvcTrpcTcp.0x126d_200", data);
69989
70045
  const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
69990
- const { download } = Media.NTV2RichMediaResp.decode(oidbRespBody);
69991
- return `https://${download?.info?.domain}${download?.info?.urlPath}${download?.rKeyParam}`;
70046
+ return Media.NTV2RichMediaResp.decode(oidbRespBody);
69992
70047
  }
69993
70048
  async getGroupPttUrl(fileUuid) {
69994
70049
  const body = Media.NTV2RichMediaReq.encode({
@@ -70021,8 +70076,7 @@ function MediaMixin(Base) {
70021
70076
  });
70022
70077
  const res = await this.httpSendPB("OidbSvcTrpcTcp.0x126e_200", data);
70023
70078
  const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70024
- const { download } = Media.NTV2RichMediaResp.decode(oidbRespBody);
70025
- return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
70079
+ return Media.NTV2RichMediaResp.decode(oidbRespBody);
70026
70080
  }
70027
70081
  async getGroupVideoUrl(fileUuid) {
70028
70082
  const body = Media.NTV2RichMediaReq.encode({
@@ -70055,8 +70109,7 @@ function MediaMixin(Base) {
70055
70109
  });
70056
70110
  const res = await this.httpSendPB("OidbSvcTrpcTcp.0x11ea_200", data);
70057
70111
  const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70058
- const { download } = Media.NTV2RichMediaResp.decode(oidbRespBody);
70059
- return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
70112
+ return Media.NTV2RichMediaResp.decode(oidbRespBody);
70060
70113
  }
70061
70114
  async getPrivateVideoUrl(fileUuid) {
70062
70115
  const body = Media.NTV2RichMediaReq.encode({
@@ -70092,8 +70145,7 @@ function MediaMixin(Base) {
70092
70145
  });
70093
70146
  const res = await this.httpSendPB("OidbSvcTrpcTcp.0x11e9_200", data);
70094
70147
  const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70095
- const { download } = Media.NTV2RichMediaResp.decode(oidbRespBody);
70096
- return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
70148
+ return Media.NTV2RichMediaResp.decode(oidbRespBody);
70097
70149
  }
70098
70150
  async getHighwaySession() {
70099
70151
  const data = Media.HighwaySessionReq.encode({ reqBody: {
@@ -70277,6 +70329,152 @@ function MediaMixin(Base) {
70277
70329
  sha3CheckSum
70278
70330
  };
70279
70331
  }
70332
+ async getGroupImageUploadInfo(groupCode, filePath) {
70333
+ const peer = {
70334
+ chatType: ChatType.Group,
70335
+ peerUid: groupCode,
70336
+ guildId: ""
70337
+ };
70338
+ const body = await NTV2RichMedia.buildUploadReq(peer, {
70339
+ type: "image",
70340
+ filePath
70341
+ }, { pic: {
70342
+ summary: "[图片]",
70343
+ bytesPbReserveC2c: Buffer.from([
70344
+ 8,
70345
+ 0,
70346
+ 24,
70347
+ 0,
70348
+ 32,
70349
+ 0,
70350
+ 74,
70351
+ 0,
70352
+ 80,
70353
+ 0,
70354
+ 98,
70355
+ 0,
70356
+ 146,
70357
+ 1,
70358
+ 0,
70359
+ 154,
70360
+ 1,
70361
+ 0,
70362
+ 170,
70363
+ 1,
70364
+ 12,
70365
+ 8,
70366
+ 0,
70367
+ 18,
70368
+ 0,
70369
+ 24,
70370
+ 0,
70371
+ 32,
70372
+ 0,
70373
+ 40,
70374
+ 0,
70375
+ 58,
70376
+ 0
70377
+ ])
70378
+ } });
70379
+ const data = Oidb.Base.encode({
70380
+ command: 4548,
70381
+ subCommand: 100,
70382
+ body
70383
+ });
70384
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0x11c4_100", data);
70385
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70386
+ const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
70387
+ return {
70388
+ info: upload.msgInfo,
70389
+ compat: upload.compatQMsg,
70390
+ ext: NTV2RichMedia.generateExt(upload)
70391
+ };
70392
+ }
70393
+ async getC2CImageUploadInfo(peerUid, filePath) {
70394
+ const peer = {
70395
+ chatType: ChatType.C2C,
70396
+ peerUid,
70397
+ guildId: ""
70398
+ };
70399
+ const body = await NTV2RichMedia.buildUploadReq(peer, {
70400
+ type: "image",
70401
+ filePath
70402
+ }, { pic: {
70403
+ summary: "[图片]",
70404
+ bytesPbReserveC2c: Buffer.from([
70405
+ 8,
70406
+ 0,
70407
+ 24,
70408
+ 0,
70409
+ 32,
70410
+ 0,
70411
+ 74,
70412
+ 0,
70413
+ 80,
70414
+ 0,
70415
+ 98,
70416
+ 0,
70417
+ 146,
70418
+ 1,
70419
+ 0,
70420
+ 154,
70421
+ 1,
70422
+ 0,
70423
+ 170,
70424
+ 1,
70425
+ 12,
70426
+ 8,
70427
+ 0,
70428
+ 18,
70429
+ 0,
70430
+ 24,
70431
+ 0,
70432
+ 32,
70433
+ 0,
70434
+ 40,
70435
+ 0,
70436
+ 58,
70437
+ 0
70438
+ ])
70439
+ } });
70440
+ const data = Oidb.Base.encode({
70441
+ command: 4549,
70442
+ subCommand: 100,
70443
+ body
70444
+ });
70445
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0x11c5_100", data);
70446
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70447
+ const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
70448
+ return {
70449
+ info: upload.msgInfo,
70450
+ compat: upload.compatQMsg,
70451
+ ext: NTV2RichMedia.generateExt(upload)
70452
+ };
70453
+ }
70454
+ async imageOcr(imageUrl) {
70455
+ const body = Oidb.ImageOcrReq.encode({
70456
+ version: 1,
70457
+ client: 0,
70458
+ entrance: 1,
70459
+ ocrReqBody: {
70460
+ imageUrl,
70461
+ originMd5: "",
70462
+ afterCompressMd5: "",
70463
+ afterCompressFileSize: "",
70464
+ afterCompressWeight: "",
70465
+ afterCompressHeight: "",
70466
+ isCut: false
70467
+ }
70468
+ });
70469
+ const data = Oidb.Base.encode({
70470
+ command: 3591,
70471
+ subCommand: 0,
70472
+ body
70473
+ });
70474
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0xe07_0", data);
70475
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70476
+ return Oidb.ImageOcrResp.decode(oidbRespBody);
70477
+ }
70280
70478
  };
70281
70479
  }
70282
70480
  //#endregion
@@ -70441,6 +70639,22 @@ function UserMixin(Base) {
70441
70639
  };
70442
70640
  }
70443
70641
  //#endregion
70642
+ //#region src/main/pmhq/mixins/system.ts
70643
+ function SystemMixin(Base) {
70644
+ return class extends Base {
70645
+ async fetchPins() {
70646
+ const data = Oidb.Base.encode({
70647
+ command: 4787,
70648
+ subCommand: 0,
70649
+ body: Buffer.alloc(0)
70650
+ });
70651
+ const res = await this.httpSendPB("OidbSvcTrpcTcp.0x12b3_0", data);
70652
+ const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
70653
+ return Oidb.FetchPinsResp.decode(oidbRespBody);
70654
+ }
70655
+ };
70656
+ }
70657
+ //#endregion
70444
70658
  //#region src/main/pmhq/index.ts
70445
70659
  function applyMixins(Base, mixins) {
70446
70660
  return mixins.reduce((acc, mixin) => mixin(acc), Base);
@@ -70450,7 +70664,8 @@ var PMHQ = applyMixins(PMHQBase, [
70450
70664
  FriendMixin,
70451
70665
  MediaMixin,
70452
70666
  MessageMixin,
70453
- UserMixin
70667
+ UserMixin,
70668
+ SystemMixin
70454
70669
  ]);
70455
70670
  //#endregion
70456
70671
  //#region node_modules/@cordisjs/plugin-timer/lib/index.js
@@ -70599,7 +70814,6 @@ async function onLoad() {
70599
70814
  ctx.plugin(Config);
70600
70815
  ctx.plugin(PMHQ);
70601
70816
  ctx.plugin(NTQQFileApi);
70602
- ctx.plugin(NTQQFileCacheApi);
70603
70817
  ctx.plugin(NTQQFriendApi);
70604
70818
  ctx.plugin(NTQQGroupApi);
70605
70819
  ctx.plugin(NTLoginApi);