mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: msg push
This commit is contained in:
parent
a0a50755d3
commit
4487db4e0a
@ -8,12 +8,12 @@ export abstract class ConfigBase<T> {
|
||||
configPath: string;
|
||||
configData: T = {} as T;
|
||||
|
||||
protected constructor(name: string, core: NapCatCore, configPath: string) {
|
||||
protected constructor(name: string, core: NapCatCore, configPath: string, copy_default: boolean = true) {
|
||||
this.name = name;
|
||||
this.core = core;
|
||||
this.configPath = configPath;
|
||||
fs.mkdirSync(this.configPath, { recursive: true });
|
||||
this.read();
|
||||
this.read(copy_default);
|
||||
}
|
||||
|
||||
protected getKeys(): string[] | null {
|
||||
@ -32,16 +32,18 @@ export abstract class ConfigBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
read(): T {
|
||||
read(copy_default: boolean = true): T {
|
||||
const logger = this.core.context.logger;
|
||||
const configPath = this.getConfigPath(this.core.selfInfo.uin);
|
||||
if (!fs.existsSync(configPath)) {
|
||||
if (!fs.existsSync(configPath) && copy_default) {
|
||||
try {
|
||||
fs.writeFileSync(configPath, fs.readFileSync(this.getConfigPath(undefined), 'utf-8'));
|
||||
logger.log(`[Core] [Config] 配置文件创建成功!\n`);
|
||||
} catch (e: any) {
|
||||
logger.logError.bind(logger)(`[Core] [Config] 创建配置文件时发生错误:`, e.message);
|
||||
}
|
||||
} else if (!fs.existsSync(configPath) && !copy_default) {
|
||||
fs.writeFileSync(configPath, '{}');
|
||||
}
|
||||
try {
|
||||
this.configData = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
|
@ -37,13 +37,13 @@ abstract class BaseAction<PayloadType, ReturnDataType> {
|
||||
};
|
||||
}
|
||||
|
||||
public async handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
public async handle(payload: PayloadType, adaptername: string): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const result = await this.check(payload);
|
||||
if (!result.valid) {
|
||||
return OB11Response.error(result.message, 400);
|
||||
}
|
||||
try {
|
||||
const resData = await this._handle(payload);
|
||||
const resData = await this._handle(payload, adaptername);
|
||||
return OB11Response.ok(resData);
|
||||
} catch (e: any) {
|
||||
this.core.context.logger.logError.bind(this.core.context.logger)('发生错误', e);
|
||||
@ -51,13 +51,13 @@ abstract class BaseAction<PayloadType, ReturnDataType> {
|
||||
}
|
||||
}
|
||||
|
||||
public async websocketHandle(payload: PayloadType, echo: any): Promise<OB11Return<ReturnDataType | null>> {
|
||||
public async websocketHandle(payload: PayloadType, echo: any, adaptername: string): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const result = await this.check(payload);
|
||||
if (!result.valid) {
|
||||
return OB11Response.error(result.message, 1400, echo);
|
||||
}
|
||||
try {
|
||||
const resData = await this._handle(payload);
|
||||
const resData = await this._handle(payload, adaptername);
|
||||
return OB11Response.ok(resData, echo);
|
||||
} catch (e: any) {
|
||||
this.core.context.logger.logError.bind(this.core.context.logger)('发生错误', e);
|
||||
@ -65,7 +65,7 @@ abstract class BaseAction<PayloadType, ReturnDataType> {
|
||||
}
|
||||
}
|
||||
|
||||
abstract _handle(payload: PayloadType): PromiseLike<ReturnDataType>;
|
||||
abstract _handle(payload: PayloadType, adaptername: string): PromiseLike<ReturnDataType>;
|
||||
}
|
||||
|
||||
export default BaseAction;
|
||||
|
@ -72,7 +72,7 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
|
||||
}
|
||||
|
||||
const singleMsg = data.msgList[0];
|
||||
const resMsg = await this.obContext.apis.MsgApi.parseMessage(singleMsg, 'array');//强制array 以便处理
|
||||
const resMsg = (await this.obContext.apis.MsgApi.parseMessageV2(singleMsg))?.arrayMsg;//强制array 以便处理
|
||||
if (!(resMsg?.message?.[0] as OB11MessageForward)?.data?.content) {
|
||||
throw new Error('找不到相关的聊天记录');
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
|
||||
actionName = ActionName.GetFriendMsgHistory;
|
||||
payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload): Promise<Response> {
|
||||
async _handle(payload: Payload, adapter: string): Promise<Response> {
|
||||
//处理参数
|
||||
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
|
||||
const MsgCount = +(payload.count ?? 20);
|
||||
@ -45,9 +45,10 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
|
||||
await Promise.all(msgList.map(async msg => {
|
||||
msg.id = MessageUnique.createUniqueMsgId({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
||||
}));
|
||||
let network = Object.values(this.obContext.configLoader.configData.network) as Array<typeof this.obContext.configLoader.configData.network[keyof typeof this.obContext.configLoader.configData.network]>;
|
||||
//烘焙消息
|
||||
const ob11MsgList = (await Promise.all(
|
||||
msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg)))
|
||||
msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg, network.flat().find(e => e.name === adapter)?.messagePostFormat ?? 'array')))
|
||||
).filter(msg => msg !== undefined);
|
||||
return { 'messages': ob11MsgList };
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ export class OneBotMsgApi {
|
||||
multiMsgItem.parentMsgPeer = parentMsgPeer;
|
||||
multiMsgItem.parentMsgIdList = msg.parentMsgIdList;
|
||||
multiMsgItem.id = MessageUnique.createUniqueMsgId(parentMsgPeer, multiMsgItem.msgId); //该ID仅用查看 无法调用
|
||||
return await this.parseMessage(multiMsgItem);
|
||||
return await this.parseMessage(multiMsgItem, 'array');
|
||||
},
|
||||
))).filter(item => item !== undefined),
|
||||
},
|
||||
@ -693,7 +693,7 @@ export class OneBotMsgApi {
|
||||
|
||||
async parseMessage(
|
||||
msg: RawMessage,
|
||||
messagePostFormat: string = this.obContext.configLoader.configData.messagePostFormat,
|
||||
messagePostFormat: string,
|
||||
) {
|
||||
if (msg.senderUin == '0' || msg.senderUin == '') return;
|
||||
if (msg.peerUin == '0' || msg.peerUin == '') return;
|
||||
@ -796,6 +796,110 @@ export class OneBotMsgApi {
|
||||
return resMsg;
|
||||
}
|
||||
|
||||
async parseMessageV2(
|
||||
msg: RawMessage,
|
||||
) {
|
||||
if (msg.senderUin == '0' || msg.senderUin == '') return;
|
||||
if (msg.peerUin == '0' || msg.peerUin == '') return;
|
||||
//跳过空消息
|
||||
const resMsg: OB11Message = {
|
||||
self_id: parseInt(this.core.selfInfo.uin),
|
||||
user_id: parseInt(msg.senderUin),
|
||||
time: parseInt(msg.msgTime) || Date.now(),
|
||||
message_id: msg.id!,
|
||||
message_seq: msg.id!,
|
||||
real_id: msg.id!,
|
||||
message_type: msg.chatType == ChatType.KCHATTYPEGROUP ? 'group' : 'private',
|
||||
sender: {
|
||||
user_id: +(msg.senderUin ?? 0),
|
||||
nickname: msg.sendNickName,
|
||||
card: msg.sendMemberName ?? '',
|
||||
},
|
||||
raw_message: '',
|
||||
font: 14,
|
||||
sub_type: 'friend',
|
||||
message: [],
|
||||
message_format: 'array',
|
||||
post_type: this.core.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
|
||||
};
|
||||
if (this.core.selfInfo.uin == msg.senderUin) {
|
||||
resMsg.message_sent_type = 'self';
|
||||
}
|
||||
if (msg.chatType == ChatType.KCHATTYPEGROUP) {
|
||||
resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼
|
||||
resMsg.group_id = parseInt(msg.peerUin);
|
||||
let member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
|
||||
if (!member) member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
|
||||
if (member) {
|
||||
resMsg.sender.role = OB11Entities.groupMemberRole(member.role);
|
||||
resMsg.sender.nickname = member.nick;
|
||||
}
|
||||
} else if (msg.chatType == ChatType.KCHATTYPEC2C) {
|
||||
resMsg.sub_type = 'friend';
|
||||
resMsg.sender.nickname = (await this.core.apis.UserApi.getUserDetailInfo(msg.senderUid)).nick;
|
||||
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
|
||||
resMsg.sub_type = 'group';
|
||||
const ret = await this.core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
|
||||
if (ret.result === 0) {
|
||||
const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
|
||||
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
|
||||
resMsg.sender.nickname = member?.nick ?? member?.cardName ?? '临时会话';
|
||||
resMsg.temp_source = resMsg.group_id;
|
||||
} else {
|
||||
resMsg.group_id = 284840486; //兜底数据
|
||||
resMsg.temp_source = resMsg.group_id;
|
||||
resMsg.sender.nickname = '临时会话';
|
||||
}
|
||||
}
|
||||
|
||||
// 处理消息段
|
||||
const msgSegments = await Promise.allSettled(msg.elements.map(
|
||||
async (element) => {
|
||||
for (const key in element) {
|
||||
if (keyCanBeParsed(key, this.rawToOb11Converters) && element[key]) {
|
||||
const converters = this.rawToOb11Converters[key] as (
|
||||
element: Exclude<MessageElement[keyof RawToOb11Converters], null | undefined>,
|
||||
msg: RawMessage,
|
||||
elementWrapper: MessageElement,
|
||||
) => PromiseLike<OB11MessageData | null>;
|
||||
const parsedElement = await converters?.(
|
||||
element[key],
|
||||
msg,
|
||||
element,
|
||||
);
|
||||
// 对于 face 类型的消息,检查是否存在
|
||||
if (key === 'faceElement' && !parsedElement) {
|
||||
return null; // 如果没有找到对应的表情,返回 null
|
||||
}
|
||||
|
||||
return parsedElement;
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
|
||||
// 过滤掉无效的消息段
|
||||
const validSegments = msgSegments.filter(entry => {
|
||||
if (entry.status === 'fulfilled') {
|
||||
return !!entry.value;
|
||||
} else {
|
||||
this.core.context.logger.logError.bind(this.core.context.logger)('消息段解析失败', entry.reason);
|
||||
return false;
|
||||
}
|
||||
}).map((entry) => (<PromiseFulfilledResult<OB11MessageData>>entry).value).filter(value => value != null);
|
||||
|
||||
const msgAsCQCode = validSegments.map(msg => encodeCQCode(msg)).join('').trim();
|
||||
resMsg.message = validSegments;
|
||||
resMsg.raw_message = msgAsCQCode;
|
||||
let stringMsg = structuredClone(resMsg);
|
||||
stringMsg = await this.importArrayTostringMsg(stringMsg);
|
||||
return { stringMsg: stringMsg, arrayMsg: resMsg };
|
||||
}
|
||||
async importArrayTostringMsg(msg: OB11Message) {
|
||||
msg.message_format = 'string';
|
||||
msg.message = msg.raw_message;
|
||||
return msg;
|
||||
}
|
||||
async createSendElements(
|
||||
messageData: OB11MessageData[],
|
||||
peer: Peer,
|
||||
|
@ -1,6 +1,6 @@
|
||||
export interface AdapterConfig {
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
enable: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@ const createDefaultAdapterConfig = <T extends AdapterConfig>(config: T): T => co
|
||||
|
||||
const httpServerDefaultConfigs = createDefaultAdapterConfig({
|
||||
name: 'http-server',
|
||||
enabled: false,
|
||||
port: '3000',
|
||||
enable: false,
|
||||
port: 3000,
|
||||
host: '0.0.0.0',
|
||||
enableCors: true,
|
||||
enableWebsocket: true,
|
||||
@ -22,7 +22,7 @@ export type HttpServerConfig = typeof httpServerDefaultConfigs;
|
||||
|
||||
const httpClientDefaultConfigs = createDefaultAdapterConfig({
|
||||
name: 'http-client',
|
||||
enabled: false,
|
||||
enable: false,
|
||||
url: 'http://localhost:8080',
|
||||
messagePostFormat: 'array',
|
||||
reportSelfMessage: false,
|
||||
@ -33,9 +33,9 @@ export type HttpClientConfig = typeof httpClientDefaultConfigs;
|
||||
|
||||
const websocketServerDefaultConfigs = createDefaultAdapterConfig({
|
||||
name: 'websocket-server',
|
||||
enabled: false,
|
||||
enable: false,
|
||||
host: '0.0.0.0',
|
||||
port: '3002',
|
||||
port: 3002,
|
||||
messagePostFormat: 'array',
|
||||
reportSelfMessage: false,
|
||||
token: '',
|
||||
@ -47,7 +47,7 @@ export type WebsocketServerConfig = typeof websocketServerDefaultConfigs;
|
||||
|
||||
const websocketClientDefaultConfigs = createDefaultAdapterConfig({
|
||||
name: 'websocket-client',
|
||||
enabled: false,
|
||||
enable: false,
|
||||
url: 'ws://localhost:8082',
|
||||
messagePostFormat: 'array',
|
||||
reportSelfMessage: false,
|
||||
@ -71,6 +71,7 @@ export function mergeConfigs<T extends AdapterConfig>(defaultConfig: T, userConf
|
||||
export interface OnebotConfig {
|
||||
network: NetworkConfig;//网络配置
|
||||
musicSignUrl: string;//音乐签名地址
|
||||
enableLocalFile2Url: boolean
|
||||
}
|
||||
|
||||
const createDefaultConfig = <T>(config: T): T => config;
|
||||
@ -82,7 +83,8 @@ export const defaultOnebotConfig = createDefaultConfig<OnebotConfig>({
|
||||
websocketServers: [],
|
||||
websocketClients: [],
|
||||
},
|
||||
musicSignUrl: ""
|
||||
musicSignUrl: "",
|
||||
enableLocalFile2Url: false
|
||||
})
|
||||
export const mergeNetworkDefaultConfig = {
|
||||
httpServers: httpServerDefaultConfigs,
|
||||
@ -110,4 +112,4 @@ export function mergeOnebotConfigs(defaultConfig: OnebotConfig, userConfig: Part
|
||||
mergedConfig.musicSignUrl = userConfig.musicSignUrl;
|
||||
}
|
||||
return mergedConfig;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { ConfigBase } from '@/common/config-base';
|
||||
import ob11DefaultConfig from './onebot11.json';
|
||||
import { NapCatCore } from '@/core';
|
||||
import { OnebotConfig } from './config';
|
||||
|
||||
export type OB11Config = typeof ob11DefaultConfig;
|
||||
|
||||
export class OB11ConfigLoader extends ConfigBase<OB11Config> {
|
||||
export class OB11ConfigLoader extends ConfigBase<OnebotConfig> {
|
||||
constructor(core: NapCatCore, configPath: string) {
|
||||
super('onebot11', core, configPath);
|
||||
super('onebot11', core, configPath, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"http": {
|
||||
"enable": false,
|
||||
"host": "",
|
||||
"port": 3000,
|
||||
"secret": "",
|
||||
"enableHeart": false,
|
||||
"enablePost": false,
|
||||
"postUrls": []
|
||||
},
|
||||
"ws": {
|
||||
"enable": false,
|
||||
"host": "",
|
||||
"port": 3001
|
||||
},
|
||||
"reverseWs": {
|
||||
"enable": false,
|
||||
"urls": []
|
||||
},
|
||||
"GroupLocalTime": {
|
||||
"Record": false,
|
||||
"RecordList": []
|
||||
},
|
||||
"debug": false,
|
||||
"heartInterval": 30000,
|
||||
"messagePostFormat": "array",
|
||||
"enableLocalFile2Url": true,
|
||||
"musicSignUrl": "",
|
||||
"reportSelfMessage": false,
|
||||
"token": ""
|
||||
}
|
@ -14,7 +14,7 @@ import {
|
||||
RawMessage,
|
||||
SendStatusType,
|
||||
} from '@/core';
|
||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/config';
|
||||
import { OB11ConfigLoader } from '@/onebot/config';
|
||||
import {
|
||||
OB11ActiveHttpAdapter,
|
||||
OB11ActiveWebSocketAdapter,
|
||||
@ -45,6 +45,8 @@ import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecal
|
||||
import { LRUCache } from '@/common/lru-cache';
|
||||
import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener';
|
||||
import { BotOfflineEvent } from './event/notice/BotOfflineEvent';
|
||||
import { defaultOnebotConfig, mergeOnebotConfigs, OnebotConfig } from './config/config';
|
||||
import { OB11Message } from './types';
|
||||
|
||||
//OneBot实现类
|
||||
export class NapCatOneBot11Adapter {
|
||||
@ -61,7 +63,8 @@ export class NapCatOneBot11Adapter {
|
||||
constructor(core: NapCatCore, context: InstanceContext, pathWrapper: NapCatPathWrapper) {
|
||||
this.core = core;
|
||||
this.context = context;
|
||||
this.configLoader = new OB11ConfigLoader(core, pathWrapper.configPath);
|
||||
this.configLoader = new OB11ConfigLoader(core, pathWrapper.configPath,);
|
||||
this.configLoader.save(mergeOnebotConfigs(defaultOnebotConfig, this.configLoader.configData));
|
||||
this.apis = {
|
||||
GroupApi: new OneBotGroupApi(this, core),
|
||||
UserApi: new OneBotUserApi(this, core),
|
||||
@ -72,65 +75,77 @@ export class NapCatOneBot11Adapter {
|
||||
this.actions = createActionMap(this, core);
|
||||
this.networkManager = new OB11NetworkManager();
|
||||
}
|
||||
|
||||
async creatOneBotLog(ob11Config: OnebotConfig) {
|
||||
let log = `[network] 配置加载\n`;
|
||||
for (const key of ob11Config.network.httpServers) {
|
||||
log += `HTTP服务: ${key.host}:${key.port}, : ${key.enable ? '已启动' : '未启动'}\n`;
|
||||
}
|
||||
for (const key of ob11Config.network.httpClients) {
|
||||
log += `HTTP上报服务: ${key.url}, : ${key.enable ? '已启动' : '未启动'}\n`;
|
||||
}
|
||||
for (const key of ob11Config.network.websocketServers) {
|
||||
log += `WebSocket服务: ${key.host}:${key.port}, : ${key.enable ? '已启动' : '未启动'}\n`;
|
||||
}
|
||||
for (const key of ob11Config.network.websocketClients) {
|
||||
log += `WebSocket反向服务: ${key.url}, : ${key.enable ? '已启动' : '未启动'}\n`;
|
||||
}
|
||||
return log;
|
||||
}
|
||||
async InitOneBot() {
|
||||
const selfInfo = this.core.selfInfo;
|
||||
const ob11Config = this.configLoader.configData;
|
||||
|
||||
const serviceInfo = `
|
||||
HTTP服务 ${ob11Config.http.enable ? '已启动' : '未启动'}, ${ob11Config.http.host}:${ob11Config.http.port}
|
||||
HTTP上报服务 ${ob11Config.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${ob11Config.http.postUrls}
|
||||
WebSocket服务 ${ob11Config.ws.enable ? '已启动' : '未启动'}, ${ob11Config.ws.host}:${ob11Config.ws.port}
|
||||
WebSocket反向服务 ${ob11Config.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${ob11Config.reverseWs.urls}`;
|
||||
|
||||
this.core.apis.UserApi.getUserDetailInfo(selfInfo.uid).then(user => {
|
||||
selfInfo.nick = user.nick;
|
||||
this.context.logger.setLogSelfInfo(selfInfo);
|
||||
}).catch(this.context.logger.logError.bind(this.context.logger));
|
||||
|
||||
let serviceInfo = await this.creatOneBotLog(ob11Config);
|
||||
this.context.logger.log(`[Notice] [OneBot11] ${serviceInfo}`);
|
||||
|
||||
//创建NetWork服务
|
||||
if (ob11Config.http.enable) {
|
||||
this.networkManager.registerAdapter(new OB11PassiveHttpAdapter(
|
||||
ob11Config.http.port, ob11Config.token, this.core, this.actions,
|
||||
));
|
||||
// //创建NetWork服务
|
||||
for (const key of ob11Config.network.httpServers) {
|
||||
if (key.enable) {
|
||||
this.networkManager.registerAdapter(new OB11PassiveHttpAdapter(
|
||||
key.name, key.port, key.token, this.core, this.actions,
|
||||
));
|
||||
}
|
||||
}
|
||||
if (ob11Config.http.enablePost) {
|
||||
ob11Config.http.postUrls.forEach(url => {
|
||||
for (const key of ob11Config.network.httpClients) {
|
||||
if (key.enable) {
|
||||
this.networkManager.registerAdapter(new OB11ActiveHttpAdapter(
|
||||
url, ob11Config.http.secret, this.core, this,
|
||||
key.name, key.url, key.token, this.core, this,
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
if (ob11Config.ws.enable) {
|
||||
const OBPassiveWebSocketAdapter = new OB11PassiveWebSocketAdapter(
|
||||
ob11Config.ws.host, ob11Config.ws.port, ob11Config.heartInterval, ob11Config.token, this.core, this.actions,
|
||||
);
|
||||
this.networkManager.registerAdapter(OBPassiveWebSocketAdapter);
|
||||
for (const key of ob11Config.network.websocketServers) {
|
||||
if (key.enable) {
|
||||
this.networkManager.registerAdapter(new OB11PassiveWebSocketAdapter(
|
||||
key.name, key.host, key.port, key.heartInterval, key.token, this.core, this.actions,
|
||||
));
|
||||
}
|
||||
}
|
||||
if (ob11Config.reverseWs.enable) {
|
||||
ob11Config.reverseWs.urls.forEach(url => {
|
||||
for (const key of ob11Config.network.websocketClients) {
|
||||
if (key.enable) {
|
||||
this.networkManager.registerAdapter(new OB11ActiveWebSocketAdapter(
|
||||
url, 5000, ob11Config.heartInterval, ob11Config.token, this.core, this.actions,
|
||||
key.name, key.url, 5000, key.heartInterval, key.token, this.core, this.actions,
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await this.networkManager.openAllAdapters();
|
||||
|
||||
this.initMsgListener();
|
||||
this.initBuddyListener();
|
||||
this.initGroupListener();
|
||||
//this.initRecentContactListener();
|
||||
|
||||
await WebUiDataRuntime.setQQLoginUin(selfInfo.uin.toString());
|
||||
await WebUiDataRuntime.setQQLoginStatus(true);
|
||||
await WebUiDataRuntime.setOnOB11ConfigChanged(async (newConfig: OB11Config) => {
|
||||
const prev = this.configLoader.configData;
|
||||
this.configLoader.save(newConfig);
|
||||
this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`);
|
||||
await this.reloadNetwork(prev, newConfig);
|
||||
});
|
||||
// await WebUiDataRuntime.setOnOB11ConfigChanged(async (newConfig: OB11Config) => {
|
||||
// const prev = this.configLoader.configData;
|
||||
// this.configLoader.save(newConfig);
|
||||
// this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`);
|
||||
// await this.reloadNetwork(prev, newConfig);
|
||||
// });
|
||||
}
|
||||
|
||||
initRecentContactListener() {
|
||||
@ -144,88 +159,88 @@ export class NapCatOneBot11Adapter {
|
||||
};
|
||||
}
|
||||
|
||||
private async reloadNetwork(prev: OB11Config, now: OB11Config) {
|
||||
const serviceInfo = `
|
||||
HTTP服务 ${now.http.enable ? '已启动' : '未启动'}, ${now.http.host}:${now.http.port}
|
||||
HTTP上报服务 ${now.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${now.http.postUrls}
|
||||
WebSocket服务 ${now.ws.enable ? '已启动' : '未启动'}, ${now.ws.host}:${now.ws.port}
|
||||
WebSocket反向服务 ${now.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${now.reverseWs.urls}`;
|
||||
this.context.logger.log(`[Notice] [OneBot11] 热重载 ${serviceInfo}`);
|
||||
// private async reloadNetwork(prev: OB11Config, now: OB11Config) {
|
||||
// const serviceInfo = `
|
||||
// HTTP服务 ${now.http.enable ? '已启动' : '未启动'}, ${now.http.host}:${now.http.port}
|
||||
// HTTP上报服务 ${now.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${now.http.postUrls}
|
||||
// WebSocket服务 ${now.ws.enable ? '已启动' : '未启动'}, ${now.ws.host}:${now.ws.port}
|
||||
// WebSocket反向服务 ${now.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${now.reverseWs.urls}`;
|
||||
// this.context.logger.log(`[Notice] [OneBot11] 热重载 ${serviceInfo}`);
|
||||
|
||||
// check difference in passive http (Http)
|
||||
if (prev.http.enable !== now.http.enable) {
|
||||
if (now.http.enable) {
|
||||
await this.networkManager.registerAdapterAndOpen(new OB11PassiveHttpAdapter(
|
||||
now.http.port, now.token, this.core, this.actions,
|
||||
));
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate(adapter => adapter instanceof OB11PassiveHttpAdapter);
|
||||
}
|
||||
}
|
||||
// // check difference in passive http (Http)
|
||||
// if (prev.http.enable !== now.http.enable) {
|
||||
// if (now.http.enable) {
|
||||
// await this.networkManager.registerAdapterAndOpen(new OB11PassiveHttpAdapter(
|
||||
// now.http.port, now.token, this.core, this.actions,
|
||||
// ));
|
||||
// } else {
|
||||
// await this.networkManager.closeAdapterByPredicate(adapter => adapter instanceof OB11PassiveHttpAdapter);
|
||||
// }
|
||||
// }
|
||||
|
||||
// check difference in active http (HttpPost)
|
||||
if (prev.http.enablePost !== now.http.enablePost) {
|
||||
if (now.http.enablePost) {
|
||||
now.http.postUrls.forEach(url => {
|
||||
this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||
url, now.http.secret, this.core, this,
|
||||
));
|
||||
});
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate(adapter => adapter instanceof OB11ActiveHttpAdapter);
|
||||
}
|
||||
} else if (now.http.enablePost) {
|
||||
const { added, removed } = this.findDifference<string>(prev.http.postUrls, now.http.postUrls);
|
||||
await this.networkManager.closeAdapterByPredicate(
|
||||
adapter => adapter instanceof OB11ActiveHttpAdapter && removed.includes(adapter.url),
|
||||
);
|
||||
for (const url of added) {
|
||||
await this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||
url, now.http.secret, this.core, this,
|
||||
));
|
||||
}
|
||||
}
|
||||
// // check difference in active http (HttpPost)
|
||||
// if (prev.http.enablePost !== now.http.enablePost) {
|
||||
// if (now.http.enablePost) {
|
||||
// now.http.postUrls.forEach(url => {
|
||||
// this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||
// url, now.http.secret, this.core, this,
|
||||
// ));
|
||||
// });
|
||||
// } else {
|
||||
// await this.networkManager.closeAdapterByPredicate(adapter => adapter instanceof OB11ActiveHttpAdapter);
|
||||
// }
|
||||
// } else if (now.http.enablePost) {
|
||||
// const { added, removed } = this.findDifference<string>(prev.http.postUrls, now.http.postUrls);
|
||||
// await this.networkManager.closeAdapterByPredicate(
|
||||
// adapter => adapter instanceof OB11ActiveHttpAdapter && removed.includes(adapter.url),
|
||||
// );
|
||||
// for (const url of added) {
|
||||
// await this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||
// url, now.http.secret, this.core, this,
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// check difference in passive websocket (Ws)
|
||||
if (prev.ws.enable !== now.ws.enable) {
|
||||
if (now.ws.enable) {
|
||||
await this.networkManager.registerAdapterAndOpen(new OB11PassiveWebSocketAdapter(
|
||||
now.ws.host, now.ws.port, now.heartInterval, now.token, this.core, this.actions,
|
||||
));
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate(
|
||||
adapter => adapter instanceof OB11PassiveWebSocketAdapter,
|
||||
);
|
||||
}
|
||||
}
|
||||
// // check difference in passive websocket (Ws)
|
||||
// if (prev.ws.enable !== now.ws.enable) {
|
||||
// if (now.ws.enable) {
|
||||
// await this.networkManager.registerAdapterAndOpen(new OB11PassiveWebSocketAdapter(
|
||||
// now.ws.host, now.ws.port, now.heartInterval, now.token, this.core, this.actions,
|
||||
// ));
|
||||
// } else {
|
||||
// await this.networkManager.closeAdapterByPredicate(
|
||||
// adapter => adapter instanceof OB11PassiveWebSocketAdapter,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// check difference in active websocket (ReverseWs)
|
||||
if (prev.reverseWs.enable !== now.reverseWs.enable) {
|
||||
if (now.reverseWs.enable) {
|
||||
now.reverseWs.urls.forEach(url => {
|
||||
this.networkManager.registerAdapterAndOpen(new OB11ActiveWebSocketAdapter(
|
||||
url, 5000, now.heartInterval, now.token, this.core, this.actions,
|
||||
));
|
||||
});
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate(
|
||||
adapter => adapter instanceof OB11ActiveWebSocketAdapter,
|
||||
);
|
||||
}
|
||||
} else if (now.reverseWs.enable) {
|
||||
const { added, removed } = this.findDifference<string>(prev.reverseWs.urls, now.reverseWs.urls);
|
||||
await this.networkManager.closeAdapterByPredicate(
|
||||
adapter => adapter instanceof OB11ActiveWebSocketAdapter && removed.includes(adapter.url),
|
||||
);
|
||||
for (const url of added) {
|
||||
await this.networkManager.registerAdapterAndOpen(new OB11ActiveWebSocketAdapter(
|
||||
url, 5000, now.heartInterval, now.token, this.core, this.actions,
|
||||
));
|
||||
}
|
||||
}
|
||||
// // check difference in active websocket (ReverseWs)
|
||||
// if (prev.reverseWs.enable !== now.reverseWs.enable) {
|
||||
// if (now.reverseWs.enable) {
|
||||
// now.reverseWs.urls.forEach(url => {
|
||||
// this.networkManager.registerAdapterAndOpen(new OB11ActiveWebSocketAdapter(
|
||||
// url, 5000, now.heartInterval, now.token, this.core, this.actions,
|
||||
// ));
|
||||
// });
|
||||
// } else {
|
||||
// await this.networkManager.closeAdapterByPredicate(
|
||||
// adapter => adapter instanceof OB11ActiveWebSocketAdapter,
|
||||
// );
|
||||
// }
|
||||
// } else if (now.reverseWs.enable) {
|
||||
// const { added, removed } = this.findDifference<string>(prev.reverseWs.urls, now.reverseWs.urls);
|
||||
// await this.networkManager.closeAdapterByPredicate(
|
||||
// adapter => adapter instanceof OB11ActiveWebSocketAdapter && removed.includes(adapter.url),
|
||||
// );
|
||||
// for (const url of added) {
|
||||
// await this.networkManager.registerAdapterAndOpen(new OB11ActiveWebSocketAdapter(
|
||||
// url, 5000, now.heartInterval, now.token, this.core, this.actions,
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
private findDifference<T>(prev: T[], now: T[]): { added: T[], removed: T[] } {
|
||||
const added = now.filter(item => !prev.includes(item));
|
||||
@ -285,21 +300,12 @@ export class NapCatOneBot11Adapter {
|
||||
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && msgIdSend.get(msg.msgId) == 0) {
|
||||
msgIdSend.put(msg.msgId, 1);
|
||||
// 完成后再post
|
||||
this.apis.MsgApi.parseMessage(msg)
|
||||
.then((ob11Msg) => {
|
||||
if (!ob11Msg) return;
|
||||
ob11Msg.target_id = parseInt(msg.peerUin);
|
||||
if (this.configLoader.configData.reportSelfMessage) {
|
||||
msg.id = MessageUnique.createUniqueMsgId({
|
||||
chatType: msg.chatType,
|
||||
peerUid: msg.peerUid,
|
||||
guildId: '',
|
||||
}, msg.msgId);
|
||||
this.emitMsg(msg);
|
||||
} else {
|
||||
// logOB11Message(this.core, ob11Msg);
|
||||
}
|
||||
});
|
||||
msg.id = MessageUnique.createUniqueMsgId({
|
||||
chatType: msg.chatType,
|
||||
peerUid: msg.peerUid,
|
||||
guildId: '',
|
||||
}, msg.msgId);
|
||||
this.emitMsg(msg, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -491,56 +497,52 @@ export class NapCatOneBot11Adapter {
|
||||
);
|
||||
}
|
||||
|
||||
private async emitMsg(message: RawMessage, parseEvent: boolean = true) {
|
||||
const { debug, reportSelfMessage, messagePostFormat } = this.configLoader.configData;
|
||||
private async emitMsg(message: RawMessage, selfMsg: boolean = true) {
|
||||
let network = Object.values(this.configLoader.configData.network) as Array<typeof this.configLoader.configData.network[keyof typeof this.configLoader.configData.network]>;
|
||||
this.context.logger.logDebug('收到新消息 RawMessage', message);
|
||||
this.apis.MsgApi.parseMessage(message, messagePostFormat).then((ob11Msg) => {
|
||||
this.apis.MsgApi.parseMessageV2(message).then((ob11Msg) => {
|
||||
if (!ob11Msg) return;
|
||||
const isSelfMsg = ob11Msg.stringMsg.user_id.toString() == this.core.selfInfo.uin || ob11Msg.arrayMsg.user_id.toString() == this.core.selfInfo.uin;
|
||||
this.context.logger.logDebug('转化为 OB11Message', ob11Msg);
|
||||
if (debug) {
|
||||
ob11Msg.raw = message;
|
||||
} else if (ob11Msg.message.length === 0) {
|
||||
let msgMap: Map<string, OB11Message> = new Map();
|
||||
let enable_client: string[] = [];
|
||||
network.flat().filter(e => e.enable).map(e => {
|
||||
enable_client.push(e.name);
|
||||
if (e.messagePostFormat == 'string') {
|
||||
msgMap.set(e.name, structuredClone(ob11Msg.stringMsg));
|
||||
} else {
|
||||
msgMap.set(e.name, structuredClone(ob11Msg.arrayMsg));
|
||||
}
|
||||
if (isSelfMsg) {
|
||||
ob11Msg.stringMsg.target_id = parseInt(message.peerUin);
|
||||
ob11Msg.arrayMsg.target_id = parseInt(message.peerUin);
|
||||
}
|
||||
});
|
||||
|
||||
let debug_network = network.flat().filter(e => e.enable && e.debug);
|
||||
if (debug_network.length > 0) {
|
||||
for (const adapter of debug_network) {
|
||||
if (adapter.name) {
|
||||
const msg = msgMap.get(adapter.name);
|
||||
if (msg) {
|
||||
msg.raw = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} else if (ob11Msg.stringMsg.message.length === 0 || ob11Msg.arrayMsg.message.length == 0) {
|
||||
return;
|
||||
|
||||
}
|
||||
const isSelfMsg = ob11Msg.user_id.toString() == this.core.selfInfo.uin;
|
||||
if (isSelfMsg && !reportSelfMessage) {
|
||||
return;
|
||||
}
|
||||
let notreportSelf_network = network.flat().filter(e => e.enable && !e.reportSelfMessage);
|
||||
if (isSelfMsg) {
|
||||
ob11Msg.target_id = parseInt(message.peerUin);
|
||||
for (const adapter of notreportSelf_network) {
|
||||
msgMap.delete(adapter.name);
|
||||
}
|
||||
}
|
||||
// if (ob11Msg.raw_message.startsWith('!set')) {
|
||||
// this.core.apis.UserApi.getUidByUinV2(ob11Msg.user_id.toString()).then(uid => {
|
||||
// if(uid){
|
||||
// this.core.apis.PacketApi.sendSetSpecialTittlePacket(message.peerUin, uid, '测试');
|
||||
// console.log('set', message.peerUin, uid);
|
||||
// }
|
||||
|
||||
// });
|
||||
|
||||
// }
|
||||
// if (ob11Msg.raw_message.startsWith('!status')) {
|
||||
// console.log('status', message.peerUin, message.senderUin);
|
||||
// let delMsg: string[] = [];
|
||||
// let peer = {
|
||||
// peerUid: message.peerUin,
|
||||
// chatType: 2,
|
||||
// };
|
||||
// this.core.apis.PacketApi.sendStatusPacket(+message.senderUin).then(async e => {
|
||||
// if (e) {
|
||||
// const { sendElements } = await this.apis.MsgApi.createSendElements([{
|
||||
// type: OB11MessageDataType.text,
|
||||
// data: {
|
||||
// text: 'status ' + JSON.stringify(e, null, 2),
|
||||
// }
|
||||
// }], peer)
|
||||
|
||||
// this.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, delMsg)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
this.networkManager.emitEvent(ob11Msg);
|
||||
this.networkManager.emitEventByNames(msgMap);
|
||||
}).catch(e => this.context.logger.logError.bind(this.context.logger)('constructMessage error: ', e));
|
||||
|
||||
this.apis.GroupApi.parseGroupEvent(message).then(groupEvent => {
|
||||
|
@ -10,6 +10,7 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
isOpen: boolean = false;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public url: string,
|
||||
public secret: string | undefined,
|
||||
public core: NapCatCore,
|
||||
|
@ -15,6 +15,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
private heartbeatRef: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public url: string,
|
||||
public reconnectIntervalInMillis: number,
|
||||
public heartbeatIntervalInMillis: number,
|
||||
@ -147,7 +148,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
this.checkStateAndReply<any>(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo));
|
||||
return;
|
||||
}
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '');
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||
this.checkStateAndReply<any>({ ...retdata });
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export type OB11EmitEventContent = OB11BaseEvent | OB11Message;
|
||||
|
||||
export interface IOB11NetworkAdapter {
|
||||
actions?: ActionMap;
|
||||
name: string;
|
||||
|
||||
onEvent<T extends OB11EmitEventContent>(event: T): void;
|
||||
|
||||
@ -15,19 +16,34 @@ export interface IOB11NetworkAdapter {
|
||||
}
|
||||
|
||||
export class OB11NetworkManager {
|
||||
adapters: IOB11NetworkAdapter[] = [];
|
||||
adapters: Map<string, IOB11NetworkAdapter> = new Map();
|
||||
|
||||
async openAllAdapters() {
|
||||
return Promise.all(this.adapters.map(adapter => adapter.open()));
|
||||
return Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.open()));
|
||||
}
|
||||
|
||||
async emitEvent(event: OB11EmitEventContent) {
|
||||
//console.log('adapters', this.adapters.length);
|
||||
return Promise.all(this.adapters.map(adapter => adapter.onEvent(event)));
|
||||
return Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.onEvent(event)));
|
||||
}
|
||||
|
||||
async emitEventByName(names: string[], event: OB11EmitEventContent) {
|
||||
return Promise.all(names.map(name => {
|
||||
const adapter = this.adapters.get(name);
|
||||
if (adapter) {
|
||||
return adapter.onEvent(event);
|
||||
}
|
||||
}));
|
||||
}
|
||||
async emitEventByNames(map:Map<string,OB11EmitEventContent>){
|
||||
return Promise.all(Array.from(map.entries()).map(([name, event]) => {
|
||||
const adapter = this.adapters.get(name);
|
||||
if (adapter) {
|
||||
return adapter.onEvent(event);
|
||||
}
|
||||
}));
|
||||
}
|
||||
registerAdapter(adapter: IOB11NetworkAdapter) {
|
||||
this.adapters.push(adapter);
|
||||
this.adapters.set(adapter.name, adapter);
|
||||
}
|
||||
|
||||
async registerAdapterAndOpen(adapter: IOB11NetworkAdapter) {
|
||||
@ -36,24 +52,28 @@ export class OB11NetworkManager {
|
||||
}
|
||||
|
||||
async closeSomeAdapters(adaptersToClose: IOB11NetworkAdapter[]) {
|
||||
this.adapters = this.adapters.filter(adapter => !adaptersToClose.includes(adapter));
|
||||
await Promise.all(adaptersToClose.map(adapter => adapter.close()));
|
||||
for (const adapter of adaptersToClose) {
|
||||
this.adapters.delete(adapter.name);
|
||||
await adapter.close();
|
||||
}
|
||||
}
|
||||
|
||||
findSomeAdapter(name: string) {
|
||||
return this.adapters.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all adapters that satisfy the predicate.
|
||||
*/
|
||||
async closeAdapterByPredicate(closeFilter: (adapter: IOB11NetworkAdapter) => boolean) {
|
||||
await this.closeSomeAdapters(this.adapters.filter(closeFilter));
|
||||
const adaptersToClose = Array.from(this.adapters.values()).filter(closeFilter);
|
||||
await this.closeSomeAdapters(adaptersToClose);
|
||||
}
|
||||
|
||||
async closeAllAdapters() {
|
||||
await Promise.all(this.adapters.map(adapter => adapter.close()));
|
||||
this.adapters = [];
|
||||
await Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.close()));
|
||||
this.adapters.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export * from './active-http';
|
||||
export * from './active-websocket';
|
||||
export * from './passive-http';
|
||||
export * from './passive-websocket';
|
||||
export * from './passive-websocket';
|
@ -12,6 +12,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
private isOpen: boolean = false;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public port: number,
|
||||
public token: string,
|
||||
public core: NapCatCore,
|
||||
@ -101,7 +102,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
const action = this.actions.get(actionName);
|
||||
if (action) {
|
||||
try {
|
||||
const result = await action.handle(payload);
|
||||
const result = await action.handle(payload,this.name);
|
||||
return res.json(result);
|
||||
} catch (error: any) {
|
||||
return res.json(OB11Response.error(error?.stack?.toString() || error?.message || 'Error Handle', 200));
|
||||
|
@ -24,6 +24,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
wsClientWithEvent: WebSocket[] = [];
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
ip: string,
|
||||
port: number,
|
||||
heartbeatInterval: number,
|
||||
@ -188,7 +189,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
this.checkStateAndReply<any>(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo), wsClient);
|
||||
return;
|
||||
}
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '');
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||
this.checkStateAndReply<any>({ ...retdata }, wsClient);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ const FrameworkBaseConfigPlugin: PluginOption[] = [
|
||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||
{ src: './src/native/packet', dest: 'dist/moehoo', flatten: false },
|
||||
{ src: './static/', dest: 'dist/static/', flatten: false },
|
||||
{ src: './src/onebot/config/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
||||
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
||||
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
||||
@ -41,7 +40,6 @@ const ShellBaseConfigPlugin: PluginOption[] = [
|
||||
{ src: './src/native/packet', dest: 'dist/moehoo', flatten: false },
|
||||
{ src: './static/', dest: 'dist/static/', flatten: false },
|
||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||
{ src: './src/onebot/config/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './package.json', dest: 'dist' },
|
||||
{ src: './launcher/', dest: 'dist', flatten: true },
|
||||
...(startScripts.map((startScript) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user