mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-16 04:45:46 +00:00
fix #98
This commit is contained in:
parent
9837ef4f36
commit
330b086b8b
@ -32,17 +32,17 @@ export class WebsocketServerBase {
|
|||||||
if (port instanceof http.Server) {
|
if (port instanceof http.Server) {
|
||||||
try {
|
try {
|
||||||
const wss = new WebSocketServer({
|
const wss = new WebSocketServer({
|
||||||
noServer: true,
|
noServer: true,
|
||||||
maxPayload: 1024 * 1024 * 1024
|
maxPayload: 1024 * 1024 * 1024
|
||||||
}).on('error', () => {
|
}).on('error', () => {
|
||||||
});
|
});
|
||||||
this.ws = wss;
|
this.ws = wss;
|
||||||
port.on('upgrade', function upgrade(request, socket, head) {
|
port.on('upgrade', function upgrade(request, socket, head) {
|
||||||
wss.handleUpgrade(request, socket, head, function done(ws) {
|
wss.handleUpgrade(request, socket, head, function done(ws) {
|
||||||
wss.emit('connection', ws, request);
|
wss.emit('connection', ws, request);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
log(`ws服务启动成功, 绑定到HTTP服务`);
|
log('ws服务启动成功, 绑定到HTTP服务');
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw Error('ws服务启动失败, 可能是绑定的HTTP服务异常' + e.toString());
|
throw Error('ws服务启动失败, 可能是绑定的HTTP服务异常' + e.toString());
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ fs.mkdirSync(configDir, { recursive: true });
|
|||||||
|
|
||||||
|
|
||||||
export class ConfigBase<T> {
|
export class ConfigBase<T> {
|
||||||
public name: string = 'default_config'
|
public name: string = 'default_config';
|
||||||
private pathName: string | null = null // 本次读取的文件路径
|
private pathName: string | null = null; // 本次读取的文件路径
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,21 +30,21 @@ export class ConfigBase<T> {
|
|||||||
return configDir;
|
return configDir;
|
||||||
}
|
}
|
||||||
getConfigPath(pathName: string | null): string {
|
getConfigPath(pathName: string | null): string {
|
||||||
const suffix = pathName ? `_${pathName}` : ''
|
const suffix = pathName ? `_${pathName}` : '';
|
||||||
const filename = `${this.name}${suffix}.json`
|
const filename = `${this.name}${suffix}.json`;
|
||||||
return path.join(this.getConfigDir(), filename);
|
return path.join(this.getConfigDir(), filename);
|
||||||
}
|
}
|
||||||
read() {
|
read() {
|
||||||
// 尝试加载当前账号配置
|
// 尝试加载当前账号配置
|
||||||
if (this.read_from_file(selfInfo.uin, false)) return this
|
if (this.read_from_file(selfInfo.uin, false)) return this;
|
||||||
// 尝试加载默认配置
|
// 尝试加载默认配置
|
||||||
return this.read_from_file('', true)
|
return this.read_from_file('', true);
|
||||||
}
|
}
|
||||||
read_from_file(pathName: string, createIfNotExist: boolean) {
|
read_from_file(pathName: string, createIfNotExist: boolean) {
|
||||||
const configPath = this.getConfigPath(pathName);
|
const configPath = this.getConfigPath(pathName);
|
||||||
if (!fs.existsSync(configPath)) {
|
if (!fs.existsSync(configPath)) {
|
||||||
if (!createIfNotExist) return null
|
if (!createIfNotExist) return null;
|
||||||
this.pathName = pathName // 记录有效的设置文件
|
this.pathName = pathName; // 记录有效的设置文件
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
||||||
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
|
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
|
||||||
@ -77,7 +77,7 @@ export class ConfigBase<T> {
|
|||||||
Object.assign(this, config);
|
Object.assign(this, config);
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
// 用户要求强制写入,则变更当前文件为目标文件
|
// 用户要求强制写入,则变更当前文件为目标文件
|
||||||
this.pathName = `${selfInfo.uin}`
|
this.pathName = `${selfInfo.uin}`;
|
||||||
}
|
}
|
||||||
const configPath = this.getConfigPath(this.pathName);
|
const configPath = this.getConfigPath(this.pathName);
|
||||||
try {
|
try {
|
||||||
|
@ -150,7 +150,7 @@ export class NTEventWrapper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
|
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
|
||||||
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
|
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
|
||||||
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
|
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
|
||||||
const id = randomUUID();
|
const id = randomUUID();
|
||||||
let complete = 0;
|
let complete = 0;
|
||||||
|
@ -93,8 +93,8 @@ class MessageUniqueWrapper {
|
|||||||
if (!heads) {
|
if (!heads) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value));
|
const data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value));
|
||||||
let ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
|
const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
|
||||||
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
|
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
|
||||||
}
|
}
|
||||||
createMsg(peer: Peer, msgId: string): number | undefined {
|
createMsg(peer: Peer, msgId: string): number | undefined {
|
||||||
|
@ -14,7 +14,7 @@ export function sleep(ms: number): Promise<void> {
|
|||||||
|
|
||||||
export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> {
|
export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> {
|
||||||
const timeoutPromise = new Promise<T>((_, reject) =>
|
const timeoutPromise = new Promise<T>((_, reject) =>
|
||||||
setTimeout(() => reject(new Error("PromiseTimer: Operation timed out")), ms)
|
setTimeout(() => reject(new Error('PromiseTimer: Operation timed out')), ms)
|
||||||
);
|
);
|
||||||
return Promise.race([promise, timeoutPromise]);
|
return Promise.race([promise, timeoutPromise]);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export class FetchCustomFace extends BaseAction<Payload, string[]> {
|
|||||||
actionName = ActionName.FetchCustomFace;
|
actionName = ActionName.FetchCustomFace;
|
||||||
PayloadSchema = SchemaData;
|
PayloadSchema = SchemaData;
|
||||||
protected async _handle(payload: Payload) {
|
protected async _handle(payload: Payload) {
|
||||||
let ret = await NTQQMsgApi.fetchFavEmojiList(payload.count || 48);
|
const ret = await NTQQMsgApi.fetchFavEmojiList(payload.count || 48);
|
||||||
return ret.emojiInfoList.map(e => e.url);
|
return ret.emojiInfoList.map(e => e.url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
const { enableLocalFile2Url } = ob11Config;
|
const { enableLocalFile2Url } = ob11Config;
|
||||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||||
if (NTSearchNameResult.length !== 0) {
|
if (NTSearchNameResult.length !== 0) {
|
||||||
let MsgId = NTSearchNameResult[0].msgId;
|
const MsgId = NTSearchNameResult[0].msgId;
|
||||||
let peer: Peer | undefined = undefined;
|
let peer: Peer | undefined = undefined;
|
||||||
if (NTSearchNameResult[0].chatType == ChatType.group) {
|
if (NTSearchNameResult[0].chatType == ChatType.group) {
|
||||||
peer = { chatType: ChatType.group, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode };
|
peer = { chatType: ChatType.group, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode };
|
||||||
@ -56,12 +56,12 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
if (!peer) {
|
if (!peer) {
|
||||||
throw new Error('chattype not support');
|
throw new Error('chattype not support');
|
||||||
}
|
}
|
||||||
let msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList;
|
const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList;
|
||||||
if (!msgList || msgList.length == 0) {
|
if (!msgList || msgList.length == 0) {
|
||||||
throw new Error('msg not found');
|
throw new Error('msg not found');
|
||||||
}
|
}
|
||||||
let msg = msgList[0];
|
const msg = msgList[0];
|
||||||
let file = msg.elements.filter(e => e.elementType == NTSearchNameResult[0].elemType);
|
const file = msg.elements.filter(e => e.elementType == NTSearchNameResult[0].elemType);
|
||||||
if (file.length == 0) {
|
if (file.length == 0) {
|
||||||
throw new Error('file not found');
|
throw new Error('file not found');
|
||||||
}
|
}
|
||||||
@ -73,11 +73,11 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
file_name: NTSearchNameResult[0].fileName
|
file_name: NTSearchNameResult[0].fileName
|
||||||
};
|
};
|
||||||
if (enableLocalFile2Url) {
|
if (enableLocalFile2Url) {
|
||||||
try {
|
try {
|
||||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error('文件下载失败. ' + e);
|
throw new Error('文件下载失败. ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//不手动删除?文件持久化了
|
//不手动删除?文件持久化了
|
||||||
return res;
|
return res;
|
||||||
|
@ -35,9 +35,9 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
|
|||||||
const peer = {
|
const peer = {
|
||||||
chatType: ChatType.group,
|
chatType: ChatType.group,
|
||||||
peerUid: group.groupCode
|
peerUid: group.groupCode
|
||||||
}
|
};
|
||||||
if (!payload.message_seq) {
|
if (!payload.message_seq) {
|
||||||
let latestMsgId = (await NTQQMsgApi.getLastestMsgByUids(peer)).msgList[0].msgId;
|
const latestMsgId = (await NTQQMsgApi.getLastestMsgByUids(peer)).msgList[0].msgId;
|
||||||
targetMsgShortId = await MessageUnique.createMsg(peer, latestMsgId || '0');
|
targetMsgShortId = await MessageUnique.createMsg(peer, latestMsgId || '0');
|
||||||
}
|
}
|
||||||
const startMsgId = (await MessageUnique.getMsgIdAndPeerByShortId(targetMsgShortId ?? (payload.message_seq ?? 0)))?.MsgId || '0';
|
const startMsgId = (await MessageUnique.getMsgIdAndPeerByShortId(targetMsgShortId ?? (payload.message_seq ?? 0)))?.MsgId || '0';
|
||||||
|
@ -9,43 +9,43 @@ import { uri2local } from '@/common/utils/file';
|
|||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { NTQQFriendApi, NTQQUserApi } from '@/core';
|
import { NTQQFriendApi, NTQQUserApi } from '@/core';
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
user_id: { type: ['number', 'string'] },
|
user_id: { type: ['number', 'string'] },
|
||||||
file: { type: 'string' },
|
file: { type: 'string' },
|
||||||
name: { type: 'string' }
|
name: { type: 'string' }
|
||||||
},
|
},
|
||||||
required: ['user_id', 'file', 'name']
|
required: ['user_id', 'file', 'name']
|
||||||
} as const satisfies JSONSchema;
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
export default class GoCQHTTPUploadPrivateFile extends BaseAction<Payload, null> {
|
export default class GoCQHTTPUploadPrivateFile extends BaseAction<Payload, null> {
|
||||||
actionName = ActionName.GOCQHTTP_UploadPrivateFile;
|
actionName = ActionName.GOCQHTTP_UploadPrivateFile;
|
||||||
PayloadSchema = SchemaData;
|
PayloadSchema = SchemaData;
|
||||||
async getPeer(payload: Payload): Promise<Peer> {
|
async getPeer(payload: Payload): Promise<Peer> {
|
||||||
if (payload.user_id) {
|
if (payload.user_id) {
|
||||||
const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString());
|
const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString());
|
||||||
if (!peerUid) {
|
if (!peerUid) {
|
||||||
throw `私聊${payload.user_id}不存在`;
|
throw `私聊${payload.user_id}不存在`;
|
||||||
}
|
}
|
||||||
const isBuddy = await NTQQFriendApi.isBuddy(peerUid);
|
const isBuddy = await NTQQFriendApi.isBuddy(peerUid);
|
||||||
return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid };
|
return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid };
|
||||||
}
|
|
||||||
throw '缺少参数 user_id';
|
|
||||||
}
|
}
|
||||||
protected async _handle(payload: Payload): Promise<null> {
|
throw '缺少参数 user_id';
|
||||||
let peer = await this.getPeer(payload);
|
}
|
||||||
let file = payload.file;
|
protected async _handle(payload: Payload): Promise<null> {
|
||||||
if (fs.existsSync(file)) {
|
const peer = await this.getPeer(payload);
|
||||||
file = `file://${file}`;
|
let file = payload.file;
|
||||||
}
|
if (fs.existsSync(file)) {
|
||||||
const downloadResult = await uri2local(file);
|
file = `file://${file}`;
|
||||||
if (downloadResult.errMsg) {
|
|
||||||
throw new Error(downloadResult.errMsg);
|
|
||||||
}
|
|
||||||
const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(downloadResult.path, payload.name);
|
|
||||||
await sendMsg(peer, [sendFileEle], [], true);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
const downloadResult = await uri2local(file);
|
||||||
|
if (downloadResult.errMsg) {
|
||||||
|
throw new Error(downloadResult.errMsg);
|
||||||
|
}
|
||||||
|
const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(downloadResult.path, payload.name);
|
||||||
|
await sendMsg(peer, [sendFileEle], [], true);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,9 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let LastestMsgList = await NTQQGroupApi.getLastestMsg(payload.group_id.toString(), [payload.user_id.toString()]);
|
const LastestMsgList = await NTQQGroupApi.getLastestMsg(payload.group_id.toString(), [payload.user_id.toString()]);
|
||||||
if (LastestMsgList?.msgList?.length && LastestMsgList?.msgList?.length > 0) {
|
if (LastestMsgList?.msgList?.length && LastestMsgList?.msgList?.length > 0) {
|
||||||
let last_send_time = LastestMsgList.msgList[0].msgTime;
|
const last_send_time = LastestMsgList.msgList[0].msgTime;
|
||||||
if (last_send_time && last_send_time != '0' && last_send_time != '') {
|
if (last_send_time && last_send_time != '0' && last_send_time != '') {
|
||||||
retMember.last_sent_time = parseInt(last_send_time);
|
retMember.last_sent_time = parseInt(last_send_time);
|
||||||
retMember.join_time = Math.round(Date.now() / 1000);//兜底数据 防止群管乱杀
|
retMember.join_time = Math.round(Date.now() / 1000);//兜底数据 防止群管乱杀
|
||||||
|
@ -39,7 +39,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
|
|||||||
|
|
||||||
const MemberMap: Map<number, OB11GroupMember> = new Map<number, OB11GroupMember>();
|
const MemberMap: Map<number, OB11GroupMember> = new Map<number, OB11GroupMember>();
|
||||||
// 转为Map 方便索引
|
// 转为Map 方便索引
|
||||||
let date = Math.round(Date.now() / 1000);
|
const date = Math.round(Date.now() / 1000);
|
||||||
for (let i = 0, len = _groupMembers.length; i < len; i++) {
|
for (let i = 0, len = _groupMembers.length; i < len; i++) {
|
||||||
// 保证基础数据有这个 同时避免群管插件过于依赖这个杀了
|
// 保证基础数据有这个 同时避免群管插件过于依赖这个杀了
|
||||||
_groupMembers[i].join_time = date;
|
_groupMembers[i].join_time = date;
|
||||||
@ -65,7 +65,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const DateMap = await NTQQGroupApi.getGroupMemberLastestSendTimeCache(payload.group_id.toString());//开始从本地拉取
|
const DateMap = await NTQQGroupApi.getGroupMemberLastestSendTimeCache(payload.group_id.toString());//开始从本地拉取
|
||||||
for (let DateUin of DateMap.keys()) {
|
for (const DateUin of DateMap.keys()) {
|
||||||
const MemberData = MemberMap.get(parseInt(DateUin));
|
const MemberData = MemberMap.get(parseInt(DateUin));
|
||||||
if (MemberData) {
|
if (MemberData) {
|
||||||
MemberData.last_sent_time = parseInt(DateMap.get(DateUin)!);
|
MemberData.last_sent_time = parseInt(DateMap.get(DateUin)!);
|
||||||
|
@ -213,7 +213,7 @@ export default async function createSendElements(
|
|||||||
ignoreTypes: OB11MessageDataType[] = []
|
ignoreTypes: OB11MessageDataType[] = []
|
||||||
) {
|
) {
|
||||||
const deleteAfterSentFiles: string[] = [];
|
const deleteAfterSentFiles: string[] = [];
|
||||||
let callResultList: Array<Promise<SendMessageElement | undefined>> = [];
|
const callResultList: Array<Promise<SendMessageElement | undefined>> = [];
|
||||||
for (const sendMsg of messageData) {
|
for (const sendMsg of messageData) {
|
||||||
if (ignoreTypes.includes(sendMsg.type)) {
|
if (ignoreTypes.includes(sendMsg.type)) {
|
||||||
continue;
|
continue;
|
||||||
@ -224,7 +224,7 @@ export default async function createSendElements(
|
|||||||
)?.catch(undefined);
|
)?.catch(undefined);
|
||||||
callResultList.push(callResult);
|
callResultList.push(callResult);
|
||||||
}
|
}
|
||||||
let ret = await Promise.all(callResultList);
|
const ret = await Promise.all(callResultList);
|
||||||
const sendElements: SendMessageElement[] = ret.filter(ele => ele) as SendMessageElement[];
|
const sendElements: SendMessageElement[] = ret.filter(ele => ele) as SendMessageElement[];
|
||||||
return { sendElements, deleteAfterSentFiles };
|
return { sendElements, deleteAfterSentFiles };
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ export async function handleForwardNode(destPeer: Peer, messageNodes: OB11Messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// logDebug('nodeMsgArray', nodeMsgArray);
|
// logDebug('nodeMsgArray', nodeMsgArray);
|
||||||
nodeMsgIds = nodeMsgArray.map(msg => msg.msgId);
|
nodeMsgIds = nodeMsgArray.map(msg => msg.msgId);
|
||||||
if (needSendSelf) {
|
if (needSendSelf) {
|
||||||
//logDebug('需要克隆转发消息');
|
//logDebug('需要克隆转发消息');
|
||||||
|
@ -99,7 +99,7 @@ export enum ActionName {
|
|||||||
GetRecentContact = 'get_recent_contact',
|
GetRecentContact = 'get_recent_contact',
|
||||||
_MarkAllMsgAsRead = '_mark_all_as_read',
|
_MarkAllMsgAsRead = '_mark_all_as_read',
|
||||||
GetProfileLike = 'get_profile_like',
|
GetProfileLike = 'get_profile_like',
|
||||||
SetGroupHeader = "set_group_head",
|
SetGroupHeader = 'set_group_head',
|
||||||
FetchCustomFace = "fetch_custom_face",
|
FetchCustomFace = 'fetch_custom_face',
|
||||||
GOCQHTTP_UploadPrivateFile = 'upload_private_file'
|
GOCQHTTP_UploadPrivateFile = 'upload_private_file'
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ export interface OB11Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Config extends ConfigBase<OB11Config> implements OB11Config {
|
class Config extends ConfigBase<OB11Config> implements OB11Config {
|
||||||
name: string = 'onebot11'
|
name: string = 'onebot11';
|
||||||
http = {
|
http = {
|
||||||
enable: false,
|
enable: false,
|
||||||
host: '',
|
host: '',
|
||||||
|
@ -12,12 +12,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
AtType,
|
AtType,
|
||||||
ChatType,
|
ChatType,
|
||||||
ElementType, FaceIndex,
|
FaceIndex,
|
||||||
Friend,
|
Friend,
|
||||||
GrayTipElementSubType,
|
GrayTipElementSubType,
|
||||||
Group,
|
Group,
|
||||||
GroupMember,
|
GroupMember,
|
||||||
IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, mFaceCache,
|
mFaceCache,
|
||||||
Peer,
|
Peer,
|
||||||
RawMessage,
|
RawMessage,
|
||||||
SelfInfo,
|
SelfInfo,
|
||||||
@ -76,7 +76,12 @@ export class OB11Constructor {
|
|||||||
if (msg.chatType == ChatType.group) {
|
if (msg.chatType == ChatType.group) {
|
||||||
resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼
|
resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼
|
||||||
resMsg.group_id = parseInt(msg.peerUin);
|
resMsg.group_id = parseInt(msg.peerUin);
|
||||||
const member = await getGroupMember(msg.peerUin, msg.senderUin!);
|
let member = await getGroupMember(msg.peerUin, msg.senderUin!);
|
||||||
|
if (!member) {
|
||||||
|
//直接去QQNative取
|
||||||
|
const memberList = await NTQQGroupApi.getGroupMembers(msg.peerUin);
|
||||||
|
member = memberList.get(msg.senderUin!);
|
||||||
|
}
|
||||||
if (member) {
|
if (member) {
|
||||||
resMsg.sender.role = OB11Constructor.groupMemberRole(member.role);
|
resMsg.sender.role = OB11Constructor.groupMemberRole(member.role);
|
||||||
resMsg.sender.nickname = member.nick;
|
resMsg.sender.nickname = member.nick;
|
||||||
@ -138,12 +143,12 @@ export class OB11Constructor {
|
|||||||
//log("收到回复消息", element.replyElement);
|
//log("收到回复消息", element.replyElement);
|
||||||
try {
|
try {
|
||||||
//做这么多都是因为NC速度太快 可能nt还没有写入数据库
|
//做这么多都是因为NC速度太快 可能nt还没有写入数据库
|
||||||
let records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords);
|
const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords);
|
||||||
|
|
||||||
if (!records) {
|
if (!records) {
|
||||||
throw new Error('Record筛选失败');
|
throw new Error('Record筛选失败');
|
||||||
}
|
}
|
||||||
let peer = {
|
const peer = {
|
||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
@ -165,7 +170,7 @@ export class OB11Constructor {
|
|||||||
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0];
|
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0];
|
||||||
}
|
}
|
||||||
if (!replyMsg || replyMsg.msgRandom !== records.msgRandom) {
|
if (!replyMsg || replyMsg.msgRandom !== records.msgRandom) {
|
||||||
throw new Error('回复消息消息验证失败')
|
throw new Error('回复消息消息验证失败');
|
||||||
}
|
}
|
||||||
if (replyMsg) {
|
if (replyMsg) {
|
||||||
message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString();
|
message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString();
|
||||||
@ -209,13 +214,13 @@ export class OB11Constructor {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
FileElement.fileSize,
|
FileElement.fileSize,
|
||||||
FileElement.fileName
|
FileElement.fileName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (element.videoElement) {
|
else if (element.videoElement) {
|
||||||
@ -235,7 +240,7 @@ export class OB11Constructor {
|
|||||||
let videoDownUrl = undefined;
|
let videoDownUrl = undefined;
|
||||||
|
|
||||||
if (videoUrl) {
|
if (videoUrl) {
|
||||||
let videoDownUrlTemp = videoUrl.find((url) => { if (url.url) { return true; } return false; });
|
const videoDownUrlTemp = videoUrl.find((url) => { if (url.url) { return true; } return false; });
|
||||||
if (videoDownUrlTemp) {
|
if (videoDownUrlTemp) {
|
||||||
videoDownUrl = videoDownUrlTemp.url;
|
videoDownUrl = videoDownUrlTemp.url;
|
||||||
}
|
}
|
||||||
@ -256,20 +261,20 @@ export class OB11Constructor {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
videoElement.fileSize || '0',
|
videoElement.fileSize || '0',
|
||||||
videoElement.fileName
|
videoElement.fileName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (element.pttElement) {
|
else if (element.pttElement) {
|
||||||
message_data['type'] = OB11MessageDataType.voice;
|
message_data['type'] = OB11MessageDataType.voice;
|
||||||
message_data['data']['file'] = element.pttElement.fileName;
|
message_data['data']['file'] = element.pttElement.fileName;
|
||||||
message_data['data']['path'] = element.pttElement.filePath;
|
message_data['data']['path'] = element.pttElement.filePath;
|
||||||
message_data["data"]["file_id"] = element.pttElement.fileUuid;
|
message_data['data']['file_id'] = element.pttElement.fileUuid;
|
||||||
message_data['data']['file_size'] = element.pttElement.fileSize;
|
message_data['data']['file_size'] = element.pttElement.fileSize;
|
||||||
// dbUtil.addFileCache({
|
// dbUtil.addFileCache({
|
||||||
// name: element.pttElement.fileName,
|
// name: element.pttElement.fileName,
|
||||||
@ -287,13 +292,13 @@ export class OB11Constructor {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
element.pttElement.fileSize || '0',
|
element.pttElement.fileSize || '0',
|
||||||
element.pttElement.fileUuid || ''
|
element.pttElement.fileUuid || ''
|
||||||
);
|
);
|
||||||
//以uuid作为文件名
|
//以uuid作为文件名
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ export interface LineDevice {
|
|||||||
device_name: string;
|
device_name: string;
|
||||||
device_kind: string;
|
device_kind: string;
|
||||||
}
|
}
|
||||||
export let DeviceList = new Array<LineDevice>();
|
export const DeviceList = new Array<LineDevice>();
|
||||||
|
|
||||||
//peer->cached(boolen)
|
//peer->cached(boolen)
|
||||||
// const PokeCache = new Map<string, boolean>();
|
// const PokeCache = new Map<string, boolean>();
|
||||||
@ -419,7 +419,7 @@ export class NapCatOnebot11 {
|
|||||||
if (check_http_ws_equal(NewOb11) || check_http_ws_equal(OldConfig)) {
|
if (check_http_ws_equal(NewOb11) || check_http_ws_equal(OldConfig)) {
|
||||||
// http与ws共站 需要同步重启
|
// http与ws共站 需要同步重启
|
||||||
if (isHttpChanged || isWsChanged) {
|
if (isHttpChanged || isWsChanged) {
|
||||||
log("http与ws进行热重载")
|
log('http与ws进行热重载');
|
||||||
ob11WebsocketServer.stop();
|
ob11WebsocketServer.stop();
|
||||||
ob11HTTPServer.stop();
|
ob11HTTPServer.stop();
|
||||||
if (NewOb11.http.enable) {
|
if (NewOb11.http.enable) {
|
||||||
@ -436,7 +436,7 @@ export class NapCatOnebot11 {
|
|||||||
} else {
|
} else {
|
||||||
// http重启逻辑
|
// http重启逻辑
|
||||||
if (isHttpChanged) {
|
if (isHttpChanged) {
|
||||||
log("http进行热重载")
|
log('http进行热重载');
|
||||||
ob11HTTPServer.stop();
|
ob11HTTPServer.stop();
|
||||||
if (NewOb11.http.enable) {
|
if (NewOb11.http.enable) {
|
||||||
ob11HTTPServer.start(NewOb11.http.port, NewOb11.http.host);
|
ob11HTTPServer.start(NewOb11.http.port, NewOb11.http.host);
|
||||||
@ -445,7 +445,7 @@ export class NapCatOnebot11 {
|
|||||||
|
|
||||||
// ws重启逻辑
|
// ws重启逻辑
|
||||||
if (isWsChanged) {
|
if (isWsChanged) {
|
||||||
log("ws进行热重载")
|
log('ws进行热重载');
|
||||||
ob11WebsocketServer.stop();
|
ob11WebsocketServer.stop();
|
||||||
if (NewOb11.ws.enable) {
|
if (NewOb11.ws.enable) {
|
||||||
ob11WebsocketServer.start(NewOb11.ws.port, NewOb11.ws.host);
|
ob11WebsocketServer.start(NewOb11.ws.port, NewOb11.ws.host);
|
||||||
@ -455,7 +455,7 @@ export class NapCatOnebot11 {
|
|||||||
|
|
||||||
// 反向ws重启逻辑
|
// 反向ws重启逻辑
|
||||||
if (isWsReverseChanged) {
|
if (isWsReverseChanged) {
|
||||||
log("反向ws进行热重载")
|
log('反向ws进行热重载');
|
||||||
ob11ReverseWebsockets.stop();
|
ob11ReverseWebsockets.stop();
|
||||||
if (NewOb11.reverseWs.enable) {
|
if (NewOb11.reverseWs.enable) {
|
||||||
ob11ReverseWebsockets.start();
|
ob11ReverseWebsockets.start();
|
||||||
|
@ -23,7 +23,7 @@ async function tryUseHost(host: string): Promise<string> {
|
|||||||
|
|
||||||
server.on('error', (err: any) => {
|
server.on('error', (err: any) => {
|
||||||
if (err.code === 'EADDRNOTAVAIL') {
|
if (err.code === 'EADDRNOTAVAIL') {
|
||||||
reject("主机地址验证失败,可能为非本机地址");
|
reject('主机地址验证失败,可能为非本机地址');
|
||||||
} else {
|
} else {
|
||||||
reject(`遇到错误: ${err.code}`);
|
reject(`遇到错误: ${err.code}`);
|
||||||
}
|
}
|
||||||
@ -87,10 +87,10 @@ class WebUiConfigWrapper {
|
|||||||
return this.WebUiConfigData;
|
return this.WebUiConfigData;
|
||||||
}
|
}
|
||||||
const defaultconfig: WebUiConfigType = {
|
const defaultconfig: WebUiConfigType = {
|
||||||
host: "0.0.0.0",
|
host: '0.0.0.0',
|
||||||
port: 6099,
|
port: 6099,
|
||||||
prefix: "",
|
prefix: '',
|
||||||
token: "", // 默认先填空,空密码无法登录
|
token: '', // 默认先填空,空密码无法登录
|
||||||
loginRate: 3
|
loginRate: 3
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
@ -109,8 +109,8 @@ class WebUiConfigWrapper {
|
|||||||
// 更新配置字段后新增字段可能会缺失,同步一下
|
// 更新配置字段后新增字段可能会缺失,同步一下
|
||||||
const parsedConfig = this.applyDefaults(JSON.parse(fileContent) as Partial<WebUiConfigType>, defaultconfig);
|
const parsedConfig = this.applyDefaults(JSON.parse(fileContent) as Partial<WebUiConfigType>, defaultconfig);
|
||||||
|
|
||||||
if (!parsedConfig.prefix.startsWith("/")) parsedConfig.prefix = "/" + parsedConfig.prefix;
|
if (!parsedConfig.prefix.startsWith('/')) parsedConfig.prefix = '/' + parsedConfig.prefix;
|
||||||
if (parsedConfig.prefix.endsWith("/")) parsedConfig.prefix = parsedConfig.prefix.slice(0, -1);
|
if (parsedConfig.prefix.endsWith('/')) parsedConfig.prefix = parsedConfig.prefix.slice(0, -1);
|
||||||
// 配置已经被操作过了,还是回写一下吧,不然新配置不会出现在配置文件里
|
// 配置已经被操作过了,还是回写一下吧,不然新配置不会出现在配置文件里
|
||||||
writeFileSync(configPath, JSON.stringify(parsedConfig, null, 4));
|
writeFileSync(configPath, JSON.stringify(parsedConfig, null, 4));
|
||||||
// 不希望回写的配置放后面
|
// 不希望回写的配置放后面
|
||||||
@ -118,14 +118,14 @@ class WebUiConfigWrapper {
|
|||||||
// 查询主机地址是否可用
|
// 查询主机地址是否可用
|
||||||
const [host_err, host] = await tryUseHost(parsedConfig.host).then(data => [null, data as string]).catch(err => [err, null]);
|
const [host_err, host] = await tryUseHost(parsedConfig.host).then(data => [null, data as string]).catch(err => [err, null]);
|
||||||
if (host_err) {
|
if (host_err) {
|
||||||
logError("host不可用", host_err)
|
logError('host不可用', host_err);
|
||||||
parsedConfig.port = 0; // 设置为0,禁用WebUI
|
parsedConfig.port = 0; // 设置为0,禁用WebUI
|
||||||
} else {
|
} else {
|
||||||
parsedConfig.host = host;
|
parsedConfig.host = host;
|
||||||
// 修正端口占用情况
|
// 修正端口占用情况
|
||||||
const [port_err, port] = await tryUsePort(parsedConfig.port, parsedConfig.host).then(data => [null, data as number]).catch(err => [err, null]);
|
const [port_err, port] = await tryUsePort(parsedConfig.port, parsedConfig.host).then(data => [null, data as number]).catch(err => [err, null]);
|
||||||
if (port_err) {
|
if (port_err) {
|
||||||
logError("port不可用", port_err)
|
logError('port不可用', port_err);
|
||||||
parsedConfig.port = 0; // 设置为0,禁用WebUI
|
parsedConfig.port = 0; // 设置为0,禁用WebUI
|
||||||
} else {
|
} else {
|
||||||
parsedConfig.port = port;
|
parsedConfig.port = port;
|
||||||
|
Loading…
Reference in New Issue
Block a user