Compare commits

...

7 Commits

Author SHA1 Message Date
手瓜一十雪
1ecd5b78e6 feat: 文件移除path字段增强部分能力 2025-02-18 16:55:43 +08:00
手瓜一十雪
fca2e3c51a style: remove debug 2025-02-18 16:52:30 +08:00
手瓜一十雪
95ea761b2d feat: get_private_file_url 2025-02-18 16:51:51 +08:00
手瓜一十雪
6b3bfa1ee9 fix #810 2025-02-18 13:24:37 +08:00
bietiaop
df3e302a9d fix: #802 2025-02-14 21:26:16 +08:00
pk5ls20
c88a68c9a8 fix: typo x2 2025-02-14 20:52:31 +08:00
Mlikiowa
92d01b9cdd release: v4.5.22 2025-02-14 10:36:03 +00:00
12 changed files with 80 additions and 37 deletions

View File

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

View File

@@ -1,19 +1,21 @@
import { PlayMode } from '@/const/enum' import { PlayMode } from '@/const/enum'
import WebUIManager from '@/controllers/webui_manager'
import type { import type {
FinalMusic, FinalMusic,
Music163ListResponse, Music163ListResponse,
Music163URLResponse Music163URLResponse
} from '@/types/music' } from '@/types/music'
import WebUIManager from '@/controllers/webui_manager'
/** /**
* 获取网易云音乐歌单 * 获取网易云音乐歌单
* @param id 歌单id * @param id 歌单id
* @returns 歌单信息 * @returns 歌单信息
*/ */
export const get163MusicList = async (id: string) => { export const get163MusicList = async (id: string) => {
let res = await WebUIManager.proxy<Music163ListResponse>('https://wavesgame.top/playlist/track/all?id=' + id); let res = await WebUIManager.proxy<Music163ListResponse>(
'https://wavesgame.top/playlist/track/all?id=' + id
)
// const res = await request.get<Music163ListResponse>( // const res = await request.get<Music163ListResponse>(
// `https://wavesgame.top/playlist/track/all?id=${id}` // `https://wavesgame.top/playlist/track/all?id=${id}`
// ) // )
@@ -71,7 +73,7 @@ export const get163MusicListSongs = async (id: string) => {
if (songURL) { if (songURL) {
finalMusic.push({ finalMusic.push({
id: song.id, id: song.id,
url: songURL, url: songURL.replace(/http:\/\//, '//').replace(/https:\/\//, '//'),
title: song.name, title: song.name,
artist: song.ar.map((p) => p.name).join('/'), artist: song.ar.map((p) => p.name).join('/'),
cover: song.al.picUrl cover: song.al.picUrl

View File

@@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "4.5.21", "version": "4.5.22",
"scripts": { "scripts": {
"build:universal": "npm run build:webui && vite build --mode universal || exit 1", "build:universal": "npm run build:webui && vite build --mode universal || exit 1",
"build:framework": "npm run build:webui && vite build --mode framework || exit 1", "build:framework": "npm run build:webui && vite build --mode framework || exit 1",

View File

@@ -1 +1 @@
export const napCatVersion = '4.5.21'; export const napCatVersion = '4.5.22';

View File

@@ -175,7 +175,7 @@
"send": "713A318", "send": "713A318",
"recv": "713DB50" "recv": "713DB50"
}, },
"6.9.63.30851-x64": { "6.9.63-30851-x64": {
"send": "46C8040", "send": "46C8040",
"recv": "46CA8AC" "recv": "46CA8AC"
}, },

View File

@@ -1,22 +1,22 @@
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import {PacketContext} from '@/core/packet/context/packetContext'; import { PacketContext } from '@/core/packet/context/packetContext';
import * as trans from '@/core/packet/transformer'; import * as trans from '@/core/packet/transformer';
import {PacketMsg} from '@/core/packet/message/message'; import { PacketMsg } from '@/core/packet/message/message';
import { import {
PacketMsgFileElement, PacketMsgFileElement,
PacketMsgPicElement, PacketMsgPicElement,
PacketMsgPttElement, PacketMsgPttElement,
PacketMsgVideoElement PacketMsgVideoElement
} from '@/core/packet/message/element'; } from '@/core/packet/message/element';
import {ChatType, MsgSourceType, NTMsgType, RawMessage} from '@/core'; import { ChatType, MsgSourceType, NTMsgType, RawMessage } from '@/core';
import {MiniAppRawData, MiniAppReqParams} from '@/core/packet/entities/miniApp'; import { MiniAppRawData, MiniAppReqParams } from '@/core/packet/entities/miniApp';
import {AIVoiceChatType} from '@/core/packet/entities/aiChat'; import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
import {NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg} from '@napneko/nap-proto-core'; import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
import {IndexNode, LongMsgResult, MsgInfo} from '@/core/packet/transformer/proto'; import { IndexNode, LongMsgResult, MsgInfo } from '@/core/packet/transformer/proto';
import {OidbPacket} from '@/core/packet/transformer/base'; import { OidbPacket } from '@/core/packet/transformer/base';
import {ImageOcrResult} from '@/core/packet/entities/ocrResult'; import { ImageOcrResult } from '@/core/packet/entities/ocrResult';
import {gunzipSync} from 'zlib'; import { gunzipSync } from 'zlib';
import {PacketMsgConverter} from '@/core/packet/message/converter'; import { PacketMsgConverter } from '@/core/packet/message/converter';
export class PacketOperationContext { export class PacketOperationContext {
private readonly context: PacketContext; private readonly context: PacketContext;
@@ -59,10 +59,10 @@ export class PacketOperationContext {
const res = trans.GetStrangerInfo.parse(resp); const res = trans.GetStrangerInfo.parse(resp);
const extBigInt = BigInt(res.data.status.value); const extBigInt = BigInt(res.data.status.value);
if (extBigInt <= 10n) { if (extBigInt <= 10n) {
return {status: Number(extBigInt) * 10, ext_status: 0}; return { status: Number(extBigInt) * 10, ext_status: 0 };
} }
status = Number((extBigInt & 0xff00n) + ((extBigInt >> 16n) & 0xffn)); status = Number((extBigInt & 0xff00n) + ((extBigInt >> 16n) & 0xffn));
return {status: 10, ext_status: status}; return { status: 10, ext_status: status };
} catch { } catch {
return undefined; return undefined;
} }
@@ -79,13 +79,13 @@ export class PacketOperationContext {
const reqList = msg.flatMap(m => const reqList = msg.flatMap(m =>
m.msg.map(e => { m.msg.map(e => {
if (e instanceof PacketMsgPicElement) { if (e instanceof PacketMsgPicElement) {
return this.context.highway.uploadImage({chatType, peerUid}, e); return this.context.highway.uploadImage({ chatType, peerUid }, e);
} else if (e instanceof PacketMsgVideoElement) { } else if (e instanceof PacketMsgVideoElement) {
return this.context.highway.uploadVideo({chatType, peerUid}, e); return this.context.highway.uploadVideo({ chatType, peerUid }, e);
} else if (e instanceof PacketMsgPttElement) { } else if (e instanceof PacketMsgPttElement) {
return this.context.highway.uploadPtt({chatType, peerUid}, e); return this.context.highway.uploadPtt({ chatType, peerUid }, e);
} else if (e instanceof PacketMsgFileElement) { } else if (e instanceof PacketMsgFileElement) {
return this.context.highway.uploadFile({chatType, peerUid}, e); return this.context.highway.uploadFile({ chatType, peerUid }, e);
} }
return null; return null;
}).filter(Boolean) }).filter(Boolean)
@@ -160,6 +160,12 @@ export class PacketOperationContext {
const res = trans.DownloadGroupFile.parse(resp); const res = trans.DownloadGroupFile.parse(resp);
return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`; return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`;
} }
async GetPrivateFileUrl(self_id: string, fileUUID: string, md5: string) {
const req = trans.DownloadPrivateFile.build(self_id, fileUUID, md5);
const resp = await this.context.client.sendOidbPacket(req, true);
const res = trans.DownloadPrivateFile.parse(resp);
return `http://${res.body?.result?.server}:${res.body?.result?.port}${res.body?.result?.url?.slice(8)}&isthumb=0`;
}
async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>) { async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>) {
const req = trans.DownloadGroupPtt.build(groupUin, node); const req = trans.DownloadGroupPtt.build(groupUin, node);

View File

@@ -465,14 +465,14 @@ export interface NodeIKernelMsgService {
setMsgEmojiLikesForRole(...args: unknown[]): unknown; setMsgEmojiLikesForRole(...args: unknown[]): unknown;
clickInlineKeyboardButton(params: { clickInlineKeyboardButton(params: {
guildId: string, guildId?: string,
peerId: string, peerId: string,
botAppid: string, botAppid: string,
msgSeq: string, msgSeq: string,
buttonId: string, buttonId: string,
callback_data: string, callback_data: string,
dmFlag: number, dmFlag: number,
chatType: number chatType: number // 1私聊 2群
}): Promise<GeneralCallResult & { status: number, promptText: string, promptType: number, promptIcon: number }>; }): Promise<GeneralCallResult & { status: number, promptText: string, promptType: number, promptIcon: number }>;
setCurOnScreenMsg(...args: unknown[]): unknown; setCurOnScreenMsg(...args: unknown[]): unknown;

View File

@@ -7,6 +7,7 @@ const SchemaData = Type.Object({
bot_appid: Type.String(), bot_appid: Type.String(),
button_id: Type.String({ default: '' }), button_id: Type.String({ default: '' }),
callback_data: Type.String({ default: '' }), callback_data: Type.String({ default: '' }),
msg_seq: Type.String({ default: '10086' }),
}); });
type Payload = Static<typeof SchemaData>; type Payload = Static<typeof SchemaData>;
@@ -18,13 +19,12 @@ export class ClickInlineKeyboardButton extends OneBotAction<Payload, unknown> {
async _handle(payload: Payload) { async _handle(payload: Payload) {
return await this.core.apis.MsgApi.clickInlineKeyboardButton({ return await this.core.apis.MsgApi.clickInlineKeyboardButton({
buttonId: payload.button_id, buttonId: payload.button_id,
guildId: '',// 频道使用
peerId: payload.group_id.toString(), peerId: payload.group_id.toString(),
botAppid: payload.bot_appid, botAppid: payload.bot_appid,
msgSeq: '10086', msgSeq: payload.msg_seq,
callback_data: payload.callback_data, callback_data: payload.callback_data,
dmFlag: 0, dmFlag: 0,
chatType: 1 chatType: 2
}) })
} }
} }

View File

@@ -0,0 +1,36 @@
import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox';
const SchemaData = Type.Object({
file_id: Type.String(),
});
type Payload = Static<typeof SchemaData>;
interface GetPrivateFileUrlResponse {
url?: string;
}
export class GetPrivateFileUrl extends GetPacketStatusDepends<Payload, GetPrivateFileUrlResponse> {
override actionName = ActionName.NapCat_GetPrivateFileUrl;
override payloadSchema = SchemaData;
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id);
if (contextMsgFile?.fileUUID && contextMsgFile.msgId) {
let msg = await this.core.apis.MsgApi.getMsgsByMsgId(contextMsgFile.peer, [contextMsgFile.msgId]);
let self_id = this.core.selfInfo.uid;
let file_hash = msg.msgList[0]?.elements.map(ele => ele.fileElement?.file10MMd5)[0];
if (file_hash) {
return {
url: await this.core.apis.PacketApi.pkt.operation.GetPrivateFileUrl(self_id, contextMsgFile.fileUUID, file_hash)
};
}
}
throw new Error('real fileUUID not found!');
}
}

View File

@@ -106,6 +106,7 @@ import { SendPoke } from '@/onebot/action/packet/SendPoke';
import { SetDiyOnlineStatus } from './extends/SetDiyOnlineStatus'; import { SetDiyOnlineStatus } from './extends/SetDiyOnlineStatus';
import { BotExit } from './extends/BotExit'; import { BotExit } from './extends/BotExit';
import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton'; import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton';
import { GetPrivateFileUrl } from './file/GetPrivateFileUrl';
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) { export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
@@ -225,6 +226,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
new GetGroupSystemMsg(obContext, core), new GetGroupSystemMsg(obContext, core),
new BotExit(obContext, core), new BotExit(obContext, core),
new ClickInlineKeyboardButton(obContext, core), new ClickInlineKeyboardButton(obContext, core),
new GetPrivateFileUrl(obContext,core)
]; ];
type HandlerUnion = typeof actionHandlers[number]; type HandlerUnion = typeof actionHandlers[number];

View File

@@ -10,6 +10,7 @@ export interface InvalidCheckResult {
} }
export const ActionName = { export const ActionName = {
NapCat_GetPrivateFileUrl: 'get_private_file_url',
ClickInlineKeyboardButton: 'click_inline_keyboard_button', ClickInlineKeyboardButton: 'click_inline_keyboard_button',
GetUnidirectionalFriendList: 'get_unidirectional_friend_list', GetUnidirectionalFriendList: 'get_unidirectional_friend_list',
// onebot 11 // onebot 11

View File

@@ -132,7 +132,6 @@ export class OneBotMsgApi {
file: element.fileName, file: element.fileName,
sub_type: element.picSubType, sub_type: element.picSubType,
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,
}, },
}; };
@@ -148,13 +147,13 @@ export class OneBotMsgApi {
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
const file = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileName); FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileUuid);
FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileName);
return { return {
type: OB11MessageDataType.file, type: OB11MessageDataType.file,
data: { data: {
file: file, file: element.fileName,
path: element.filePath, file_id: element.fileUuid,
file_id: file,
file_size: element.fileSize, file_size: element.fileSize,
}, },
}; };
@@ -216,7 +215,6 @@ export class OneBotMsgApi {
data: { data: {
summary: _.faceName, // 商城表情名称 summary: _.faceName, // 商城表情名称
file: filename, file: filename,
path: url,
url: url, url: url,
key: _.key, key: _.key,
emoji_id: _.emojiId, emoji_id: _.emojiId,
@@ -339,7 +337,6 @@ export class OneBotMsgApi {
type: OB11MessageDataType.video, type: OB11MessageDataType.video,
data: { data: {
file: fileCode, file: fileCode,
path: videoDownUrl,
url: videoDownUrl, url: videoDownUrl,
file_size: element.fileSize, file_size: element.fileSize,
}, },
@@ -357,7 +354,6 @@ export class OneBotMsgApi {
type: OB11MessageDataType.voice, type: OB11MessageDataType.voice,
data: { data: {
file: fileCode, file: fileCode,
path: element.filePath,
file_size: element.fileSize, file_size: element.fileSize,
}, },
}; };