mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: Implement complete transform & Build & Upload FakeForwardMsg
This commit is contained in:
parent
9c17dc1b8f
commit
c9e3bbcd9f
@ -1,17 +1,18 @@
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import { InstanceContext, NapCatCore } from '..';
|
import {ChatType, InstanceContext, NapCatCore} from '..';
|
||||||
import offset from '@/core/external/offset.json';
|
import offset from '@/core/external/offset.json';
|
||||||
import { PacketClient, RecvPacketData } from '@/core/packet/client';
|
import {PacketClient, RecvPacketData} from '@/core/packet/client';
|
||||||
import { PacketSession } from "@/core/packet/session";
|
import {PacketSession} from "@/core/packet/session";
|
||||||
import { PacketHexStr, PacketPacker } from "@/core/packet/packer";
|
import {PacketHexStr} from "@/core/packet/packer";
|
||||||
import { NapProtoMsg } from '@/core/packet/proto/NapProto';
|
import {NapProtoMsg} from '@/core/packet/proto/NapProto';
|
||||||
import { OidbSvcTrpcTcp0X9067_202_Rsp_Body } from '@/core/packet/proto/oidb/Oidb.0x9067_202';
|
import {OidbSvcTrpcTcp0X9067_202_Rsp_Body} from '@/core/packet/proto/oidb/Oidb.0x9067_202';
|
||||||
import { OidbSvcTrpcTcpBase, OidbSvcTrpcTcpBaseRsp } from '@/core/packet/proto/oidb/OidbBase';
|
import {OidbSvcTrpcTcpBase, OidbSvcTrpcTcpBaseRsp} from '@/core/packet/proto/oidb/OidbBase';
|
||||||
import { OidbSvcTrpcTcp0XFE1_2RSP } from '@/core/packet/proto/oidb/Oidb.0XFE1_2';
|
import {OidbSvcTrpcTcp0XFE1_2RSP} from '@/core/packet/proto/oidb/Oidb.0XFE1_2';
|
||||||
import { LogWrapper } from "@/common/log";
|
import {LogWrapper} from "@/common/log";
|
||||||
import { SendLongMsgResp } from "@/core/packet/proto/message/action";
|
import {SendLongMsgResp} from "@/core/packet/proto/message/action";
|
||||||
import { PacketMsg } from "@/core/packet/msg/message";
|
import {PacketMsg} from "@/core/packet/msg/message";
|
||||||
import { OidbSvcTrpcTcp0x6D6Response } from "@/core/packet/proto/oidb/Oidb.0x6D6";
|
import {OidbSvcTrpcTcp0x6D6Response} from "@/core/packet/proto/oidb/Oidb.0x6D6";
|
||||||
|
import {PacketMsgPicElement} from "@/core/packet/msg/element";
|
||||||
|
|
||||||
interface OffsetType {
|
interface OffsetType {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
@ -28,14 +29,12 @@ export class NTQQPacketApi {
|
|||||||
logger: LogWrapper
|
logger: LogWrapper
|
||||||
serverUrl: string | undefined;
|
serverUrl: string | undefined;
|
||||||
qqVersion: string | undefined;
|
qqVersion: string | undefined;
|
||||||
packetPacker: PacketPacker;
|
|
||||||
packetSession: PacketSession | undefined;
|
packetSession: PacketSession | undefined;
|
||||||
|
|
||||||
constructor(context: InstanceContext, core: NapCatCore) {
|
constructor(context: InstanceContext, core: NapCatCore) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.core = core;
|
this.core = core;
|
||||||
this.logger = core.context.logger;
|
this.logger = core.context.logger;
|
||||||
this.packetPacker = new PacketPacker(this.logger);
|
|
||||||
this.packetSession = undefined;
|
this.packetSession = undefined;
|
||||||
const config = this.core.configLoader.configData;
|
const config = this.core.configLoader.configData;
|
||||||
if (config && config.packetServer && config.packetServer.length > 0) {
|
if (config && config.packetServer && config.packetServer.length > 0) {
|
||||||
@ -70,13 +69,13 @@ export class NTQQPacketApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendPokePacket(group: number, peer: number) {
|
async sendPokePacket(group: number, peer: number) {
|
||||||
const data = this.packetPacker.packPokePacket(group, peer);
|
const data = this.packetSession?.packer.packPokePacket(group, peer);
|
||||||
await this.sendPacket('OidbSvcTrpcTcp.0xed3_1', data, false);
|
await this.sendPacket('OidbSvcTrpcTcp.0xed3_1', data!, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendRkeyPacket() {
|
async sendRkeyPacket() {
|
||||||
const packet = this.packetPacker.packRkeyPacket();
|
const packet = this.packetSession?.packer.packRkeyPacket();
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x9067_202', packet, true);
|
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x9067_202', packet!, true);
|
||||||
if (!ret?.hex_data) return [];
|
if (!ret?.hex_data) return [];
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
||||||
const retData = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202_Rsp_Body).decode(body);
|
const retData = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202_Rsp_Body).decode(body);
|
||||||
@ -86,8 +85,8 @@ export class NTQQPacketApi {
|
|||||||
async sendStatusPacket(uin: number): Promise<{ status: number; ext_status: number; } | undefined> {
|
async sendStatusPacket(uin: number): Promise<{ status: number; ext_status: number; } | undefined> {
|
||||||
let status = 0;
|
let status = 0;
|
||||||
try {
|
try {
|
||||||
const packet = this.packetPacker.packStatusPacket(uin);
|
const packet = this.packetSession?.packer.packStatusPacket(uin);
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0xfe1_2', packet, true);
|
const ret = await this.sendPacket('OidbSvcTrpcTcp.0xfe1_2', packet!, true);
|
||||||
const data = Buffer.from(ret.hex_data, 'hex');
|
const data = Buffer.from(ret.hex_data, 'hex');
|
||||||
const ext = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2RSP).decode(new NapProtoMsg(OidbSvcTrpcTcpBase).decode(data).body).data.status.value;
|
const ext = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2RSP).decode(new NapProtoMsg(OidbSvcTrpcTcpBase).decode(data).body).data.status.value;
|
||||||
// ext & 0xff00 + ext >> 16 & 0xff
|
// ext & 0xff00 + ext >> 16 & 0xff
|
||||||
@ -103,20 +102,37 @@ export class NTQQPacketApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string) {
|
async sendSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string) {
|
||||||
const data = this.packetPacker.packSetSpecialTittlePacket(groupCode, uid, tittle);
|
const data = this.packetSession?.packer.packSetSpecialTittlePacket(groupCode, uid, tittle);
|
||||||
await this.sendPacket('OidbSvcTrpcTcp.0x8fc_2', data, true);
|
await this.sendPacket('OidbSvcTrpcTcp.0x8fc_2', data!, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async uploadResources(msg: PacketMsg[], groupUin: number = 0){
|
||||||
|
const reqList = []
|
||||||
|
for (const m of msg){
|
||||||
|
for (const e of m.msg){
|
||||||
|
if (e instanceof PacketMsgPicElement){
|
||||||
|
reqList.push(this.packetSession?.highwaySession.uploadImage({
|
||||||
|
chatType: groupUin ? ChatType.KCHATTYPEGROUP : ChatType.KCHATTYPEC2C,
|
||||||
|
peerUid: String(groupUin) ? String(groupUin) : this.core.selfInfo.uid
|
||||||
|
}, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(reqList);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendUploadForwardMsg(msg: PacketMsg[], groupUin: number = 0) {
|
async sendUploadForwardMsg(msg: PacketMsg[], groupUin: number = 0) {
|
||||||
const data = this.packetPacker.packUploadForwardMsg(this.core.selfInfo.uid, msg, groupUin);
|
await this.uploadResources(msg, groupUin);
|
||||||
const ret = await this.sendPacket('trpc.group.long_msg_interface.MsgService.SsoSendLongMsg', data, true);
|
const data = await this.packetSession?.packer.packUploadForwardMsg(this.core.selfInfo.uid, msg, groupUin);
|
||||||
|
const ret = await this.sendPacket('trpc.group.long_msg_interface.MsgService.SsoSendLongMsg', data!, true);
|
||||||
|
this.logger.logDebug('sendUploadForwardMsg', ret);
|
||||||
const resp = new NapProtoMsg(SendLongMsgResp).decode(Buffer.from(ret.hex_data, 'hex'));
|
const resp = new NapProtoMsg(SendLongMsgResp).decode(Buffer.from(ret.hex_data, 'hex'));
|
||||||
return resp.result.resId;
|
return resp.result.resId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendGroupFileDownloadReq(groupUin: number, fileUUID: string) {
|
async sendGroupFileDownloadReq(groupUin: number, fileUUID: string) {
|
||||||
const data = this.packetPacker.packGroupFileDownloadReq(groupUin, fileUUID);
|
const data = this.packetSession?.packer.packGroupFileDownloadReq(groupUin, fileUUID);
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x6d6_2', data, true);
|
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x6d6_2', data!, true);
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
||||||
const resp = new NapProtoMsg(OidbSvcTrpcTcp0x6D6Response).decode(body);
|
const resp = new NapProtoMsg(OidbSvcTrpcTcp0x6D6Response).decode(body);
|
||||||
if (resp.download.retCode !== 0){
|
if (resp.download.retCode !== 0){
|
||||||
|
@ -34,16 +34,16 @@ export class PacketHighwaySession {
|
|||||||
protected packer: PacketPacker;
|
protected packer: PacketPacker;
|
||||||
private cachedPrepareReq: Promise<void> | null = null;
|
private cachedPrepareReq: Promise<void> | null = null;
|
||||||
|
|
||||||
constructor(logger: LogWrapper, client: PacketClient) {
|
constructor(logger: LogWrapper, client: PacketClient, packer: PacketPacker) {
|
||||||
this.packetClient = client;
|
this.packetClient = client;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.packer = new PacketPacker(logger);
|
|
||||||
this.sig = {
|
this.sig = {
|
||||||
uin: this.packetClient.napCatCore.selfInfo.uin,
|
uin: this.packetClient.napCatCore.selfInfo.uin,
|
||||||
sigSession: null,
|
sigSession: null,
|
||||||
sessionKey: null,
|
sessionKey: null,
|
||||||
serverAddr: [],
|
serverAddr: [],
|
||||||
}
|
}
|
||||||
|
this.packer = packer;
|
||||||
this.packetHighwayClient = new PacketHighwayClient(this.sig, this.logger);
|
this.packetHighwayClient = new PacketHighwayClient(this.sig, this.logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
131
src/core/packet/msg/converter.ts
Normal file
131
src/core/packet/msg/converter.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import {
|
||||||
|
MessageElement,
|
||||||
|
RawMessage,
|
||||||
|
SendArkElement,
|
||||||
|
SendFaceElement,
|
||||||
|
SendFileElement,
|
||||||
|
SendMarkdownElement,
|
||||||
|
SendMarketFaceElement,
|
||||||
|
SendPicElement,
|
||||||
|
SendPttElement,
|
||||||
|
SendReplyElement,
|
||||||
|
SendStructLongMsgElement,
|
||||||
|
SendTextElement,
|
||||||
|
SendVideoElement
|
||||||
|
} from "@/core";
|
||||||
|
import {
|
||||||
|
IPacketMsgElement,
|
||||||
|
PacketMsgAtElement,
|
||||||
|
PacketMsgFaceElement,
|
||||||
|
PacketMsgFileElement,
|
||||||
|
PacketMsgLightAppElement,
|
||||||
|
PacketMsgMarkDownElement,
|
||||||
|
PacketMsgMarkFaceElement,
|
||||||
|
PacketMsgPicElement,
|
||||||
|
PacketMsgPttElement,
|
||||||
|
PacketMsgReplyElement,
|
||||||
|
PacketMsgTextElement,
|
||||||
|
PacketMsgVideoElement,
|
||||||
|
PacketMultiMsgElement
|
||||||
|
} from "@/core/packet/msg/element";
|
||||||
|
import {PacketMsg, PacketSendMsgElement} from "@/core/packet/msg/message";
|
||||||
|
import {LogWrapper} from "@/common/log";
|
||||||
|
|
||||||
|
type SendMessageElementMap = {
|
||||||
|
textElement: SendTextElement,
|
||||||
|
picElement: SendPicElement,
|
||||||
|
replyElement: SendReplyElement,
|
||||||
|
faceElement: SendFaceElement,
|
||||||
|
marketFaceElement: SendMarketFaceElement,
|
||||||
|
videoElement: SendVideoElement,
|
||||||
|
fileElement: SendFileElement,
|
||||||
|
pttElement: SendPttElement,
|
||||||
|
arkElement: SendArkElement,
|
||||||
|
markdownElement: SendMarkdownElement,
|
||||||
|
structLongMsgElement: SendStructLongMsgElement
|
||||||
|
};
|
||||||
|
|
||||||
|
type RawToPacketMsgConverters = {
|
||||||
|
[K in keyof SendMessageElementMap]: (
|
||||||
|
element: SendMessageElementMap[K],
|
||||||
|
msg?: RawMessage,
|
||||||
|
elementWrapper?: MessageElement,
|
||||||
|
) => IPacketMsgElement<SendMessageElementMap[K]> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type rawMsgWithSendMsg = {
|
||||||
|
senderUin: number;
|
||||||
|
senderUid?: string;
|
||||||
|
senderName: string;
|
||||||
|
groupId?: number;
|
||||||
|
time: number;
|
||||||
|
msg: PacketSendMsgElement[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PacketMsgConverter {
|
||||||
|
private logger: LogWrapper;
|
||||||
|
|
||||||
|
constructor(logger: LogWrapper) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
rawMsgWithSendMsgToPacketMsg(msg: rawMsgWithSendMsg): PacketMsg {
|
||||||
|
return {
|
||||||
|
senderUid: msg.senderUid ?? '',
|
||||||
|
senderUin: msg.senderUin,
|
||||||
|
senderName: msg.senderName,
|
||||||
|
groupId: msg.groupId,
|
||||||
|
time: msg.time,
|
||||||
|
msg: msg.msg.map((element) => {
|
||||||
|
const key = (Object.keys(this.rawToPacketMsgConverters) as Array<keyof SendMessageElementMap>).find(
|
||||||
|
(k) => (element as any)[k] !== undefined // TODO:
|
||||||
|
);
|
||||||
|
if (key) {
|
||||||
|
const elementData = (element as any)[key]; // TODO:
|
||||||
|
if (elementData) return this.rawToPacketMsgConverters[key](element as any)
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}).filter((e) => e !== null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private rawToPacketMsgConverters: RawToPacketMsgConverters = {
|
||||||
|
textElement: (element: SendTextElement) => {
|
||||||
|
if (element.textElement.atType) {
|
||||||
|
return new PacketMsgAtElement(element)
|
||||||
|
}
|
||||||
|
return new PacketMsgTextElement(element)
|
||||||
|
},
|
||||||
|
picElement: (element: SendPicElement) => {
|
||||||
|
return new PacketMsgPicElement(element)
|
||||||
|
},
|
||||||
|
replyElement: (element: SendReplyElement) => {
|
||||||
|
return new PacketMsgReplyElement(element)
|
||||||
|
},
|
||||||
|
faceElement: (element: SendFaceElement) => {
|
||||||
|
return new PacketMsgFaceElement(element)
|
||||||
|
},
|
||||||
|
marketFaceElement: (element: SendMarketFaceElement) => {
|
||||||
|
return new PacketMsgMarkFaceElement(element)
|
||||||
|
},
|
||||||
|
videoElement: (element: SendVideoElement) => {
|
||||||
|
return new PacketMsgVideoElement(element)
|
||||||
|
},
|
||||||
|
fileElement: (element: SendFileElement) => {
|
||||||
|
return new PacketMsgFileElement(element)
|
||||||
|
},
|
||||||
|
pttElement: (element: SendPttElement) => {
|
||||||
|
return new PacketMsgPttElement(element)
|
||||||
|
},
|
||||||
|
arkElement: (element: SendArkElement) => {
|
||||||
|
return new PacketMsgLightAppElement(element)
|
||||||
|
},
|
||||||
|
markdownElement: (element: SendMarkdownElement) => {
|
||||||
|
return new PacketMsgMarkDownElement(element)
|
||||||
|
},
|
||||||
|
// TODO: check this logic, move it in arkElement?
|
||||||
|
structLongMsgElement: (element: SendStructLongMsgElement) => {
|
||||||
|
return new PacketMultiMsgElement(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -248,7 +248,7 @@ export class PacketMsgFaceElement extends IPacketMsgElement<SendFaceElement> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PacketMarkFaceElement extends IPacketMsgElement<SendMarketFaceElement> {
|
export class PacketMsgMarkFaceElement extends IPacketMsgElement<SendMarketFaceElement> {
|
||||||
emojiName: string;
|
emojiName: string;
|
||||||
emojiId: string;
|
emojiId: string;
|
||||||
emojiPackageId: number;
|
emojiPackageId: number;
|
||||||
@ -357,16 +357,15 @@ export class PacketMultiMsgElement extends IPacketMsgElement<SendStructLongMsgEl
|
|||||||
resid: string;
|
resid: string;
|
||||||
message: PacketMsg[];
|
message: PacketMsg[];
|
||||||
|
|
||||||
constructor(rawElement: SendStructLongMsgElement)
|
|
||||||
constructor(rawElement: SendStructLongMsgElement, message?: PacketMsg[]) {
|
constructor(rawElement: SendStructLongMsgElement, message?: PacketMsg[]) {
|
||||||
super(rawElement);
|
super(rawElement);
|
||||||
this.resid = rawElement.structLongMsgElement.resId;
|
this.resid = rawElement.structLongMsgElement.resId;
|
||||||
this.message = message ?? [];
|
this.message = message ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
get JSON() {
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
const elementJson = {
|
return {
|
||||||
app: "com.tencent.multimsg",
|
app: "com.tencent.multimsg",
|
||||||
config: {
|
config: {
|
||||||
autosize: 1,
|
autosize: 1,
|
||||||
@ -388,20 +387,23 @@ export class PacketMultiMsgElement extends IPacketMsgElement<SendStructLongMsgEl
|
|||||||
text: `${packetMsg.senderName}: ${packetMsg.msg.map(msg => msg.toPreview()).join('')}`,
|
text: `${packetMsg.senderName}: ${packetMsg.msg.map(msg => msg.toPreview()).join('')}`,
|
||||||
})),
|
})),
|
||||||
resid: this.resid,
|
resid: this.resid,
|
||||||
source: "聊天记录",
|
source: "聊天记录", // TODO:
|
||||||
summary: `查看${this.message.length}条转发消息`,
|
summary: `查看${this.message.length}条转发消息`,
|
||||||
uniseq: id,
|
uniseq: id,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prompt: "[聊天记录]",
|
prompt: "[聊天记录]",
|
||||||
ver: "0.0.0.5",
|
ver: "0.0.0.5",
|
||||||
view: "contact"
|
view: "contact",
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
return [{
|
return [{
|
||||||
lightAppElem: {
|
lightAppElem: {
|
||||||
data: Buffer.concat([
|
data: Buffer.concat([
|
||||||
Buffer.from([0x01]),
|
Buffer.from([0x01]),
|
||||||
zlib.deflateSync(Buffer.from(JSON.stringify(elementJson), 'utf-8'))
|
zlib.deflateSync(Buffer.from(JSON.stringify(this.JSON), 'utf-8'))
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
@ -16,16 +16,22 @@ import {LogWrapper} from "@/common/log";
|
|||||||
import {PacketMsg} from "@/core/packet/msg/message";
|
import {PacketMsg} from "@/core/packet/msg/message";
|
||||||
import {OidbSvcTrpcTcp0x6D6} from "@/core/packet/proto/oidb/Oidb.0x6D6";
|
import {OidbSvcTrpcTcp0x6D6} from "@/core/packet/proto/oidb/Oidb.0x6D6";
|
||||||
import {OidbSvcTrpcTcp0XE37_1200} from "@/core/packet/proto/oidb/Oidb.0xE37_1200";
|
import {OidbSvcTrpcTcp0XE37_1200} from "@/core/packet/proto/oidb/Oidb.0xE37_1200";
|
||||||
|
import {PacketMsgConverter} from "@/core/packet/msg/converter";
|
||||||
|
import {PacketClient} from "@/core/packet/client";
|
||||||
|
|
||||||
export type PacketHexStr = string & { readonly hexNya: unique symbol };
|
export type PacketHexStr = string & { readonly hexNya: unique symbol };
|
||||||
|
|
||||||
export class PacketPacker {
|
export class PacketPacker {
|
||||||
private readonly logger: LogWrapper;
|
readonly logger: LogWrapper;
|
||||||
private readonly packetBuilder: PacketMsgBuilder;
|
readonly client: PacketClient;
|
||||||
|
readonly packetBuilder: PacketMsgBuilder;
|
||||||
|
readonly packetConverter: PacketMsgConverter;
|
||||||
|
|
||||||
constructor(logger: LogWrapper) {
|
constructor(logger: LogWrapper, client: PacketClient) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
this.client = client;
|
||||||
this.packetBuilder = new PacketMsgBuilder(logger);
|
this.packetBuilder = new PacketMsgBuilder(logger);
|
||||||
|
this.packetConverter = new PacketMsgConverter(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
private toHexStr(byteArray: Uint8Array): PacketHexStr {
|
private toHexStr(byteArray: Uint8Array): PacketHexStr {
|
||||||
@ -96,8 +102,7 @@ export class PacketPacker {
|
|||||||
return this.toHexStr(this.packOidbPacket(0xfe1, 2, oidb_0xfe1_2));
|
return this.toHexStr(this.packOidbPacket(0xfe1, 2, oidb_0xfe1_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
packUploadForwardMsg(selfUid: string, msg: PacketMsg[], groupUin: number = 0): PacketHexStr {
|
async packUploadForwardMsg(selfUid: string, msg: PacketMsg[], groupUin: number = 0): Promise<PacketHexStr> {
|
||||||
// this.logger.logDebug("packUploadForwardMsg START!!!", selfUid, msg, groupUin);
|
|
||||||
const msgBody = this.packetBuilder.buildFakeMsg(selfUid, msg);
|
const msgBody = this.packetBuilder.buildFakeMsg(selfUid, msg);
|
||||||
const longMsgResultData = new NapProtoMsg(LongMsgResult).encode(
|
const longMsgResultData = new NapProtoMsg(LongMsgResult).encode(
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { PacketClient } from "@/core/packet/client";
|
import { PacketClient } from "@/core/packet/client";
|
||||||
import { PacketHighwaySession } from "@/core/packet/highway/session";
|
import { PacketHighwaySession } from "@/core/packet/highway/session";
|
||||||
import { LogWrapper } from "@/common/log";
|
import { LogWrapper } from "@/common/log";
|
||||||
|
import {PacketPacker} from "@/core/packet/packer";
|
||||||
|
|
||||||
export class PacketSession {
|
export class PacketSession {
|
||||||
readonly logger: LogWrapper;
|
readonly logger: LogWrapper;
|
||||||
readonly client: PacketClient;
|
readonly client: PacketClient;
|
||||||
|
readonly packer: PacketPacker;
|
||||||
readonly highwaySession: PacketHighwaySession;
|
readonly highwaySession: PacketHighwaySession;
|
||||||
|
|
||||||
constructor(logger: LogWrapper, client: PacketClient) {
|
constructor(logger: LogWrapper, client: PacketClient) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.highwaySession = new PacketHighwaySession(this.logger, this.client);
|
this.packer = new PacketPacker(this.logger, this.client);
|
||||||
|
this.highwaySession = new PacketHighwaySession(this.logger, this.client, this.packer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
import BaseAction from '../BaseAction';
|
|
||||||
import {ActionName} from '../types';
|
|
||||||
import {FromSchema, JSONSchema} from 'json-schema-to-ts';
|
|
||||||
import {ChatType, SendTextElement} from "@/core";
|
|
||||||
import {PacketMsgPicElement, PacketMsgTextElement} from "@/core/packet/msg/element";
|
|
||||||
|
|
||||||
const SchemaData = {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
group_id: {type: ['number', 'string']},
|
|
||||||
pic: {type: 'string'},
|
|
||||||
},
|
|
||||||
required: ['group_id', 'pic'],
|
|
||||||
} as const satisfies JSONSchema;
|
|
||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
|
||||||
|
|
||||||
export class UploadForwardMsg extends BaseAction<Payload, any> {
|
|
||||||
actionName = ActionName.UploadForwardMsg;
|
|
||||||
payloadSchema = SchemaData;
|
|
||||||
|
|
||||||
async _handle(payload: Payload) {
|
|
||||||
if (!this.core.apis.PacketApi.available) {
|
|
||||||
throw new Error('PacketClient is not init');
|
|
||||||
}
|
|
||||||
// throw new Error('Not implemented');
|
|
||||||
const peer = {
|
|
||||||
chatType: ChatType.KCHATTYPEGROUP,
|
|
||||||
peerUid: "10001", // TODO: must be a valid group id
|
|
||||||
}
|
|
||||||
const img = await this.core.apis.FileApi.createValidSendPicElement(
|
|
||||||
{
|
|
||||||
deleteAfterSentFiles: [],
|
|
||||||
peer: peer
|
|
||||||
},
|
|
||||||
"", // TODO:
|
|
||||||
"www",
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
const sendImg = new PacketMsgPicElement(img);
|
|
||||||
console.log(JSON.stringify(img));
|
|
||||||
await this.core.apis.PacketApi.packetSession?.highwaySession.uploadImage(
|
|
||||||
peer, sendImg
|
|
||||||
)
|
|
||||||
return await this.core.apis.PacketApi.sendUploadForwardMsg([
|
|
||||||
{
|
|
||||||
groupId: 10001,
|
|
||||||
senderId: 10001,
|
|
||||||
senderName: "qwq",
|
|
||||||
time: Math.floor(Date.now() / 1000),
|
|
||||||
msg: [new PacketMsgTextElement({
|
|
||||||
textElement: {
|
|
||||||
content: "Love from Napcat.Packet~"
|
|
||||||
}
|
|
||||||
} as SendTextElement)]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
groupId: 10001,
|
|
||||||
senderId: 10001,
|
|
||||||
senderName: "qwq",
|
|
||||||
time: Math.floor(Date.now() / 1000),
|
|
||||||
msg: [new PacketMsgTextElement({
|
|
||||||
textElement: {
|
|
||||||
content: "Nya~"
|
|
||||||
}
|
|
||||||
} as SendTextElement), sendImg]
|
|
||||||
}], 10001); // TODO: must be a valid group id
|
|
||||||
}
|
|
||||||
}
|
|
@ -87,7 +87,6 @@ import { GroupPoke } from './group/GroupPoke';
|
|||||||
import { GetUserStatus } from './extends/GetUserStatus';
|
import { GetUserStatus } from './extends/GetUserStatus';
|
||||||
import { GetRkey } from './extends/GetRkey';
|
import { GetRkey } from './extends/GetRkey';
|
||||||
import { SetSpecialTittle } from './extends/SetSpecialTittle';
|
import { SetSpecialTittle } from './extends/SetSpecialTittle';
|
||||||
import { UploadForwardMsg } from "@/onebot/action/extends/UploadForwardMsg";
|
|
||||||
import { GetGroupShutList } from './group/GetGroupShutList';
|
import { GetGroupShutList } from './group/GetGroupShutList';
|
||||||
import { GetGroupMemberList } from './group/GetGroupMemberList';
|
import { GetGroupMemberList } from './group/GetGroupMemberList';
|
||||||
import { GetGroupFileUrl } from "@/onebot/action/file/GetGroupFileUrl";
|
import { GetGroupFileUrl } from "@/onebot/action/file/GetGroupFileUrl";
|
||||||
@ -193,7 +192,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
|
|||||||
new GetUserStatus(obContext, core),
|
new GetUserStatus(obContext, core),
|
||||||
new GetRkey(obContext, core),
|
new GetRkey(obContext, core),
|
||||||
new SetSpecialTittle(obContext, core),
|
new SetSpecialTittle(obContext, core),
|
||||||
new UploadForwardMsg(obContext, core),
|
// new UploadForwardMsg(obContext, core),
|
||||||
new GetGroupShutList(obContext, core),
|
new GetGroupShutList(obContext, core),
|
||||||
new GetGroupFileUrl(obContext, core),
|
new GetGroupFileUrl(obContext, core),
|
||||||
];
|
];
|
||||||
|
@ -6,14 +6,18 @@ import {
|
|||||||
OB11PostContext,
|
OB11PostContext,
|
||||||
OB11PostSendMsg,
|
OB11PostSendMsg,
|
||||||
} from '@/onebot/types';
|
} from '@/onebot/types';
|
||||||
import { ActionName, BaseCheckResult } from '@/onebot/action/types';
|
import {ActionName, BaseCheckResult} from '@/onebot/action/types';
|
||||||
import { decodeCQCode } from '@/onebot/cqcode';
|
import {decodeCQCode} from '@/onebot/cqcode';
|
||||||
import { MessageUnique } from '@/common/message-unique';
|
import {MessageUnique} from '@/common/message-unique';
|
||||||
import { ChatType, ElementType, NapCatCore, Peer, RawMessage, SendMessageElement } from '@/core';
|
import {ChatType, ElementType, NapCatCore, Peer, RawMessage, SendArkElement, SendMessageElement} from '@/core';
|
||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
|
import {rawMsgWithSendMsg} from "@/core/packet/msg/converter";
|
||||||
|
import {PacketMsg} from "@/core/packet/msg/message";
|
||||||
|
import {PacketMultiMsgElement} from "@/core/packet/msg/element";
|
||||||
|
|
||||||
export interface ReturnDataType {
|
export interface ReturnDataType {
|
||||||
message_id: number;
|
message_id: number;
|
||||||
|
res_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ContextMode {
|
export enum ContextMode {
|
||||||
@ -26,7 +30,7 @@ export enum ContextMode {
|
|||||||
export function normalize(message: OB11MessageMixType, autoEscape = false): OB11MessageData[] {
|
export function normalize(message: OB11MessageMixType, autoEscape = false): OB11MessageData[] {
|
||||||
return typeof message === 'string' ? (
|
return typeof message === 'string' ? (
|
||||||
autoEscape ?
|
autoEscape ?
|
||||||
[{ type: OB11MessageDataType.text, data: { text: message } }] :
|
[{type: OB11MessageDataType.text, data: {text: message}}] :
|
||||||
decodeCQCode(message)
|
decodeCQCode(message)
|
||||||
) : Array.isArray(message) ? message : [message];
|
) : Array.isArray(message) ? message : [message];
|
||||||
}
|
}
|
||||||
@ -96,10 +100,10 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素',
|
message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { valid: true };
|
return {valid: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handle(payload: OB11PostSendMsg): Promise<{ message_id: number }> {
|
async _handle(payload: OB11PostSendMsg): Promise<ReturnDataType> {
|
||||||
this.contextMode = ContextMode.Normal;
|
this.contextMode = ContextMode.Normal;
|
||||||
if (payload.message_type === 'group') this.contextMode = ContextMode.Group;
|
if (payload.message_type === 'group') this.contextMode = ContextMode.Group;
|
||||||
if (payload.message_type === 'private') this.contextMode = ContextMode.Private;
|
if (payload.message_type === 'private') this.contextMode = ContextMode.Private;
|
||||||
@ -111,17 +115,19 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (getSpecialMsgNum(payload, OB11MessageDataType.node)) {
|
if (getSpecialMsgNum(payload, OB11MessageDataType.node)) {
|
||||||
const returnMsg = await this.handleForwardedNodes(peer, messages as OB11MessageNode[]);
|
const packetMode = this.core.apis.PacketApi.available
|
||||||
if (returnMsg) {
|
const returnMsgAndResId = packetMode
|
||||||
|
? await this.handleForwardedNodesPacket(peer, messages as OB11MessageNode[])
|
||||||
|
: await this.handleForwardedNodes(peer, messages as OB11MessageNode[]);
|
||||||
|
if (returnMsgAndResId.message) {
|
||||||
const msgShortId = MessageUnique.createUniqueMsgId({
|
const msgShortId = MessageUnique.createUniqueMsgId({
|
||||||
guildId: '',
|
guildId: '',
|
||||||
peerUid: peer.peerUid,
|
peerUid: peer.peerUid,
|
||||||
chatType: peer.chatType,
|
chatType: peer.chatType,
|
||||||
}, returnMsg!.msgId);
|
}, (returnMsgAndResId.message)!.msgId);
|
||||||
return { message_id: msgShortId! };
|
return {message_id: msgShortId!, res_id: returnMsgAndResId.res_id};
|
||||||
} else {
|
|
||||||
throw Error('发送转发消息失败');
|
|
||||||
}
|
}
|
||||||
|
throw Error('发送转发消息失败');
|
||||||
} else {
|
} else {
|
||||||
// if (getSpecialMsgNum(payload, OB11MessageDataType.music)) {
|
// if (getSpecialMsgNum(payload, OB11MessageDataType.music)) {
|
||||||
// const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic;
|
// const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic;
|
||||||
@ -131,13 +137,61 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
// log("send msg:", peer, sendElements)
|
// log("send msg:", peer, sendElements)
|
||||||
|
|
||||||
const { sendElements, deleteAfterSentFiles } = await this.obContext.apis.MsgApi
|
const {sendElements, deleteAfterSentFiles} = await this.obContext.apis.MsgApi
|
||||||
.createSendElements(messages, peer);
|
.createSendElements(messages, peer);
|
||||||
const returnMsg = await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles);
|
const returnMsg = await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles);
|
||||||
return { message_id: returnMsg!.id! };
|
return {message_id: returnMsg!.id!};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleForwardedNodes(destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<RawMessage | null> {
|
private async handleForwardedNodesPacket(msgPeer: Peer, messageNodes: OB11MessageNode[]): Promise<{
|
||||||
|
message: RawMessage | null,
|
||||||
|
res_id?: string
|
||||||
|
}> {
|
||||||
|
const logger = this.core.context.logger;
|
||||||
|
const packetMsg: PacketMsg[] = [];
|
||||||
|
for (const node of messageNodes) {
|
||||||
|
if ((node.data.id && typeof node.data.content !== "string") || !node.data.id) {
|
||||||
|
const OB11Data = normalize(node.data.content);
|
||||||
|
const {sendElements} = await this.obContext.apis.MsgApi.createSendElements(OB11Data, msgPeer);
|
||||||
|
const packetMsgElements: rawMsgWithSendMsg = {
|
||||||
|
senderUin: node.data.user_id ?? +this.core.selfInfo.uin,
|
||||||
|
senderName: node.data.nickname,
|
||||||
|
groupId: msgPeer.chatType === ChatType.KCHATTYPEGROUP ? +msgPeer.peerUid : undefined,
|
||||||
|
time: Date.now(),
|
||||||
|
msg: sendElements,
|
||||||
|
}
|
||||||
|
logger.logDebug(`handleForwardedNodesPacket 开始转换 ${JSON.stringify(packetMsgElements)}`);
|
||||||
|
const transformedMsg = this.core.apis.PacketApi.packetSession?.packer.packetConverter.rawMsgWithSendMsgToPacketMsg(packetMsgElements);
|
||||||
|
logger.logDebug(`handleForwardedNodesPacket 转换为 ${JSON.stringify(transformedMsg)}`);
|
||||||
|
packetMsg.push(transformedMsg!);
|
||||||
|
} else {
|
||||||
|
logger.logDebug(`handleForwardedNodesPacket 跳过元素 ${JSON.stringify(node)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const resid = await this.core.apis.PacketApi.sendUploadForwardMsg(packetMsg, msgPeer.chatType === ChatType.KCHATTYPEGROUP ? +msgPeer.peerUid : 0);
|
||||||
|
const forwardJson = new PacketMultiMsgElement({
|
||||||
|
elementType: ElementType.STRUCTLONGMSG,
|
||||||
|
elementId: "",
|
||||||
|
structLongMsgElement: {
|
||||||
|
xmlContent: "",
|
||||||
|
resId: resid
|
||||||
|
}
|
||||||
|
}, packetMsg).JSON;
|
||||||
|
const finallySendElements = {
|
||||||
|
elementType: ElementType.ARK,
|
||||||
|
elementId: "",
|
||||||
|
arkElement: {
|
||||||
|
bytesData: JSON.stringify(forwardJson),
|
||||||
|
},
|
||||||
|
} as SendArkElement
|
||||||
|
const returnMsg = await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(msgPeer, [finallySendElements], [], true).catch(_ => undefined)
|
||||||
|
return {message: returnMsg ?? null, res_id: resid};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleForwardedNodes(destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<{
|
||||||
|
message: RawMessage | null,
|
||||||
|
res_id?: string
|
||||||
|
}> {
|
||||||
const selfPeer = {
|
const selfPeer = {
|
||||||
chatType: ChatType.KCHATTYPEC2C,
|
chatType: ChatType.KCHATTYPEC2C,
|
||||||
peerUid: this.core.selfInfo.uid,
|
peerUid: this.core.selfInfo.uid,
|
||||||
@ -147,7 +201,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
for (const messageNode of messageNodes) {
|
for (const messageNode of messageNodes) {
|
||||||
const nodeId = messageNode.data.id;
|
const nodeId = messageNode.data.id;
|
||||||
if (nodeId) {
|
if (nodeId) {
|
||||||
//对Mgsid和OB11ID混用情况兜底
|
// 对Msgid和OB11ID混用情况兜底
|
||||||
const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId);
|
const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId);
|
||||||
if (!nodeMsg) {
|
if (!nodeMsg) {
|
||||||
logger.logError.bind(this.core.context.logger)('转发消息失败,未找到消息', nodeId);
|
logger.logError.bind(this.core.context.logger)('转发消息失败,未找到消息', nodeId);
|
||||||
@ -167,13 +221,13 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
const nodeMsg = await this.handleForwardedNodes(selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node));
|
const nodeMsg = await this.handleForwardedNodes(selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node));
|
||||||
if (nodeMsg) {
|
if (nodeMsg) {
|
||||||
nodeMsgIds.push(nodeMsg.msgId);
|
nodeMsgIds.push(nodeMsg.message!.msgId);
|
||||||
MessageUnique.createUniqueMsgId(selfPeer, nodeMsg.msgId);
|
MessageUnique.createUniqueMsgId(selfPeer, nodeMsg.message!.msgId);
|
||||||
}
|
}
|
||||||
//完成子卡片生成跳过后续
|
//完成子卡片生成跳过后续
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const { sendElements } = await this.obContext.apis.MsgApi
|
const {sendElements} = await this.obContext.apis.MsgApi
|
||||||
.createSendElements(OB11Data, destPeer);
|
.createSendElements(OB11Data, destPeer);
|
||||||
|
|
||||||
//拆分消息
|
//拆分消息
|
||||||
@ -214,7 +268,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const nodeMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
|
const nodeMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
|
||||||
srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid };
|
srcPeer = srcPeer ?? {chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid};
|
||||||
if (srcPeer.peerUid !== nodeMsg.peerUid) {
|
if (srcPeer.peerUid !== nodeMsg.peerUid) {
|
||||||
needSendSelf = true;
|
needSendSelf = true;
|
||||||
}
|
}
|
||||||
@ -237,10 +291,14 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
|
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
|
||||||
try {
|
try {
|
||||||
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
|
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
|
||||||
return await this.core.apis.MsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds);
|
return {
|
||||||
|
message: await this.core.apis.MsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds)
|
||||||
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.logError.bind(this.core.context.logger)('forward failed', e);
|
logger.logError.bind(this.core.context.logger)('forward failed', e);
|
||||||
return null;
|
return {
|
||||||
|
message: null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,6 @@ export enum ActionName {
|
|||||||
GetUserStatus = "nc_get_user_status",
|
GetUserStatus = "nc_get_user_status",
|
||||||
GetRkey = "nc_get_rkey",
|
GetRkey = "nc_get_rkey",
|
||||||
SetSpecialTittle = "set_group_special_title",
|
SetSpecialTittle = "set_group_special_title",
|
||||||
UploadForwardMsg = "upload_forward_msg",
|
// UploadForwardMsg = "upload_forward_msg",
|
||||||
GetGroupShutList = "get_goup_shut_list",
|
GetGroupShutList = "get_goup_shut_list",
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,15 @@ import {
|
|||||||
OB11MessageFileBase,
|
OB11MessageFileBase,
|
||||||
OB11MessageForward,
|
OB11MessageForward,
|
||||||
} from '@/onebot';
|
} from '@/onebot';
|
||||||
import { OB11Entities } from '@/onebot/entities';
|
import {OB11Entities} from '@/onebot/entities';
|
||||||
import { EventType } from '@/onebot/event/OB11BaseEvent';
|
import {EventType} from '@/onebot/event/OB11BaseEvent';
|
||||||
import { encodeCQCode } from '@/onebot/cqcode';
|
import {encodeCQCode} from '@/onebot/cqcode';
|
||||||
import { uri2local } from '@/common/file';
|
import {uri2local} from '@/common/file';
|
||||||
import { RequestUtil } from '@/common/request';
|
import {RequestUtil} from '@/common/request';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import fsPromise from 'node:fs/promises';
|
import fsPromise from 'node:fs/promises';
|
||||||
import { OB11FriendAddNoticeEvent } from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
|
import {OB11FriendAddNoticeEvent} from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
|
||||||
import { decodeSysMessage } from '@/core/packet/proto/old/ProfileLike';
|
import {decodeSysMessage} from '@/core/packet/proto/old/ProfileLike';
|
||||||
|
|
||||||
type RawToOb11Converters = {
|
type RawToOb11Converters = {
|
||||||
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
|
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
|
||||||
@ -497,8 +497,7 @@ export class OneBotMsgApi {
|
|||||||
const uri2LocalRes = await uri2local(this.core.NapCatTempPath, thumb);
|
const uri2LocalRes = await uri2local(this.core.NapCatTempPath, thumb);
|
||||||
if (uri2LocalRes.success) thumb = uri2LocalRes.path;
|
if (uri2LocalRes.success) thumb = uri2LocalRes.path;
|
||||||
}
|
}
|
||||||
const videoEle = await this.core.apis.FileApi.createValidSendVideoElement(context, path, fileName, thumb);
|
return await this.core.apis.FileApi.createValidSendVideoElement(context, path, fileName, thumb);
|
||||||
return videoEle;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[OB11MessageDataType.voice]: async (sendMsg, context) =>
|
[OB11MessageDataType.voice]: async (sendMsg, context) =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user