koishi-plugin-bind-bot 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/export-utils.d.ts +49 -0
- package/lib/export-utils.js +305 -0
- package/lib/force-bind-utils.d.ts +40 -0
- package/lib/force-bind-utils.js +242 -0
- package/lib/handlers/base.handler.d.ts +61 -0
- package/lib/handlers/base.handler.js +22 -0
- package/lib/handlers/binding.handler.d.ts +45 -0
- package/lib/handlers/binding.handler.js +285 -0
- package/lib/handlers/buid.handler.d.ts +71 -0
- package/lib/handlers/buid.handler.js +694 -0
- package/lib/handlers/index.d.ts +6 -0
- package/lib/handlers/index.js +22 -0
- package/lib/handlers/mcid.handler.d.ts +101 -0
- package/lib/handlers/mcid.handler.js +1045 -0
- package/lib/handlers/tag.handler.d.ts +14 -0
- package/lib/handlers/tag.handler.js +382 -0
- package/lib/handlers/whitelist.handler.d.ts +84 -0
- package/lib/handlers/whitelist.handler.js +1011 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +2693 -0
- package/lib/managers/rcon-manager.d.ts +24 -0
- package/lib/managers/rcon-manager.js +308 -0
- package/lib/repositories/mcidbind.repository.d.ts +105 -0
- package/lib/repositories/mcidbind.repository.js +288 -0
- package/lib/repositories/schedule-mute.repository.d.ts +68 -0
- package/lib/repositories/schedule-mute.repository.js +175 -0
- package/lib/types/api.d.ts +135 -0
- package/lib/types/api.js +6 -0
- package/lib/types/common.d.ts +40 -0
- package/lib/types/common.js +6 -0
- package/lib/types/config.d.ts +55 -0
- package/lib/types/config.js +6 -0
- package/lib/types/database.d.ts +47 -0
- package/lib/types/database.js +6 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/index.js +28 -0
- package/lib/utils/helpers.d.ts +76 -0
- package/lib/utils/helpers.js +275 -0
- package/lib/utils/logger.d.ts +75 -0
- package/lib/utils/logger.js +134 -0
- package/lib/utils/message-utils.d.ts +46 -0
- package/lib/utils/message-utils.js +234 -0
- package/lib/utils/rate-limiter.d.ts +26 -0
- package/lib/utils/rate-limiter.js +47 -0
- package/lib/utils/session-manager.d.ts +70 -0
- package/lib/utils/session-manager.js +120 -0
- package/package.json +39 -0
- package/readme.md +281 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as RconClient from 'rcon-client';
|
|
2
|
+
import { LoggerService } from '../utils/logger';
|
|
3
|
+
import type { ServerConfig } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* RCON 连接管理器
|
|
6
|
+
* 负责管理 Minecraft 服务器的 RCON 连接池
|
|
7
|
+
*/
|
|
8
|
+
export declare class RconManager {
|
|
9
|
+
private connections;
|
|
10
|
+
private logger;
|
|
11
|
+
private heartbeatCmd;
|
|
12
|
+
private heartbeatInterval;
|
|
13
|
+
private maxIdleTime;
|
|
14
|
+
private maxConnections;
|
|
15
|
+
private serverConfigs;
|
|
16
|
+
constructor(logger: LoggerService, serverConfigs: ServerConfig[]);
|
|
17
|
+
getConnection(server: ServerConfig): Promise<RconClient.Rcon>;
|
|
18
|
+
private createConnection;
|
|
19
|
+
private pruneOldestConnection;
|
|
20
|
+
private resetConnection;
|
|
21
|
+
executeCommand(server: ServerConfig, command: string): Promise<string>;
|
|
22
|
+
private cleanIdleConnections;
|
|
23
|
+
closeAll(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,308 @@
|
|
|
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 () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.RconManager = void 0;
|
|
37
|
+
const RconClient = __importStar(require("rcon-client"));
|
|
38
|
+
/**
|
|
39
|
+
* RCON 连接管理器
|
|
40
|
+
* 负责管理 Minecraft 服务器的 RCON 连接池
|
|
41
|
+
*/
|
|
42
|
+
class RconManager {
|
|
43
|
+
connections = new Map();
|
|
44
|
+
logger;
|
|
45
|
+
heartbeatCmd = 'list'; // 心跳命令,使用无害的list命令
|
|
46
|
+
heartbeatInterval = 5 * 60 * 1000; // 5分钟发送一次心跳
|
|
47
|
+
maxIdleTime = 30 * 60 * 1000; // 连接空闲30分钟后关闭
|
|
48
|
+
maxConnections = 20; // 最大同时连接数,防止资源耗尽
|
|
49
|
+
serverConfigs = [];
|
|
50
|
+
constructor(logger, serverConfigs) {
|
|
51
|
+
this.logger = logger;
|
|
52
|
+
this.serverConfigs = serverConfigs;
|
|
53
|
+
// 每5分钟检查一次空闲连接
|
|
54
|
+
setInterval(() => this.cleanIdleConnections(), 5 * 60 * 1000);
|
|
55
|
+
}
|
|
56
|
+
// 获取RCON连接
|
|
57
|
+
async getConnection(server) {
|
|
58
|
+
const serverId = server.id;
|
|
59
|
+
const connectionInfo = this.connections.get(serverId);
|
|
60
|
+
// 如果已有连接且仍然活跃,检查连接状态
|
|
61
|
+
if (connectionInfo && connectionInfo.rcon && !connectionInfo.reconnecting) {
|
|
62
|
+
try {
|
|
63
|
+
// 测试连接是否仍然有效
|
|
64
|
+
await connectionInfo.rcon.send('ping');
|
|
65
|
+
// 更新最后使用时间
|
|
66
|
+
connectionInfo.lastUsed = Date.now();
|
|
67
|
+
return connectionInfo.rcon;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// 连接可能已关闭,需要重新建立
|
|
71
|
+
this.logger.error('RCON管理器', `服务器 ${server.name} 的连接已失效,将重新连接`, error);
|
|
72
|
+
await this.resetConnection(server);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 创建新连接
|
|
76
|
+
return this.createConnection(server);
|
|
77
|
+
}
|
|
78
|
+
// 创建新RCON连接
|
|
79
|
+
async createConnection(server) {
|
|
80
|
+
// 解析RCON地址和端口
|
|
81
|
+
const addressParts = server.rconAddress.split(':');
|
|
82
|
+
if (addressParts.length !== 2) {
|
|
83
|
+
throw new Error(`RCON地址格式错误: ${server.rconAddress}, 正确格式应为 IP:端口`);
|
|
84
|
+
}
|
|
85
|
+
const host = addressParts[0];
|
|
86
|
+
const portStr = addressParts[1];
|
|
87
|
+
// 验证端口是有效数字
|
|
88
|
+
const port = parseInt(portStr);
|
|
89
|
+
if (isNaN(port) || port <= 0 || port > 65535) {
|
|
90
|
+
throw new Error(`服务器${server.name}的RCON端口无效: ${portStr}, 端口应为1-65535之间的数字`);
|
|
91
|
+
}
|
|
92
|
+
const serverId = server.id;
|
|
93
|
+
// 检查连接池大小,如果超过最大限制,尝试关闭最久未使用的连接
|
|
94
|
+
if (this.connections.size >= this.maxConnections) {
|
|
95
|
+
this.logger.warn('RCON管理器', `连接数量达到上限(${this.maxConnections}),尝试关闭最久未使用的连接`);
|
|
96
|
+
this.pruneOldestConnection();
|
|
97
|
+
}
|
|
98
|
+
// 标记为正在重连
|
|
99
|
+
if (this.connections.has(serverId)) {
|
|
100
|
+
const connectionInfo = this.connections.get(serverId);
|
|
101
|
+
if (connectionInfo) {
|
|
102
|
+
connectionInfo.reconnecting = true;
|
|
103
|
+
// 清除旧的心跳定时器
|
|
104
|
+
if (connectionInfo.heartbeatInterval) {
|
|
105
|
+
clearInterval(connectionInfo.heartbeatInterval);
|
|
106
|
+
connectionInfo.heartbeatInterval = null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
// 创建新连接
|
|
112
|
+
this.logger.info('RCON管理器', `正在连接到服务器 ${server.name} (${server.rconAddress})`);
|
|
113
|
+
const rcon = new RconClient.Rcon({
|
|
114
|
+
host,
|
|
115
|
+
port,
|
|
116
|
+
password: server.rconPassword,
|
|
117
|
+
timeout: 3000 // 3秒连接超时
|
|
118
|
+
});
|
|
119
|
+
// 连接到服务器
|
|
120
|
+
await rcon.connect();
|
|
121
|
+
// 设置心跳定时器,保持连接活跃
|
|
122
|
+
const heartbeatInterval = setInterval(async () => {
|
|
123
|
+
try {
|
|
124
|
+
this.logger.debug('RCON管理器', `向服务器 ${server.name} 发送心跳命令`);
|
|
125
|
+
await rcon.send(this.heartbeatCmd);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
this.logger.error('RCON管理器', `服务器 ${server.name} 心跳失败`, error);
|
|
129
|
+
// 心跳失败,重置连接
|
|
130
|
+
this.resetConnection(server);
|
|
131
|
+
}
|
|
132
|
+
}, this.heartbeatInterval);
|
|
133
|
+
// 存储连接信息
|
|
134
|
+
this.connections.set(serverId, {
|
|
135
|
+
rcon,
|
|
136
|
+
lastUsed: Date.now(),
|
|
137
|
+
heartbeatInterval,
|
|
138
|
+
reconnecting: false
|
|
139
|
+
});
|
|
140
|
+
this.logger.info('RCON管理器', `成功连接到服务器 ${server.name}`);
|
|
141
|
+
return rcon;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
this.logger.error('RCON管理器', `连接服务器 ${server.name} 失败`, error);
|
|
145
|
+
// 重置连接状态
|
|
146
|
+
if (this.connections.has(serverId)) {
|
|
147
|
+
const connectionInfo = this.connections.get(serverId);
|
|
148
|
+
if (connectionInfo) {
|
|
149
|
+
connectionInfo.reconnecting = false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// 关闭最久未使用的连接
|
|
156
|
+
pruneOldestConnection() {
|
|
157
|
+
let oldestId = null;
|
|
158
|
+
let oldestTime = Infinity;
|
|
159
|
+
// 找出最久未使用的连接
|
|
160
|
+
for (const [serverId, connectionInfo] of this.connections.entries()) {
|
|
161
|
+
// 跳过正在重连的连接
|
|
162
|
+
if (connectionInfo.reconnecting)
|
|
163
|
+
continue;
|
|
164
|
+
if (connectionInfo.lastUsed < oldestTime) {
|
|
165
|
+
oldestTime = connectionInfo.lastUsed;
|
|
166
|
+
oldestId = serverId;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// 如果找到了可以关闭的连接
|
|
170
|
+
if (oldestId) {
|
|
171
|
+
const connectionInfo = this.connections.get(oldestId);
|
|
172
|
+
if (connectionInfo) {
|
|
173
|
+
// 清除心跳定时器
|
|
174
|
+
if (connectionInfo.heartbeatInterval) {
|
|
175
|
+
clearInterval(connectionInfo.heartbeatInterval);
|
|
176
|
+
}
|
|
177
|
+
// 尝试关闭连接
|
|
178
|
+
try {
|
|
179
|
+
connectionInfo.rcon.end();
|
|
180
|
+
this.logger.info('RCON管理器', `由于连接池满,关闭了最久未使用的连接: ${oldestId}`);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
this.logger.debug('RCON管理器', `关闭最久未使用的连接出错: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
// 从连接池中移除
|
|
186
|
+
this.connections.delete(oldestId);
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
// 重置连接
|
|
193
|
+
async resetConnection(server) {
|
|
194
|
+
const serverId = server.id;
|
|
195
|
+
const connectionInfo = this.connections.get(serverId);
|
|
196
|
+
if (connectionInfo) {
|
|
197
|
+
this.logger.info('RCON管理器', `重置服务器 ${server.name} 的连接`);
|
|
198
|
+
// 标记为正在重连
|
|
199
|
+
connectionInfo.reconnecting = true;
|
|
200
|
+
// 清除心跳
|
|
201
|
+
if (connectionInfo.heartbeatInterval) {
|
|
202
|
+
clearInterval(connectionInfo.heartbeatInterval);
|
|
203
|
+
connectionInfo.heartbeatInterval = null;
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
// 关闭旧连接
|
|
207
|
+
await connectionInfo.rcon.end();
|
|
208
|
+
this.logger.debug('RCON管理器', `已关闭服务器 ${server.name} 的旧连接`);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
// 忽略关闭连接时的错误
|
|
212
|
+
this.logger.debug('RCON管理器', `关闭服务器 ${server.name} 的连接时出错: ${error.message}`);
|
|
213
|
+
}
|
|
214
|
+
// 从映射中移除
|
|
215
|
+
this.connections.delete(serverId);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// 执行RCON命令
|
|
219
|
+
async executeCommand(server, command) {
|
|
220
|
+
// 移除重试机制,改为单次尝试
|
|
221
|
+
try {
|
|
222
|
+
// 获取或创建连接
|
|
223
|
+
const rcon = await this.getConnection(server);
|
|
224
|
+
// 记录完整的命令,但隐藏可能的敏感信息
|
|
225
|
+
let safeCommand = command;
|
|
226
|
+
// 如果命令包含"op"或"password"等敏感词,则隐藏部分内容
|
|
227
|
+
if (safeCommand.includes('password') || safeCommand.startsWith('op ')) {
|
|
228
|
+
safeCommand = safeCommand.split(' ')[0] + ' [内容已隐藏]';
|
|
229
|
+
}
|
|
230
|
+
this.logger.info('RCON管理器', `服务器 ${server.name} 执行命令: ${safeCommand}`);
|
|
231
|
+
const response = await rcon.send(command);
|
|
232
|
+
// 记录完整响应内容
|
|
233
|
+
this.logger.info('RCON管理器', `服务器 ${server.name} 收到响应: ${response.length > 0 ? response : '(空响应)'} (${response.length}字节)`);
|
|
234
|
+
// 返回结果
|
|
235
|
+
return response;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
// 根据错误类型进行不同处理
|
|
239
|
+
if (error.message.includes('ECONNREFUSED') ||
|
|
240
|
+
error.message.includes('ETIMEDOUT') ||
|
|
241
|
+
error.message.includes('ECONNRESET') ||
|
|
242
|
+
error.message.includes('socket')) {
|
|
243
|
+
// 网络连接类错误
|
|
244
|
+
this.logger.error('RCON管理器', `服务器 ${server.name} 网络连接错误`, error);
|
|
245
|
+
throw new Error(`无法连接到服务器 ${server.name}: ${error.message}`);
|
|
246
|
+
}
|
|
247
|
+
else if (error.message.includes('authentication')) {
|
|
248
|
+
// 认证错误
|
|
249
|
+
this.logger.error('RCON管理器', `服务器 ${server.name} 认证失败,请检查密码`, error);
|
|
250
|
+
throw new Error(`连接服务器 ${server.name} 失败: 认证错误,请联系管理员检查RCON密码`);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
// 其他错误
|
|
254
|
+
this.logger.error('RCON管理器', `服务器 ${server.name} 执行命令失败`, error);
|
|
255
|
+
throw new Error(`执行命令失败: ${error.message}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// 清理空闲连接
|
|
260
|
+
async cleanIdleConnections() {
|
|
261
|
+
const now = Date.now();
|
|
262
|
+
for (const [serverId, connectionInfo] of this.connections.entries()) {
|
|
263
|
+
// 获取服务器名称(用于日志)
|
|
264
|
+
const serverConfig = this.serverConfigs.find(server => server.id === serverId);
|
|
265
|
+
const serverName = serverConfig ? serverConfig.name : serverId;
|
|
266
|
+
// 如果连接空闲时间超过maxIdleTime,关闭它
|
|
267
|
+
if (now - connectionInfo.lastUsed > this.maxIdleTime) {
|
|
268
|
+
this.logger.info('RCON管理器', `关闭服务器 ${serverName} 的空闲连接`);
|
|
269
|
+
// 清除心跳定时器
|
|
270
|
+
if (connectionInfo.heartbeatInterval) {
|
|
271
|
+
clearInterval(connectionInfo.heartbeatInterval);
|
|
272
|
+
}
|
|
273
|
+
// 关闭连接
|
|
274
|
+
try {
|
|
275
|
+
await connectionInfo.rcon.end();
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
this.logger.debug('RCON管理器', `关闭服务器 ${serverName} 的空闲连接时出错: ${error.message}`);
|
|
279
|
+
}
|
|
280
|
+
// 从连接池中删除
|
|
281
|
+
this.connections.delete(serverId);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// 关闭所有连接
|
|
286
|
+
async closeAll() {
|
|
287
|
+
for (const [serverId, connectionInfo] of this.connections.entries()) {
|
|
288
|
+
// 获取服务器名称(用于日志)
|
|
289
|
+
const serverConfig = this.serverConfigs.find(server => server.id === serverId);
|
|
290
|
+
const serverName = serverConfig ? serverConfig.name : serverId;
|
|
291
|
+
// 清除心跳定时器
|
|
292
|
+
if (connectionInfo.heartbeatInterval) {
|
|
293
|
+
clearInterval(connectionInfo.heartbeatInterval);
|
|
294
|
+
}
|
|
295
|
+
// 关闭连接
|
|
296
|
+
try {
|
|
297
|
+
await connectionInfo.rcon.end();
|
|
298
|
+
this.logger.info('RCON管理器', `已关闭服务器 ${serverName} 的连接`);
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
this.logger.debug('RCON管理器', `关闭服务器 ${serverName} 的连接时出错: ${error.message}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// 清空连接池
|
|
305
|
+
this.connections.clear();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
exports.RconManager = RconManager;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { LoggerService } from '../utils/logger';
|
|
3
|
+
import type { MCIDBIND } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* MCIDBIND 数据仓储类
|
|
6
|
+
* 封装所有 MCIDBIND 表的数据库操作
|
|
7
|
+
*/
|
|
8
|
+
export declare class MCIDBINDRepository {
|
|
9
|
+
private ctx;
|
|
10
|
+
private logger;
|
|
11
|
+
constructor(ctx: Context, logger: LoggerService);
|
|
12
|
+
/**
|
|
13
|
+
* 根据 QQ 号查询绑定信息
|
|
14
|
+
* @param qqId QQ号(已规范化)
|
|
15
|
+
* @returns 绑定信息或 null
|
|
16
|
+
*/
|
|
17
|
+
findByQQId(qqId: string): Promise<MCIDBIND | null>;
|
|
18
|
+
/**
|
|
19
|
+
* 根据 MC 用户名查询绑定信息
|
|
20
|
+
* @param mcUsername MC用户名
|
|
21
|
+
* @returns 绑定信息或 null
|
|
22
|
+
*/
|
|
23
|
+
findByMCUsername(mcUsername: string): Promise<MCIDBIND | null>;
|
|
24
|
+
/**
|
|
25
|
+
* 根据 B站 UID 查询绑定信息
|
|
26
|
+
* @param buidUid B站UID
|
|
27
|
+
* @returns 绑定信息或 null
|
|
28
|
+
*/
|
|
29
|
+
findByBuidUid(buidUid: string): Promise<MCIDBIND | null>;
|
|
30
|
+
/**
|
|
31
|
+
* 获取所有绑定记录
|
|
32
|
+
* @param options 查询选项
|
|
33
|
+
* @returns 绑定记录列表
|
|
34
|
+
*/
|
|
35
|
+
findAll(options?: {
|
|
36
|
+
limit?: number;
|
|
37
|
+
}): Promise<MCIDBIND[]>;
|
|
38
|
+
/**
|
|
39
|
+
* 根据标签查询绑定记录
|
|
40
|
+
* @param tag 标签名称
|
|
41
|
+
* @returns 包含该标签的绑定记录列表
|
|
42
|
+
*/
|
|
43
|
+
findByTag(tag: string): Promise<MCIDBIND[]>;
|
|
44
|
+
/**
|
|
45
|
+
* 创建新的绑定记录
|
|
46
|
+
* @param data 绑定数据
|
|
47
|
+
* @returns 创建的记录
|
|
48
|
+
*/
|
|
49
|
+
create(data: Partial<MCIDBIND> & {
|
|
50
|
+
qqId: string;
|
|
51
|
+
}): Promise<MCIDBIND>;
|
|
52
|
+
/**
|
|
53
|
+
* 更新绑定记录(部分字段)
|
|
54
|
+
* @param qqId QQ号
|
|
55
|
+
* @param data 要更新的字段
|
|
56
|
+
*/
|
|
57
|
+
update(qqId: string, data: Partial<MCIDBIND>): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* 删除绑定记录
|
|
60
|
+
* @param qqId QQ号
|
|
61
|
+
* @returns 删除的记录数
|
|
62
|
+
*/
|
|
63
|
+
delete(qqId: string): Promise<number>;
|
|
64
|
+
/**
|
|
65
|
+
* 删除所有绑定记录
|
|
66
|
+
* @returns 删除的记录数
|
|
67
|
+
*/
|
|
68
|
+
deleteAll(): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* 批量创建绑定记录
|
|
71
|
+
* @param records 绑定记录列表
|
|
72
|
+
*/
|
|
73
|
+
batchCreate(records: Array<Partial<MCIDBIND> & {
|
|
74
|
+
qqId: string;
|
|
75
|
+
}>): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* 为用户添加标签
|
|
78
|
+
* @param qqId QQ号
|
|
79
|
+
* @param tag 标签名称
|
|
80
|
+
*/
|
|
81
|
+
addTag(qqId: string, tag: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* 为用户移除标签
|
|
84
|
+
* @param qqId QQ号
|
|
85
|
+
* @param tag 标签名称
|
|
86
|
+
*/
|
|
87
|
+
removeTag(qqId: string, tag: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* 为用户添加白名单服务器
|
|
90
|
+
* @param qqId QQ号
|
|
91
|
+
* @param serverId 服务器ID
|
|
92
|
+
*/
|
|
93
|
+
addWhitelist(qqId: string, serverId: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* 为用户移除白名单服务器
|
|
96
|
+
* @param qqId QQ号
|
|
97
|
+
* @param serverId 服务器ID
|
|
98
|
+
*/
|
|
99
|
+
removeWhitelist(qqId: string, serverId: string): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* 获取所有管理员
|
|
102
|
+
* @returns 管理员列表
|
|
103
|
+
*/
|
|
104
|
+
findAllAdmins(): Promise<MCIDBIND[]>;
|
|
105
|
+
}
|