Compare commits

...

16 Commits

Author SHA1 Message Date
手瓜一十雪
daf42c8203 release: 2.4.2 2024-09-09 15:04:19 +08:00
手瓜一十雪
0a18bae3b5 fix: #351 2024-09-09 15:04:00 +08:00
手瓜一十雪
919705966c build: 2.4.1 2024-09-09 09:19:23 +08:00
手瓜一十雪
2c54aee63e build: test 2024-09-08 21:39:53 +08:00
手瓜一十雪
3f80bdf2a3 fix 2024-09-08 18:29:21 +08:00
手瓜一十雪
1c429b8dd3 fix: type 2024-09-08 18:26:07 +08:00
手瓜一十雪
5669e2b0b7 fix: 跟进实际逻辑 2024-09-08 18:21:55 +08:00
手瓜一十雪
1a6a43babf release: 2.4.0 2024-09-08 10:50:30 +08:00
手瓜一十雪
2650db5ddc fix: 字段V2 2024-09-08 10:48:33 +08:00
手瓜一十雪
255491a107 fix: hex计算问题 2024-09-08 10:41:30 +08:00
手瓜一十雪
5c64147dfa fix: encodeFile 2024-09-08 10:34:49 +08:00
手瓜一十雪
39f4118577 fix: #347 2024-09-08 10:30:30 +08:00
手瓜一十雪
f7f6e4736a fix #349 2024-09-08 10:24:36 +08:00
手瓜一十雪
c635da7ebb style: lint 2024-09-08 10:10:47 +08:00
手瓜一十雪
58124b006a Merge pull request #346 from NapNeko/Refactor-2.4.x
refactor: v2.4.0
2024-09-08 10:08:41 +08:00
手瓜一十雪
563aeccd0f refactor: fileNameEncode 2024-09-08 10:07:49 +08:00
26 changed files with 124 additions and 64 deletions

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ", "name": "NapCatQQ",
"slug": "NapCat.Framework", "slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现", "description": "高性能的 OneBot 11 协议实现",
"version": "2.3.7", "version": "2.4.2",
"icon": "./logo.png", "icon": "./logo.png",
"authors": [ "authors": [
{ {

View File

@@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "2.3.7", "version": "2.4.2",
"scripts": { "scripts": {
"build:framework": "vite build --mode framework", "build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell", "build:shell": "vite build --mode shell",

View File

@@ -215,6 +215,10 @@ export async function checkUriType(Uri: string) {
} }
return { Uri: filePath, Type: FileUriType.Local }; return { Uri: filePath, Type: FileUriType.Local };
} }
if (uri.startsWith('data:')) {
const data = uri.split(',')[1];
if (data) return { Uri: data, Type: FileUriType.Base64 };
}
}, Uri); }, Uri);
if (OtherFileRet) return OtherFileRet; if (OtherFileRet) return OtherFileRet;
@@ -231,7 +235,8 @@ export async function uri2local(dir: string, uri: string, filename: string | und
//解析File协议和本地文件 //解析File协议和本地文件
if (UriType == FileUriType.Local) { if (UriType == FileUriType.Local) {
const fileExt = path.extname(HandledUri); const fileExt = path.extname(HandledUri);
const filename = path.basename(HandledUri, fileExt); let filename = path.basename(HandledUri, fileExt);
filename += fileExt;
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: HandledUri, isLocal: true }; return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: HandledUri, isLocal: true };
} }
//接下来都要有文件名 //接下来都要有文件名
@@ -251,7 +256,7 @@ export async function uri2local(dir: string, uri: string, filename: string | und
const filePath = path.join(dir, filename); const filePath = path.join(dir, filename);
const buffer = await httpDownload(HandledUri); const buffer = await httpDownload(HandledUri);
fs.writeFileSync(filePath, buffer); fs.writeFileSync(filePath, buffer);
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath, isLocal: true }; return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath, isLocal: false };
} }
//解析Base64 //解析Base64
if (UriType == FileUriType.Base64) { if (UriType == FileUriType.Base64) {
@@ -266,7 +271,7 @@ export async function uri2local(dir: string, uri: string, filename: string | und
fileExt = ext; fileExt = ext;
filename = filename + '.' + ext; filename = filename + '.' + ext;
} }
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath, isLocal: true }; return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath, isLocal: false };
} }
return { success: false, errMsg: '未知文件类型', fileName: '', ext: '', path: '', isLocal: false }; return { success: false, errMsg: '未知文件类型', fileName: '', ext: '', path: '', isLocal: false };
} }

View File

@@ -25,8 +25,13 @@ export async function solveAsyncProblem<T extends (...args: any[]) => Promise<an
} }
export class FileNapCatOneBotUUID { export class FileNapCatOneBotUUID {
static encodeModelId(peer: Peer, modelId: string, fileId: string): string { static encodeModelId(peer: Peer, modelId: string, fileId: string, endString: string = ""): string {
return `NapCatOneBot|ModelIdFile|${peer.chatType}|${peer.peerUid}|${modelId}|${fileId}`; const data = `NapCatOneBot|ModelIdFile|${peer.chatType}|${peer.peerUid}|${modelId}|${fileId}`;
//前四个字节塞data长度
const length = Buffer.alloc(4 + data.length);
length.writeUInt32BE(data.length * 2, 0);//储存data的hex长度
length.write(data, 4);
return length.toString('hex') + endString;
} }
static decodeModelId(uuid: string): undefined | { static decodeModelId(uuid: string): undefined | {
@@ -34,8 +39,14 @@ export class FileNapCatOneBotUUID {
modelId: string, modelId: string,
fileId: string fileId: string
} { } {
if (!uuid.startsWith('NapCatOneBot|ModelIdFile|')) return undefined; //前四个字节是data长度
const data = uuid.split('|'); const length = Buffer.from(uuid.slice(0, 8), 'hex').readUInt32BE(0);
//根据length计算需要读取的长度
const dataId = uuid.slice(8, 8 + length);
//hex还原为string
const realData = Buffer.from(dataId, 'hex').toString();
if (!realData.startsWith('NapCatOneBot|ModelIdFile|')) return undefined;
const data = realData.split('|');
if (data.length !== 6) return undefined; if (data.length !== 6) return undefined;
const [, , chatType, peerUid, modelId, fileId] = data; const [, , chatType, peerUid, modelId, fileId] = data;
return { return {
@@ -48,8 +59,14 @@ export class FileNapCatOneBotUUID {
}; };
} }
static encode(peer: Peer, msgId: string, elementId: string): string { static encode(peer: Peer, msgId: string, elementId: string, endString: string = ""): string {
return `NapCatOneBot|MsgFile|${peer.chatType}|${peer.peerUid}|${msgId}|${elementId}`; const data = `NapCatOneBot|MsgFile|${peer.chatType}|${peer.peerUid}|${msgId}|${elementId}`;
//前四个字节塞data长度
//一个字节8位 一个ascii字符1字节 一个hex字符4位 表示一个ascii字符需要两个hex字符
const length = Buffer.alloc(4 + data.length);
length.writeUInt32BE(data.length * 2, 0);
length.write(data, 4);
return length.toString('hex') + endString;
} }
static decode(uuid: string): undefined | { static decode(uuid: string): undefined | {
@@ -57,8 +74,14 @@ export class FileNapCatOneBotUUID {
msgId: string, msgId: string,
elementId: string elementId: string
} { } {
if (!uuid.startsWith('NapCatOneBot|MsgFile|')) return undefined; //前四个字节是data长度
const data = uuid.split('|'); const length = Buffer.from(uuid.slice(0, 8), 'hex').readUInt32BE(0);
//根据length计算需要读取的长度
const dataId = uuid.slice(8, 8 + length);
//hex还原为string
const realData = Buffer.from(dataId, 'hex').toString();
if (!realData.startsWith('NapCatOneBot|MsgFile|')) return undefined;
const data = realData.split('|');
if (data.length !== 6) return undefined; if (data.length !== 6) return undefined;
const [, , chatType, peerUid, msgId, elementId] = data; const [, , chatType, peerUid, msgId, elementId] = data;
return { return {

View File

@@ -53,23 +53,23 @@ export class QQBasicInfoWrapper {
//此方法不要直接使用 //此方法不要直接使用
getQUAInternal() { getQUAInternal() {
switch (systemPlatform) { switch (systemPlatform) {
case 'linux': case 'linux':
return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
case 'darwin': case 'darwin':
return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
default: default:
return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
} }
} }
getAppidInternal() { getAppidInternal() {
switch (systemPlatform) { switch (systemPlatform) {
case 'linux': case 'linux':
return '537243600'; return '537243600';
case 'darwin': case 'darwin':
return '537243441'; return '537243441';
default: default:
return '537243538'; return '537243538';
} }
} }

View File

@@ -1 +1 @@
export const napCatVersion = '2.3.7'; export const napCatVersion = '2.4.2';

View File

@@ -32,6 +32,10 @@ export class NTQQGroupApi {
for (const group of this.groups) { for (const group of this.groups) {
this.groupCache.set(group.groupCode, group); this.groupCache.set(group.groupCode, group);
} }
// let text = await this.context.session.getMsgService().sendSsoCmdReqByContend(
// 'LightAppSvc.mini_app_share.AdaptShareInfo',
// JSON.stringify({ data: 'test' }));
// console.log(text);
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`); this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
} }
@@ -263,7 +267,7 @@ export class NTQQGroupApi {
return member; return member;
} }
async getGroupMemberEx(GroupCode: string, uid: string, forced = false, retry = 2) { async getGroupMemberEx(GroupCode: string, uid: string, forced = false, retry = 2) {
let data = await solveAsyncProblem((eventWrapper: NTEventWrapper, GroupCode: string, uid: string, forced = false) => { const data = await solveAsyncProblem((eventWrapper: NTEventWrapper, GroupCode: string, uid: string, forced = false) => {
return eventWrapper.callNormalEventV2( return eventWrapper.callNormalEventV2(
'NodeIKernelGroupService/getMemberInfo', 'NodeIKernelGroupService/getMemberInfo',
'NodeIKernelGroupListener/onMemberInfoChange', 'NodeIKernelGroupListener/onMemberInfoChange',
@@ -278,7 +282,7 @@ export class NTQQGroupApi {
return data[3].get(uid); return data[3].get(uid);
} }
if (retry > 0) { if (retry > 0) {
let trydata = await this.getGroupMemberEx(GroupCode, uid, true, retry - 1) as GroupMember | undefined; const trydata = await this.getGroupMemberEx(GroupCode, uid, true, retry - 1) as GroupMember | undefined;
if (trydata) return trydata; if (trydata) return trydata;
} }
return undefined; return undefined;

View File

@@ -157,7 +157,7 @@ export class NTQQWebApi {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
try { try {
let settings = JSON.stringify({ const settings = JSON.stringify({
is_show_edit_card: is_show_edit_card, is_show_edit_card: is_show_edit_card,
tip_window_type: tip_window_type, tip_window_type: tip_window_type,
confirm_required: confirm_required confirm_required: confirm_required
@@ -167,7 +167,7 @@ export class NTQQWebApi {
imgWidth: imgWidth.toString(), imgWidth: imgWidth.toString(),
imgHeight: imgHeight.toString(), imgHeight: imgHeight.toString(),
}; };
let ret: SetNoticeRetSuccess = await RequestUtil.HttpGetJson<SetNoticeRetSuccess>( const ret: SetNoticeRetSuccess = await RequestUtil.HttpGetJson<SetNoticeRetSuccess>(
`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({ `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject), bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode, qid: GroupCode,

View File

@@ -153,7 +153,10 @@ interface CommonExt {
labels: any[]; labels: any[];
qqLevel: QQLevel; qqLevel: QQLevel;
} }
export enum BuddyListReqType {
KNOMAL,
KLETTER
}
interface Pic { interface Pic {
picId: string; picId: string;
picTime: number; picTime: number;
@@ -375,8 +378,4 @@ export enum ProfileBizType {
KVAS, KVAS,
KQZONE, KQZONE,
KOTHER KOTHER
}export enum BuddyListReqType { }
KNOMAL,
KLETTER
}

View File

@@ -145,8 +145,10 @@ export class NapCatCore {
if (Info.status == 20) { if (Info.status == 20) {
this.selfInfo.online = false; this.selfInfo.online = false;
this.context.logger.log("账号状态变更为离线"); this.context.logger.log("账号状态变更为离线");
return;
} else {
this.selfInfo.online = true;
} }
this.selfInfo.online = true;
}; };
this.context.session.getProfileService().addKernelProfileListener( this.context.session.getProfileService().addKernelProfileListener(
proxiedListenerOf(profileListener, this.context.logger), proxiedListenerOf(profileListener, this.context.logger),

View File

@@ -14,7 +14,7 @@ export interface NodeIKernelBuddyService {
}> }>
}>; }>;
getBuddyListFromCache(callFrom: string): Promise<Array< getBuddyListFromCache(reqType: BuddyListReqType): Promise<Array<
{ {
categoryId: number,//9999应该跳过 那是兜底数据吧 categoryId: number,//9999应该跳过 那是兜底数据吧
categorySortId: number,//排序方式 categorySortId: number,//排序方式
@@ -23,7 +23,7 @@ export interface NodeIKernelBuddyService {
onlineCount: number,//在线数目 onlineCount: number,//在线数目
buddyUids: Array<string>//Uids buddyUids: Array<string>//Uids
}>>; }>>;
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number; addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;
getAllBuddyCount(): number; getAllBuddyCount(): number;

View File

@@ -59,6 +59,7 @@ export interface QuickLoginResult {
} }
export interface NodeIKernelLoginService { export interface NodeIKernelLoginService {
connect(): boolean;
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new(): NodeIKernelLoginService; new(): NodeIKernelLoginService;

View File

@@ -3,6 +3,11 @@ import { BizKey, ModifyProfileParams, NodeIKernelProfileListener, ProfileBizType
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
export interface NodeIKernelProfileService { export interface NodeIKernelProfileService {
getOtherFlag(callfrom: string, uids: string[]): Promise<Map<string, any>>;
getVasInfo(callfrom: string, uids: string[]): Promise<Map<string, any>>;
getRelationFlag(callfrom: string, uids: string[]): Promise<Map<string, any>>;
getUidByUin(callfrom: string, uin: Array<string>): Promise<Map<string, string>>; getUidByUin(callfrom: string, uin: Array<string>): Promise<Map<string, string>>;

View File

@@ -43,12 +43,12 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
const fileName = mixElementInner.fileName ?? ''; const fileName = mixElementInner.fileName ?? '';
let url = ''; let url = '';
if (mixElement?.picElement && rawMessage) { if (mixElement?.picElement && rawMessage) {
let tempData = const tempData =
await this.obContext.apis.MsgApi.rawToOb11Converters.picElement?.(mixElement?.picElement, rawMessage, mixElement) as OB11MessageImage | undefined; await this.obContext.apis.MsgApi.rawToOb11Converters.picElement?.(mixElement?.picElement, rawMessage, mixElement) as OB11MessageImage | undefined;
url = tempData?.data.url ?? ''; url = tempData?.data.url ?? '';
} }
if (mixElement?.videoElement && rawMessage) { if (mixElement?.videoElement && rawMessage) {
let tempData = const tempData =
await this.obContext.apis.MsgApi.rawToOb11Converters.videoElement?.(mixElement?.videoElement, rawMessage, mixElement) as OB11MessageVideo | undefined; await this.obContext.apis.MsgApi.rawToOb11Converters.videoElement?.(mixElement?.videoElement, rawMessage, mixElement) as OB11MessageVideo | undefined;
url = tempData?.data.url ?? ''; url = tempData?.data.url ?? '';
} }

View File

@@ -28,6 +28,7 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
...extendData.detail.commonExt, ...extendData.detail.commonExt,
...extendData.detail.simpleInfo.baseInfo, ...extendData.detail.simpleInfo.baseInfo,
...extendData.detail.simpleInfo.relationFlags, ...extendData.detail.simpleInfo.relationFlags,
...extendData.detail.simpleInfo.status,
user_id: parseInt(extendData.detail.uin) || 0, user_id: parseInt(extendData.detail.uin) || 0,
nickname: extendData.detail.simpleInfo.coreInfo.nick, nickname: extendData.detail.simpleInfo.coreInfo.nick,
sex: OB11UserSex.unknown, sex: OB11UserSex.unknown,

View File

@@ -51,7 +51,7 @@ export class GetGroupEssence extends BaseAction<Payload, any> {
operator_nick: msg.add_digest_nick, operator_nick: msg.add_digest_nick,
message_id: message_id, message_id: message_id,
operator_time: msg.add_digest_time, operator_time: msg.add_digest_time,
content: (await this.obContext.apis.MsgApi.parseMessage(rawMessage, 'array'))?.message content: (await this.obContext.apis.MsgApi.parseMessage(rawMessage))?.message
}; };
} }
const msgTempData = JSON.stringify({ const msgTempData = JSON.stringify({

View File

@@ -35,7 +35,7 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
const msg = await this.core.apis.MsgApi.getMsgsByMsgId( const msg = await this.core.apis.MsgApi.getMsgsByMsgId(
peer, peer,
[msgIdWithPeer?.MsgId || payload.message_id.toString()]); [msgIdWithPeer?.MsgId || payload.message_id.toString()]);
const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg.msgList[0], 'array'); const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg.msgList[0]);
if (!retMsg) throw Error('消息为空'); if (!retMsg) throw Error('消息为空');
try { try {
retMsg.message_id = MessageUnique.createUniqueMsgId(peer, msg.msgList[0].msgId)!; retMsg.message_id = MessageUnique.createUniqueMsgId(peer, msg.msgList[0].msgId)!;

View File

@@ -21,7 +21,7 @@ export default class GetRecentContact extends BaseAction<Payload, any> {
const FastMsg = await this.core.apis.MsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]); const FastMsg = await this.core.apis.MsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
if (FastMsg.msgList.length > 0) { if (FastMsg.msgList.length > 0) {
//扩展ret.info.changedList //扩展ret.info.changedList
const lastestMsg = await this.obContext.apis.MsgApi.parseMessage(FastMsg.msgList[0], 'array'); const lastestMsg = await this.obContext.apis.MsgApi.parseMessage(FastMsg.msgList[0]);
return { return {
lastestMsg: lastestMsg, lastestMsg: lastestMsg,
peerUin: t.peerUin, peerUin: t.peerUin,

View File

@@ -19,6 +19,7 @@ import { OB11GroupPokeEvent } from '@/onebot/event/notice/OB11PokeEvent';
import { OB11GroupEssenceEvent } from '@/onebot/event/notice/OB11GroupEssenceEvent'; import { OB11GroupEssenceEvent } from '@/onebot/event/notice/OB11GroupEssenceEvent';
import { OB11GroupTitleEvent } from '@/onebot/event/notice/OB11GroupTitleEvent'; import { OB11GroupTitleEvent } from '@/onebot/event/notice/OB11GroupTitleEvent';
import { FileNapCatOneBotUUID } from '@/common/helper'; import { FileNapCatOneBotUUID } from '@/common/helper';
import { pathToFileURL } from 'node:url';
export class OneBotGroupApi { export class OneBotGroupApi {
obContext: NapCatOneBot11Adapter; obContext: NapCatOneBot11Adapter;
@@ -77,7 +78,8 @@ export class OneBotGroupApi {
id: FileNapCatOneBotUUID.encode({ id: FileNapCatOneBotUUID.encode({
chatType: ChatType.KCHATTYPEGROUP, chatType: ChatType.KCHATTYPEGROUP,
peerUid: msg.peerUid, peerUid: msg.peerUid,
}, msg.msgId, element.elementId), }, msg.msgId, element.elementId, "." + element.fileElement.fileName),
url: pathToFileURL(element.fileElement.filePath).href,
name: element.fileElement.fileName, name: element.fileElement.fileName,
size: parseInt(element.fileElement.fileSize), size: parseInt(element.fileElement.fileSize),
busid: element.fileElement.fileBizId || 0, busid: element.fileElement.fileBizId || 0,

View File

@@ -1,5 +1,6 @@
import { FileNapCatOneBotUUID } from '@/common/helper'; import { FileNapCatOneBotUUID } from '@/common/helper';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { pathToFileURL } from 'node:url';
import { import {
AtType, AtType,
ChatType, ChatType,
@@ -106,7 +107,7 @@ export class OneBotMsgApi {
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
const encodedFileId = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId); const encodedFileId = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "."+element.fileName);
return { return {
type: OB11MessageDataType.image, type: OB11MessageDataType.image,
data: { data: {
@@ -114,6 +115,7 @@ export class OneBotMsgApi {
sub_type: element.picSubType, sub_type: element.picSubType,
file_id: encodedFileId, file_id: encodedFileId,
url: await this.core.apis.FileApi.getImageUrl(element), url: await this.core.apis.FileApi.getImageUrl(element),
path: element.filePath,
file_size: element.fileSize, file_size: element.fileSize,
file_unique: element.fileName file_unique: element.fileName
}, },
@@ -135,8 +137,8 @@ export class OneBotMsgApi {
data: { data: {
file: element.fileName, file: element.fileName,
path: element.filePath, path: element.filePath,
url: element.filePath, url: pathToFileURL(element.filePath).href,
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId), file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "."+element.fileName),
file_size: element.fileSize, file_size: element.fileSize,
file_unique: element.fileName, file_unique: element.fileName,
}, },
@@ -175,13 +177,16 @@ export class OneBotMsgApi {
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
const { emojiId } = _;
const dir = emojiId.substring(0, 2);
const url = `https://gxh.vip.qq.com/club/item/parcel/item/${dir}/${emojiId}/raw300.gif`;
return { return {
type: OB11MessageDataType.image, type: OB11MessageDataType.image,
data: { data: {
file: 'marketface', file: 'marketface',
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId), file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "."+_.key+".jpg"),
path: elementWrapper.elementId, path: elementWrapper.elementId,
url: elementWrapper.elementId, url: url,
file_unique: _.key file_unique: _.key
}, },
}; };
@@ -209,7 +214,7 @@ export class OneBotMsgApi {
if (records.peerUin === '284840486') { if (records.peerUin === '284840486') {
return createReplyData(records.msgId); return createReplyData(records.msgId);
} }
let replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr])) const replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr]))
.msgList.find(msg => msg.msgRandom === records.msgRandom); .msgList.find(msg => msg.msgRandom === records.msgRandom);
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
@@ -257,14 +262,14 @@ export class OneBotMsgApi {
if (!videoDownUrl) { if (!videoDownUrl) {
videoDownUrl = element.filePath; videoDownUrl = element.filePath;
} }
const fileCode = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "."+element.fileName);
return { return {
type: OB11MessageDataType.video, type: OB11MessageDataType.video,
data: { data: {
file: element.fileName, file: fileCode,
path: videoDownUrl, path: videoDownUrl,
url: videoDownUrl, url: videoDownUrl ?? pathToFileURL(element.filePath).href,
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId), file_id: fileCode,
file_size: element.fileSize, file_size: element.fileSize,
file_unique: element.fileName, file_unique: element.fileName,
}, },
@@ -277,13 +282,16 @@ export class OneBotMsgApi {
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
const fileCode = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "."+element.fileName);
return { return {
type: OB11MessageDataType.voice, type: OB11MessageDataType.voice,
data: { data: {
file: element.fileName, file: fileCode,
path: element.filePath, path: element.filePath,
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId), url: pathToFileURL(element.filePath).href,
file_id: fileCode,
file_size: element.fileSize, file_size: element.fileSize,
file_unique: element.fileName
}, },
}; };
}, },
@@ -792,18 +800,20 @@ export class OneBotMsgApi {
) { ) {
const isBlankUrl = !inputdata.url || inputdata.url === ''; const isBlankUrl = !inputdata.url || inputdata.url === '';
const isBlankFile = !inputdata.file || inputdata.file === ''; const isBlankFile = !inputdata.file || inputdata.file === '';
const isBlankPath = !inputdata.path || inputdata.path === '';
if (isBlankUrl && isBlankFile) { if (isBlankUrl && isBlankFile) {
this.core.context.logger.logError('文件消息缺少参数', inputdata); this.core.context.logger.logError('文件消息缺少参数', inputdata);
throw Error('文件消息缺少参数'); throw Error('文件消息缺少参数');
} }
const fileOrUrl = (isBlankUrl ? inputdata.file : inputdata.url) ?? ''; //path->url->file
const realUri = (!isBlankUrl ? inputdata.url :(!isBlankPath ? inputdata.path:inputdata.file ))??'';
const { const {
path, path,
isLocal, isLocal,
fileName, fileName,
errMsg, errMsg,
success, success,
} = (await uri2local(this.core.NapCatTempPath, fileOrUrl)); } = (await uri2local(this.core.NapCatTempPath, realUri));
if (!success) { if (!success) {
this.core.context.logger.logError('文件下载失败', errMsg); this.core.context.logger.logError('文件下载失败', errMsg);

View File

@@ -109,7 +109,7 @@ export class OB11Entities {
static file(peerId: string, file: Exclude<GroupFileInfoUpdateParamType['item'][0]['fileInfo'], undefined>): OB11GroupFile { static file(peerId: string, file: Exclude<GroupFileInfoUpdateParamType['item'][0]['fileInfo'], undefined>): OB11GroupFile {
return { return {
group_id: parseInt(peerId), group_id: parseInt(peerId),
file_id: FileNapCatOneBotUUID.encodeModelId({ chatType: 2, peerUid: peerId }, file.fileModelId, file.fileId), file_id: FileNapCatOneBotUUID.encodeModelId({ chatType: 2, peerUid: peerId }, file.fileModelId, file.fileId, file.fileName),
file_name: file.fileName, file_name: file.fileName,
busid: file.busId, busid: file.busId,
size: parseInt(file.fileSize), size: parseInt(file.fileSize),

View File

@@ -6,6 +6,7 @@ export interface GroupUploadFile {
name: string, name: string,
size: number, size: number,
busid: number, busid: number,
url:string;
} }
export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent { export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent {

View File

@@ -84,6 +84,8 @@ export interface OB11MessageText {
export interface OB11MessageFileBase { export interface OB11MessageFileBase {
data: { data: {
file_unique?:string,
path?: string;
thumb?: string; thumb?: string;
name?: string; name?: string;
file: string, file: string,

View File

@@ -150,7 +150,12 @@ export async function NCoreInitShell() {
}; };
loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger) as any); loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger) as any);
const isConnect = loginService.connect();
if (!isConnect) {
logger.logError('核心登录服务连接失败!');
return;
}
logger.log('核心登录服务连接成功!');
// 实现WebUi快速登录 // 实现WebUi快速登录
loginService.getLoginList().then((res) => { loginService.getLoginList().then((res) => {
// 遍历 res.LocalLoginInfoList[x].isQuickLogin是否可以 res.LocalLoginInfoList[x].uin 转为string 加入string[] 最后遍历完成调用WebUiDataRuntime.setQQQuickLoginList // 遍历 res.LocalLoginInfoList[x].isQuickLogin是否可以 res.LocalLoginInfoList[x].uin 转为string 加入string[] 最后遍历完成调用WebUiDataRuntime.setQQQuickLoginList
@@ -199,7 +204,7 @@ export async function NCoreInitShell() {
logger.log(`可用于快速登录的 QQ\n${historyLoginList logger.log(`可用于快速登录的 QQ\n${historyLoginList
.map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`)
.join('\n') .join('\n')
}`); }`);
} }
loginService.getQRCodePicture(); loginService.getQRCodePicture();
} }

View File

@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
undefined, undefined,
SettingButton('V2.3.7', 'napcat-update-button', 'secondary'), SettingButton('V2.4.2', 'napcat-update-button', 'secondary'),
), ),
]), ]),
SettingList([ SettingList([

View File

@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
void 0, void 0,
SettingButton("V2.3.7", "napcat-update-button", "secondary") SettingButton("V2.4.2", "napcat-update-button", "secondary")
) )
]), ]),
SettingList([ SettingList([