onebots 0.4.22 → 0.4.25

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.
Files changed (84) hide show
  1. package/README.md +129 -72
  2. package/lib/adapter.d.ts +55 -0
  3. package/lib/adapter.js +60 -0
  4. package/lib/adapters/icqq/index.d.ts +36 -0
  5. package/lib/adapters/icqq/index.js +300 -0
  6. package/lib/adapters/icqq/utils.d.ts +6 -0
  7. package/lib/adapters/icqq/utils.js +26 -0
  8. package/lib/adapters/qq/bot.d.ts +24 -0
  9. package/lib/adapters/qq/bot.js +20 -0
  10. package/lib/adapters/qq/constans.d.ts +69 -0
  11. package/lib/adapters/qq/constans.js +128 -0
  12. package/lib/adapters/qq/elements.d.ts +125 -0
  13. package/lib/adapters/qq/elements.js +8 -0
  14. package/lib/adapters/qq/entries/channel.d.ts +17 -0
  15. package/lib/adapters/qq/entries/channel.js +2 -0
  16. package/lib/adapters/qq/entries/friend.d.ts +8 -0
  17. package/lib/adapters/qq/entries/friend.js +2 -0
  18. package/lib/adapters/qq/entries/group.d.ts +6 -0
  19. package/lib/adapters/qq/entries/group.js +2 -0
  20. package/lib/adapters/qq/entries/groupMember.d.ts +7 -0
  21. package/lib/adapters/qq/entries/groupMember.js +2 -0
  22. package/lib/adapters/qq/entries/guild.d.ts +21 -0
  23. package/lib/adapters/qq/entries/guild.js +2 -0
  24. package/lib/adapters/qq/entries/guildMember.d.ts +9 -0
  25. package/lib/adapters/qq/entries/guildMember.js +2 -0
  26. package/lib/adapters/qq/entries/user.d.ts +9 -0
  27. package/lib/adapters/qq/entries/user.js +2 -0
  28. package/lib/adapters/qq/event.d.ts +28 -0
  29. package/lib/adapters/qq/event.js +24 -0
  30. package/lib/adapters/qq/index.d.ts +35 -0
  31. package/lib/adapters/qq/index.js +170 -0
  32. package/lib/adapters/qq/message.d.ts +83 -0
  33. package/lib/adapters/qq/message.js +272 -0
  34. package/lib/adapters/qq/qqBot.d.ts +122 -0
  35. package/lib/adapters/qq/qqBot.js +438 -0
  36. package/lib/adapters/qq/sessionManager.d.ts +33 -0
  37. package/lib/adapters/qq/sessionManager.js +257 -0
  38. package/lib/adapters/qq/types.d.ts +45 -0
  39. package/lib/adapters/qq/types.js +2 -0
  40. package/lib/adapters/qq/utils.d.ts +12 -0
  41. package/lib/adapters/qq/utils.js +86 -0
  42. package/lib/bin.js +17 -2
  43. package/lib/config.sample.yaml +11 -5
  44. package/lib/db.js +6 -6
  45. package/lib/index.d.ts +5 -5
  46. package/lib/onebot.d.ts +30 -22
  47. package/lib/onebot.js +42 -165
  48. package/lib/server/app.d.ts +22 -12
  49. package/lib/server/app.js +97 -71
  50. package/lib/service/V11/action/common.d.ts +11 -12
  51. package/lib/service/V11/action/common.js +19 -65
  52. package/lib/service/V11/action/friend.d.ts +6 -14
  53. package/lib/service/V11/action/friend.js +6 -16
  54. package/lib/service/V11/action/group.d.ts +20 -23
  55. package/lib/service/V11/action/group.js +20 -30
  56. package/lib/service/V11/action/index.d.ts +1 -1
  57. package/lib/service/V11/db_entities.d.ts +1 -1
  58. package/lib/service/V11/db_entities.js +1 -1
  59. package/lib/service/V11/db_sqlite.d.ts +1 -1
  60. package/lib/service/V11/db_sqlite.js +5 -7
  61. package/lib/service/V11/index.d.ts +46 -14
  62. package/lib/service/V11/index.js +163 -134
  63. package/lib/service/V12/action/common.d.ts +3 -67
  64. package/lib/service/V12/action/common.js +9 -63
  65. package/lib/service/V12/action/friend.d.ts +4 -10
  66. package/lib/service/V12/action/friend.js +4 -12
  67. package/lib/service/V12/action/group.d.ts +19 -21
  68. package/lib/service/V12/action/group.js +19 -27
  69. package/lib/service/V12/action/guild.d.ts +40 -13
  70. package/lib/service/V12/action/guild.js +99 -11
  71. package/lib/service/V12/action/index.d.ts +1 -1
  72. package/lib/service/V12/index.d.ts +37 -13
  73. package/lib/service/V12/index.js +63 -94
  74. package/lib/service.d.ts +7 -2
  75. package/lib/service.js +5 -1
  76. package/lib/types.d.ts +2 -2
  77. package/lib/types.js +3 -3
  78. package/lib/utils.d.ts +7 -4
  79. package/lib/utils.js +18 -1
  80. package/package.json +74 -70
  81. package/lib/service/V11/utils.d.ts +0 -9
  82. package/lib/service/V11/utils.js +0 -31
  83. package/lib/service/V12/utils.d.ts +0 -8
  84. package/lib/service/V12/utils.js +0 -47
package/lib/onebot.js CHANGED
@@ -1,39 +1,22 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
24
12
  };
13
+ var _OneBot_logger;
25
14
  Object.defineProperty(exports, "__esModule", { value: true });
26
15
  exports.BOOLS = exports.OneBotStatus = exports.OneBot = exports.NotFoundError = void 0;
27
- require("icqq-cq-enable");
28
16
  const events_1 = require("events");
29
- const app_1 = require("./server/app");
30
17
  const utils_1 = require("./utils");
31
- const path_1 = require("path");
32
- const icqq_1 = require("icqq");
33
- const icqq_2 = require("icqq");
34
18
  const V11_1 = require("./service/V11");
35
19
  const V12_1 = require("./service/V12");
36
- const process = __importStar(require("process"));
37
20
  class NotFoundError extends Error {
38
21
  constructor() {
39
22
  super(...arguments);
@@ -42,182 +25,76 @@ class NotFoundError extends Error {
42
25
  }
43
26
  exports.NotFoundError = NotFoundError;
44
27
  class OneBot extends events_1.EventEmitter {
45
- constructor(app, uin, config) {
28
+ get app() {
29
+ return this.adapter.app;
30
+ }
31
+ get platform() {
32
+ return this.adapter.platform;
33
+ }
34
+ get logger() {
35
+ return __classPrivateFieldSet(this, _OneBot_logger, __classPrivateFieldGet(this, _OneBot_logger, "f") || this.adapter.getLogger(this.uin), "f");
36
+ }
37
+ constructor(adapter, uin, version_configs) {
46
38
  super();
47
- this.app = app;
39
+ this.adapter = adapter;
48
40
  this.uin = uin;
49
- config = [].concat(config);
50
- const protocolConfig = {
51
- data_dir: (0, path_1.join)(app_1.App.configDir, 'data'),
52
- ...this.app.config.general.protocol
53
- };
54
- this.config = config.map(c => {
41
+ _OneBot_logger.set(this, void 0);
42
+ this.config = version_configs.map(c => {
55
43
  if (!c.version)
56
44
  c.version = 'V11';
57
- if (!c.protocol)
58
- c.protocol = {};
59
- if (c.password)
60
- this.password = c.password;
61
- Object.assign(protocolConfig, c.protocol);
62
45
  switch (c.version) {
63
46
  case 'V11':
64
- return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.app.config.general.V11), c);
47
+ return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.adapter.app.config.general.V11), c);
65
48
  case 'V12':
66
- return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.app.config.general.V12), c);
49
+ return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.adapter.app.config.general.V12), c);
67
50
  default:
68
51
  throw new Error('不支持的oneBot版本:' + c.version);
69
52
  }
70
53
  });
71
- this.client = new icqq_1.Client(protocolConfig);
72
54
  this.instances = this.config.map(c => {
73
55
  switch (c.version) {
74
56
  case 'V11':
75
- return new V11_1.V11(this, this.client, c);
57
+ return new V11_1.V11(this, c);
76
58
  case 'V12':
77
- return new V12_1.V12(this, this.client, c);
59
+ return new V12_1.V12(this, c);
78
60
  default:
79
61
  throw new Error('不支持的oneBot版本:' + c.version);
80
62
  }
81
63
  });
82
64
  this.status = OneBotStatus.Good;
83
65
  }
84
- start() {
85
- this.startListen();
86
- const disposeArr = [];
87
- const clean = () => {
88
- while (disposeArr.length) {
89
- disposeArr.shift()();
90
- }
91
- };
92
- this.client.trap('system.login.qrcode', function qrcodeHelper() {
93
- console.log('扫码后回车继续');
94
- process.stdin.once('data', () => {
95
- this.login();
96
- });
97
- disposeArr.push(() => {
98
- this.off('system.login.qrcode', qrcodeHelper);
99
- });
100
- });
101
- this.client.trap('system.login.device', function deviceHelper(e) {
102
- console.log('请选择验证方式:1.短信验证 2.url验证');
103
- process.stdin.once('data', (buf) => {
104
- const input = buf.toString().trim();
105
- if (input === '1') {
106
- this.sendSmsCode();
107
- console.log('请输入短信验证码:');
108
- process.stdin.once('data', buf => {
109
- this.submitSmsCode(buf.toString().trim());
110
- });
111
- }
112
- else {
113
- console.log(`请前往:${e.url} 完成验证后回车继续`);
114
- process.stdin.once('data', () => {
115
- this.login();
116
- });
117
- }
118
- });
119
- disposeArr.push(() => {
120
- this.off('system.login.device', deviceHelper);
121
- });
122
- });
123
- this.client.trap('system.login.error', function errorHandler(e) {
124
- if (e.message.includes('密码错误')) {
125
- process.stdin.once('data', (e) => {
126
- this.login(e.toString().trim());
127
- });
128
- }
129
- else {
130
- process.exit();
131
- }
132
- this.off('system.login.error', errorHandler);
133
- });
134
- this.client.trap('system.login.slider', function sliderHelper(e) {
135
- console.log('请输入滑块验证返回的ticket');
136
- process.stdin.once('data', (e) => {
137
- this.submitSlider(e.toString().trim());
138
- });
139
- disposeArr.push(() => {
140
- this.off('system.login.slider', sliderHelper);
141
- });
142
- });
143
- this.client.trap('system.online', clean);
144
- return new Promise(async (resolve) => {
145
- const callback = (result) => {
146
- if (timer) {
147
- clearTimeout(timer);
148
- timer = null;
149
- }
150
- resolve(result);
151
- while (disposes.length) {
152
- const dispose = disposes.shift();
153
- dispose();
154
- }
155
- };
156
- let timer = setTimeout(() => {
157
- callback([false, '登录超时']);
158
- }, this.app.config.timeout * 1000);
159
- await this.client.login(this.uin, this.password);
160
- const disposes = [this.client.trapOnce('system.online', () => { callback([true, null]); }),
161
- this.client.trapOnce('system.login.error', (e) => callback([false, e.message]))];
162
- });
163
- }
164
- startListen() {
165
- this.client.on('system.online', this.system_online.bind(this, "system.online"));
166
- this.client.trap('system', this.dispatch.bind(this, 'system'));
167
- this.client.trap('notice', this.dispatch.bind(this, 'notice'));
168
- this.client.trap('request', this.dispatch.bind(this, 'request'));
169
- this.client.trap('message', this.dispatch.bind(this, 'message'));
66
+ async start() {
170
67
  for (const instance of this.instances) {
171
- instance.start(this.instances.length > 1 ? '/' + instance.version : undefined);
68
+ instance.start();
172
69
  }
173
70
  }
174
71
  async stop(force) {
175
72
  for (const instance of this.instances) {
176
73
  await instance.stop(force);
177
74
  }
178
- this.client.logout(force);
179
75
  }
180
- system_online(event, data) {
181
- for (const instance of this.instances) {
182
- instance.system_online(data);
183
- }
76
+ getGroupList(version) {
77
+ return this.adapter.getGroupList(this.uin, version);
78
+ }
79
+ getFriendList(version) {
80
+ return this.adapter.getFriendList(this.uin, version);
184
81
  }
185
82
  async dispatch(event, data) {
186
- let group_id = data["group_id"];
187
83
  for (const instance of this.instances) {
188
- if (group_id) {
189
- // 群消息派发白名单
190
- let lst = instance.config.group_whitelist;
191
- if (lst && lst.length > 0 && !lst.includes(group_id))
192
- continue;
193
- }
194
- const result = instance.format(event, data);
195
- if (data.source) { // 有 data.source 字段代表这是个回复
196
- switch (data.message_type) {
197
- case 'group':
198
- data.message.unshift({
199
- type: 'reply',
200
- seq: data.source.seq,
201
- id: (0, icqq_2.genGroupMessageId)(data.group_id, data.source.user_id, data.source.seq, data.source.rand, data.source.time)
202
- });
203
- break;
204
- case 'private':
205
- data.message.unshift({
206
- type: 'reply',
207
- seq: data.source.seq,
208
- id: (0, icqq_2.genDmMessageId)(data.source.user_id, data.source.seq, data.source.rand, data.source.time)
209
- });
210
- break;
211
- }
212
- }
213
- instance.dispatch(result);
84
+ instance.dispatch(instance.format(event, this.adapter.formatEventPayload(instance.version, event, data)));
214
85
  }
215
86
  }
216
87
  }
217
88
  exports.OneBot = OneBot;
89
+ _OneBot_logger = new WeakMap();
218
90
  var OneBotStatus;
219
91
  (function (OneBotStatus) {
220
92
  OneBotStatus[OneBotStatus["Good"] = 0] = "Good";
221
93
  OneBotStatus[OneBotStatus["Bad"] = 1] = "Bad";
94
+ OneBotStatus["Online"] = "online";
222
95
  })(OneBotStatus || (exports.OneBotStatus = OneBotStatus = {}));
96
+ (function (OneBot) {
97
+ OneBot.UnsupportedMethodError = new Error('不支持的方法');
98
+ OneBot.UnsupportedVersionError = new Error('不支持的oneBot版本');
99
+ })(OneBot || (exports.OneBot = OneBot = {}));
223
100
  exports.BOOLS = ["no_cache", "auto_escape", "as_long", "enable", "reject_add_request", "is_dismiss", "approve", "block"];
@@ -4,12 +4,13 @@ import Koa from 'koa';
4
4
  import "reflect-metadata";
5
5
  import { Logger } from "log4js";
6
6
  import { Server } from "http";
7
- import { Config as IcqqConfig } from "icqq";
8
7
  import { OneBot } from "../onebot";
8
+ import { Class } from "../utils";
9
9
  import { Router } from "./router";
10
10
  import { V11 } from "../service/V11";
11
11
  import { V12 } from "../service/V12";
12
- import { LogLevel, MayBeArray } from "../types";
12
+ import { LogLevel } from "../types";
13
+ import { Adapter } from "../adapter";
13
14
  export interface KoaOptions {
14
15
  env?: string;
15
16
  keys?: string[];
@@ -18,27 +19,33 @@ export interface KoaOptions {
18
19
  proxyIpHeader?: string;
19
20
  maxIpsCount?: number;
20
21
  }
22
+ type AdapterClass = Class<Adapter>;
21
23
  export declare class App extends Koa {
22
24
  config: App.Config;
23
25
  readonly httpServer: Server;
24
26
  logger: Logger;
25
27
  static configDir: string;
26
28
  static configPath: string;
27
- oneBots: OneBot<any>[];
29
+ adapters: Map<string, Adapter>;
28
30
  router: Router;
29
31
  constructor(config?: App.Config);
30
- getLogger(uin: number | string, version?: string): Logger;
31
- private getBots;
32
+ getLogger(patform: string): Logger;
33
+ private getConfigMaps;
32
34
  private createOneBots;
33
- addAccount(uin: number | `${number}`, config: MayBeArray<OneBot.Config<OneBot.Version>>): void;
34
- updateAccount(uin: number | `${number}`, config: MayBeArray<OneBot.Config<OneBot.Version>>): void;
35
- removeAccount(uin: number | `${number}`, force?: boolean): void;
36
- createOneBot(uin: number, config: MayBeArray<OneBot.Config<OneBot.Version>>): OneBot<OneBot.Version>;
35
+ addAccount<P extends string>(platform: P, uin: string, config: Adapter.Configs[P]): void;
36
+ updateAccount<P extends string>(platform: P, uin: string, config: Adapter.Configs[P]): void;
37
+ removeAccount(platform: string, uin: string, force?: boolean): void;
38
+ createOneBot<P extends string>(platform: P, uin: string, config: Adapter.Config): OneBot<OneBot.Version>;
39
+ get oneBots(): OneBot<OneBot.Version>[];
40
+ findOrCreateAdapter<P extends string>(platform: P, config?: Adapter.Config): Adapter<string>;
37
41
  start(): Promise<void>;
38
42
  }
39
- export declare function createApp(config?: App.Config | string): App;
43
+ export declare function createOnebots(config?: App.Config | string): App;
40
44
  export declare function defineConfig(config: App.Config): App.Config;
41
45
  export declare namespace App {
46
+ const ADAPTERS: Map<string, AdapterClass>;
47
+ interface Adapters<P extends string = string> extends Map<P, Adapter<P>> {
48
+ }
42
49
  type Config = {
43
50
  port?: number;
44
51
  path?: string;
@@ -47,8 +54,11 @@ export declare namespace App {
47
54
  general?: {
48
55
  V11?: V11.Config;
49
56
  V12?: V12.Config;
50
- protocol?: IcqqConfig;
51
57
  };
52
- } & KoaOptions & Record<`${number}`, MayBeArray<OneBot.Config<OneBot.Version>>>;
58
+ } & KoaOptions & Record<`${string}.${string}`, Adapter.Config>;
53
59
  const defaultConfig: Config;
60
+ function registerAdapter(name: string): void;
61
+ function registerAdapter<T extends string>(platform: T, adapter: AdapterClass): void;
62
+ function loadAdapter<T extends string>(platform: string): Class<Adapter<T>>;
54
63
  }
64
+ export {};
package/lib/server/app.js CHANGED
@@ -25,9 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
- var _a;
29
28
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.defineConfig = exports.createApp = exports.App = void 0;
29
+ exports.defineConfig = exports.createOnebots = exports.App = void 0;
31
30
  const koa_1 = __importDefault(require("koa"));
32
31
  const os = __importStar(require("os"));
33
32
  require("reflect-metadata");
@@ -36,7 +35,6 @@ const log4js_1 = require("log4js");
36
35
  const http_1 = require("http");
37
36
  const js_yaml_1 = __importDefault(require("js-yaml"));
38
37
  const koa_bodyparser_1 = __importDefault(require("koa-bodyparser"));
39
- const onebot_1 = require("../onebot");
40
38
  const mime = require('mime-types');
41
39
  const utils_1 = require("../utils");
42
40
  const router_1 = require("./router");
@@ -47,9 +45,9 @@ const path = __importStar(require("path"));
47
45
  class App extends koa_1.default {
48
46
  constructor(config = {}) {
49
47
  super(config);
50
- this.oneBots = [];
51
- this.config = (0, utils_1.deepMerge)((0, utils_1.deepClone)(_a.defaultConfig), config);
52
- this.logger = (0, log4js_1.getLogger)('[icqq-OneBot]');
48
+ this.adapters = new Map();
49
+ this.config = (0, utils_1.deepMerge)((0, utils_1.deepClone)(App.defaultConfig), config);
50
+ this.logger = (0, log4js_1.getLogger)('[OneBots]');
53
51
  this.logger.level = this.config.log_level;
54
52
  this.router = new router_1.Router({ prefix: config.path });
55
53
  this.use((0, koa_bodyparser_1.default)())
@@ -58,67 +56,70 @@ class App extends koa_1.default {
58
56
  this.httpServer = (0, http_1.createServer)(this.callback());
59
57
  this.createOneBots();
60
58
  }
61
- getLogger(uin, version = '') {
62
- const logger = (0, log4js_1.getLogger)(`[icqq-OneBot${version}:${uin}]`);
59
+ getLogger(patform) {
60
+ const logger = (0, log4js_1.getLogger)(`[OneBots:${patform}]`);
63
61
  logger.level = this.config.log_level;
64
62
  return logger;
65
63
  }
66
- getBots() {
67
- const result = new Map();
68
- Object.entries(this.config).forEach(([key, value]) => {
69
- if (parseInt(key).toString() === key && value && typeof value === 'object') {
70
- result.set(parseInt(key), value);
71
- }
72
- });
64
+ getConfigMaps() {
65
+ const result = [];
66
+ for (const [key, value] of Object.entries(this.config)) {
67
+ const [adapter, ...uinArr] = key.split('.');
68
+ const uin = uinArr.join('.');
69
+ if (!uin)
70
+ continue;
71
+ result.push([adapter, uin, value]);
72
+ }
73
73
  return result;
74
74
  }
75
75
  createOneBots() {
76
- for (const [uin, config] of this.getBots()) {
77
- this.createOneBot(uin, config);
76
+ for (const [platform, uin, config] of this.getConfigMaps()) {
77
+ this.createOneBot(platform, uin, config);
78
78
  }
79
79
  }
80
- addAccount(uin, config) {
81
- if (typeof uin !== "number")
82
- uin = Number(uin);
83
- if (Number.isNaN(uin))
84
- throw new Error('无效的账号');
85
- if (this.oneBots.find(oneBot => oneBot.uin === uin))
86
- throw new Error('账户已存在');
80
+ addAccount(platform, uin, config) {
87
81
  this.config[uin] = config;
88
- const oneBot = this.createOneBot(uin, config);
89
- oneBot.startListen();
90
- (0, fs_1.writeFileSync)(_a.configPath, js_yaml_1.default.dump((0, utils_1.deepClone)(this.config)));
82
+ const oneBot = this.createOneBot(platform, uin, config);
83
+ oneBot.start();
84
+ (0, fs_1.writeFileSync)(App.configPath, js_yaml_1.default.dump((0, utils_1.deepClone)(this.config)));
91
85
  }
92
- updateAccount(uin, config) {
93
- if (typeof uin !== "number")
94
- uin = Number(uin);
95
- if (Number.isNaN(uin))
96
- throw new Error('无效的账号');
97
- const oneBot = this.oneBots.find(oneBot => oneBot.uin === uin);
86
+ updateAccount(platform, uin, config) {
87
+ const adapter = this.findOrCreateAdapter(platform);
88
+ const oneBot = adapter.oneBots.get(uin);
98
89
  if (!oneBot)
99
- return this.addAccount(uin, config);
90
+ return this.addAccount(platform, uin, config);
100
91
  const newConfig = (0, utils_1.deepMerge)(this.config[uin], config);
101
- this.removeAccount(uin);
102
- this.addAccount(uin, newConfig);
92
+ this.removeAccount(platform, uin);
93
+ this.addAccount(platform, uin, newConfig);
103
94
  }
104
- removeAccount(uin, force) {
105
- if (typeof uin !== "number")
106
- uin = Number(uin);
107
- if (Number.isNaN(uin))
108
- throw new Error('无效的账号');
109
- const currentIdx = this.oneBots.findIndex(oneBot => oneBot.uin === uin);
110
- if (currentIdx < 0)
111
- throw new Error('账户不存在');
112
- const oneBot = this.oneBots[currentIdx];
95
+ removeAccount(platform, uin, force) {
96
+ const adapter = this.findOrCreateAdapter(platform);
97
+ const oneBot = adapter.oneBots.get(uin);
98
+ if (!oneBot)
99
+ throw new Error(`未找到账号${uin}`);
113
100
  oneBot.stop(force);
114
101
  delete this.config[uin];
115
- this.oneBots.splice(currentIdx, 1);
116
- (0, fs_1.writeFileSync)(_a.configPath, js_yaml_1.default.dump(this.config));
102
+ adapter.oneBots.delete(uin);
103
+ (0, fs_1.writeFileSync)(App.configPath, js_yaml_1.default.dump(this.config));
117
104
  }
118
- createOneBot(uin, config) {
119
- const oneBot = new onebot_1.OneBot(this, uin, config);
120
- this.oneBots.push(oneBot);
121
- return oneBot;
105
+ createOneBot(platform, uin, config) {
106
+ const adapter = this.findOrCreateAdapter(platform, config);
107
+ return adapter.createOneBot(uin, config.protocol, config.versions);
108
+ }
109
+ get oneBots() {
110
+ return [...this.adapters.values()].map((adapter) => {
111
+ return [...adapter.oneBots.values()];
112
+ }).flat();
113
+ }
114
+ findOrCreateAdapter(platform, config) {
115
+ if (this.adapters.has(platform))
116
+ return this.adapters.get(platform);
117
+ const AdapterClass = App.ADAPTERS.get(platform);
118
+ if (!AdapterClass)
119
+ throw new Error(`未安装适配器(${platform})`);
120
+ const adapter = new AdapterClass(this, config);
121
+ this.adapters.set(platform, adapter);
122
+ return adapter;
122
123
  }
123
124
  async start() {
124
125
  this.httpServer.listen(this.config.port);
@@ -126,18 +127,18 @@ class App extends koa_1.default {
126
127
  ctx.body = this.oneBots.map(bot => {
127
128
  return {
128
129
  uin: bot.uin,
129
- config: bot.config.map(c => (0, utils_1.protectedFields)(c, 'protocol', "access_token")),
130
+ config: bot.config.map(c => (0, utils_1.protectedFields)(c, 'password', 'sign_api_addr', "access_token")),
130
131
  urls: bot.config.map(c => `/${c.version}/${bot.uin}`)
131
132
  };
132
133
  });
133
134
  });
134
135
  this.router.get('/qrcode', (ctx) => {
135
136
  const { uin } = ctx.query;
136
- const uinUrl = path.join(_a.configDir, 'data', uin);
137
+ const uinUrl = path.join(App.configDir, 'data', uin);
137
138
  if (!(0, fs_1.existsSync)(uinUrl)) {
138
139
  return ctx.res.writeHead(400).end('未登录');
139
140
  }
140
- const qrcodePath = path.join(_a.configDir, 'data', uin, 'qrcode.png');
141
+ const qrcodePath = path.join(App.configDir, 'data', uin, 'qrcode.png');
141
142
  let file = null;
142
143
  try {
143
144
  file = (0, fs_2.readFileSync)(qrcodePath); //读取文件
@@ -151,17 +152,17 @@ class App extends koa_1.default {
151
152
  });
152
153
  this.router.get('/detail', (ctx) => {
153
154
  let { uin } = ctx.request.query;
154
- const oneBot = this.oneBots.find(bot => bot.uin === Number(uin));
155
+ const oneBot = this.oneBots.find(bot => bot.uin === String(uin));
155
156
  ctx.body = {
156
157
  uin,
157
- config: oneBot.config.map(c => (0, utils_1.protectedFields)(c, 'protocol', "access_token")),
158
+ config: oneBot.config.map(c => (0, utils_1.protectedFields)(c, "access_token")),
158
159
  urls: oneBot.config.map(c => `/${uin}/${c.version}`)
159
160
  };
160
161
  });
161
162
  this.router.post('/add', (ctx, next) => {
162
163
  const { uin, ...config } = (ctx.request.body || {});
163
164
  try {
164
- this.addAccount(uin, config);
165
+ this.addAccount(config.platform, uin, config);
165
166
  ctx.body = `添加成功`;
166
167
  }
167
168
  catch (e) {
@@ -171,7 +172,7 @@ class App extends koa_1.default {
171
172
  this.router.post('/edit', (ctx, next) => {
172
173
  const { uin, ...config } = (ctx.request.body || {});
173
174
  try {
174
- this.updateAccount(Number(uin), config);
175
+ this.updateAccount(config.platform, uin, config);
175
176
  ctx.body = `修改成功`;
176
177
  }
177
178
  catch (e) {
@@ -179,9 +180,9 @@ class App extends koa_1.default {
179
180
  }
180
181
  });
181
182
  this.router.get('/remove', (ctx, next) => {
182
- const { uin, force } = ctx.request.query;
183
+ const { uin, platform, force } = ctx.request.query;
183
184
  try {
184
- this.removeAccount(Number(uin), Boolean(force));
185
+ this.removeAccount(String(platform), String(uin), Boolean(force));
185
186
  ctx.body = `移除成功`;
186
187
  }
187
188
  catch (e) {
@@ -196,18 +197,15 @@ class App extends koa_1.default {
196
197
  console.error('unhandledRejection', e);
197
198
  });
198
199
  this.logger.mark(`server listen at http://0.0.0.0:${this.config.port}/${this.config.path ? this.config.path : ''}`);
199
- for (const oneBot of this.oneBots) {
200
- const [isSuccess, reason] = await oneBot.start();
201
- if (!isSuccess)
202
- this.logger.warn(`【${oneBot.uin}】: 登录失败,错误信息\n:`, reason);
200
+ for (const [_, adapter] of this.adapters) {
201
+ await adapter.start();
203
202
  }
204
203
  }
205
204
  }
206
205
  exports.App = App;
207
- _a = App;
208
206
  App.configDir = path.join(os.homedir(), '.onebots');
209
- App.configPath = path.join(_a.configDir, 'config.yaml');
210
- function createApp(config = 'config.yaml') {
207
+ App.configPath = path.join(App.configDir, 'config.yaml');
208
+ function createOnebots(config = 'config.yaml') {
211
209
  if (typeof config === 'string') {
212
210
  config = path.resolve(process.cwd(), config);
213
211
  App.configDir = path.dirname(config);
@@ -226,22 +224,50 @@ function createApp(config = 'config.yaml') {
226
224
  }
227
225
  return new App(config);
228
226
  }
229
- exports.createApp = createApp;
227
+ exports.createOnebots = createOnebots;
230
228
  function defineConfig(config) {
231
229
  return config;
232
230
  }
233
231
  exports.defineConfig = defineConfig;
234
232
  (function (App) {
233
+ App.ADAPTERS = new Map();
235
234
  App.defaultConfig = {
236
235
  port: 6727,
237
236
  timeout: 30,
238
237
  general: {
239
238
  V11: V11_1.V11.defaultConfig,
240
239
  V12: V12_1.V12.defaultConfig,
241
- protocol: {
242
- platform: 2
243
- }
244
240
  },
245
241
  log_level: 'info',
246
242
  };
243
+ function registerAdapter(platform, adapter) {
244
+ if (!adapter)
245
+ adapter = App.loadAdapter(platform);
246
+ if (App.ADAPTERS.has(platform)) {
247
+ console.warn(`已存在对应的适配器:${platform}`);
248
+ return this;
249
+ }
250
+ App.ADAPTERS.set(platform, adapter);
251
+ }
252
+ App.registerAdapter = registerAdapter;
253
+ function loadAdapter(platform) {
254
+ const maybeNames = [
255
+ path.join(__dirname, '../adapters', platform),
256
+ `@onebots/adapter-${platform}`,
257
+ `onebots-adapter-${platform}`,
258
+ platform // 别人写的
259
+ ];
260
+ let adapter = null;
261
+ for (const adapterName of maybeNames) {
262
+ try {
263
+ adapter = require(adapterName)?.default;
264
+ break;
265
+ }
266
+ catch { }
267
+ }
268
+ if (!adapter)
269
+ throw new Error(`找不到对应的适配器:${platform}`);
270
+ return adapter;
271
+ }
272
+ App.loadAdapter = loadAdapter;
247
273
  })(App || (exports.App = App = {}));