feat & refactor: add more packetElement & refactor packetMsg

This commit is contained in:
pk5ls20 2024-10-18 16:01:54 +08:00
parent 524fd258d8
commit 698e095364
No known key found for this signature in database
GPG Key ID: 6370ED7A169F493A
10 changed files with 119 additions and 38 deletions

View File

@ -23,7 +23,9 @@ export class LimitedHashTable<K, V> {
}
while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
const oldestKey = this.keyToValue.keys().next().value;
// @ts-ignore
this.valueToKey.delete(this.keyToValue.get(oldestKey)!);
// @ts-ignore
this.keyToValue.delete(oldestKey);
}
}

View File

@ -8,9 +8,9 @@ import { NapProtoMsg } from '@/core/packet/proto/NapProto';
import { OidbSvcTrpcTcp0X9067_202_Rsp_Body } from '@/core/packet/proto/oidb/Oidb.0x9067_202';
import { OidbSvcTrpcTcpBase, OidbSvcTrpcTcpBaseRsp } from '@/core/packet/proto/oidb/OidbBase';
import { OidbSvcTrpcTcp0XFE1_2RSP } from '@/core/packet/proto/oidb/Oidb.fe1_2';
import { PacketForwardNode } from "@/core/packet/msg/entity/forward";
import {LogWrapper} from "@/common/log";
import {SendLongMsgResp} from "@/core/packet/proto/message/action";
import {PacketMsg} from "@/core/packet/msg/message";
interface OffsetType {
[key: string]: {
@ -106,7 +106,7 @@ export class NTQQPacketApi {
await this.sendPacket('OidbSvcTrpcTcp.0x8fc_2', data, true);
}
async sendUploadForwardMsg(msg: PacketForwardNode[], groupUin: number = 0) {
async sendUploadForwardMsg(msg: PacketMsg[], groupUin: number = 0) {
const data = this.packetPacker.packUploadForwardMsg(this.core.selfInfo.uid, msg, groupUin);
const ret = await this.sendPacket('trpc.group.long_msg_interface.MsgService.SsoSendLongMsg', data, true);
const resp = new NapProtoMsg(SendLongMsgResp).decode(Buffer.from(ret.hex_data, 'hex'));

View File

@ -1,4 +1,4 @@
import assert from "node:assert";
import * as assert from "node:assert";
export class Frame{
static pack(head: Buffer, body: Buffer): Buffer {

View File

@ -1,8 +1,8 @@
import * as crypto from "crypto";
import {PushMsgBody} from "@/core/packet/proto/message/message";
import {NapProtoEncodeStructType} from "@/core/packet/proto/NapProto";
import {PacketForwardNode} from "@/core/packet/msg/entity/forward";
import {LogWrapper} from "@/common/log";
import {PacketMsg} from "@/core/packet/msg/message";
export class PacketMsgBuilder {
private logger: LogWrapper;
@ -11,14 +11,14 @@ export class PacketMsgBuilder {
this.logger = logger;
}
buildFakeMsg(selfUid: string, element: PacketForwardNode[]): NapProtoEncodeStructType<typeof PushMsgBody>[] {
buildFakeMsg(selfUid: string, element: PacketMsg[]): NapProtoEncodeStructType<typeof PushMsgBody>[] {
return element.map((node): NapProtoEncodeStructType<typeof PushMsgBody> => {
const avatar = `https://q.qlogo.cn/headimg_dl?dst_uin=${node.senderId}&spec=640&img_type=jpg`;
const avatar = `https://q.qlogo.cn/headimg_dl?dst_uin=${node.senderUin}&spec=640&img_type=jpg`;
const msgElement = node.msg.flatMap(msg => msg.buildElement() ?? []);
return {
responseHead: {
fromUid: "",
fromUin: node.senderId,
fromUin: node.senderUin,
toUid: node.groupId ? undefined : selfUid,
forward: node.groupId ? undefined : {
friendName: node.senderName,

View File

@ -1,5 +1,6 @@
import assert from "node:assert";
import * as assert from "node:assert";
import * as zlib from "node:zlib";
import * as crypto from "node:crypto";
import {NapProtoEncodeStructType, NapProtoMsg} from "@/core/packet/proto/NapProto";
import {
CustomFace,
@ -26,6 +27,7 @@ import {
SendVideoElement
} from "@/core";
import {MsgInfo} from "@/core/packet/proto/oidb/common/Ntv2.RichMediaReq";
import {PacketMsg} from "@/core/packet/msg/message";
// raw <-> packet
// TODO: check ob11 -> raw impl!
@ -42,6 +44,10 @@ export abstract class IPacketMsgElement<T extends SendMessageElement | SendStruc
buildElement(): NapProtoEncodeStructType<typeof Elem>[] | undefined {
return undefined;
}
toPreview(): string {
return '[nya~]';
}
}
export class PacketMsgTextElement extends IPacketMsgElement<SendTextElement> {
@ -59,6 +65,10 @@ export class PacketMsgTextElement extends IPacketMsgElement<SendTextElement> {
}
}];
}
toPreview(): string {
return this.text;
}
}
export class PacketMsgAtElement extends PacketMsgTextElement {
@ -85,6 +95,10 @@ export class PacketMsgAtElement extends PacketMsgTextElement {
}
}];
}
toPreview(): string {
return `@${this.targetUid} ${this.text}`;
}
}
export class PacketMsgPicElement extends IPacketMsgElement<SendPicElement> {
@ -121,6 +135,10 @@ export class PacketMsgPicElement extends IPacketMsgElement<SendPicElement> {
}
}]
}
toPreview(): string {
return "[图片]";
}
}
export class PacketMsgReplyElement extends IPacketMsgElement<SendReplyElement> {
@ -169,6 +187,10 @@ export class PacketMsgReplyElement extends IPacketMsgElement<SendReplyElement> {
} : undefined,
}]
}
toPreview(): string {
return "[回复]";
}
}
export class PacketMsgFaceElement extends IPacketMsgElement<SendFaceElement> {
@ -218,6 +240,10 @@ export class PacketMsgFaceElement extends IPacketMsgElement<SendFaceElement> {
}]
}
}
toPreview(): string {
return "[表情]";
}
}
export class PacketMsgVideoElement extends IPacketMsgElement<SendVideoElement> {
@ -256,6 +282,10 @@ export class PacketMsgLightAppElement extends IPacketMsgElement<SendArkElement>
}
}]
}
toPreview(): string {
return "[小程序]";
}
}
export class PacketMsgMarkDownElement extends IPacketMsgElement<SendMarkdownElement> {
@ -277,23 +307,67 @@ export class PacketMsgMarkDownElement extends IPacketMsgElement<SendMarkdownElem
}
}]
}
toPreview(): string {
return this.content;
}
}
// TODO:
// export class PacketMsgLongMsgElement extends IPacketMsgElement<SendStructLongMsgElement> {
// resid: string;
//
// constructor(element: SendStructLongMsgElement) {
// super(element);
// this.resid = element.structLongMsgElement.resId;
// }
//
// buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
// return [{
// generalFlags: {
// longTextResId: this.resid,
// longTextFlag: 1
// }
// }]
// }
// }
export class PacketMultiMsgElement extends IPacketMsgElement<SendStructLongMsgElement> {
resid: string;
message: PacketMsg[];
constructor(rawElement: SendStructLongMsgElement)
constructor(rawElement: SendStructLongMsgElement, message?: PacketMsg[]) {
super(rawElement);
this.resid = rawElement.structLongMsgElement.resId;
this.message = message ?? [];
}
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
const id = crypto.randomUUID();
const elementJson = {
app: "com.tencent.multimsg",
config: {
autosize: 1,
forward: 1,
round: 1,
type: "normal",
width: 300
},
desc: "[聊天记录]",
extra: {
filename: id,
tsum: this.message.length,
},
meta: {
detail: {
news: this.message.length === 0 ? [{
text: "[Nya~ This message is send from NapCat.Packet!]",
}] : this.message.map(packetMsg => ({
text: `${packetMsg.senderName}: ${packetMsg.msg.map(msg => msg.toPreview()).join('')}`,
})),
resid: this.resid,
source: "聊天记录",
summary: `查看${this.message.length}条转发消息`,
uniseq: id,
}
},
prompt: "[聊天记录]",
ver: "0.0.0.5",
view: "contact"
}
return [{
lightAppElem: {
data: Buffer.concat([
Buffer.from([0x01]),
zlib.deflateSync(Buffer.from(JSON.stringify(elementJson), 'utf-8'))
])
}
}]
}
toPreview(): string {
return "[聊天记录]";
}
}

View File

@ -1,10 +0,0 @@
import { IPacketMsgElement } from "@/core/packet/msg/element";
import { SendMessageElement } from "@/core";
export interface PacketForwardNode {
groupId?: number
senderId: number
senderName: string
time: number
msg: IPacketMsgElement<SendMessageElement>[]
}

View File

@ -0,0 +1,13 @@
import {IPacketMsgElement} from "@/core/packet/msg/element";
import {SendMessageElement} from "@/core";
export interface PacketMsg {
seq?: number;
clientSeq?: number;
groupId?: number;
senderUid: string;
senderUin: number;
senderName: string;
time: number;
msg: IPacketMsgElement<SendMessageElement>[]
}

View File

@ -11,9 +11,9 @@ import {NTV2RichMediaReq} from "@/core/packet/proto/oidb/common/Ntv2.RichMediaRe
import {HttpConn0x6ff_501} from "@/core/packet/proto/action/action";
import {LongMsgResult, SendLongMsgReq} from "@/core/packet/proto/message/action";
import {PacketMsgBuilder} from "@/core/packet/msg/builder";
import {PacketForwardNode} from "@/core/packet/msg/entity/forward";
import {PacketMsgPicElement} from "@/core/packet/msg/element";
import {LogWrapper} from "@/common/log";
import {PacketMsg} from "@/core/packet/msg/message";
export type PacketHexStr = string & { readonly hexNya: unique symbol };
@ -94,7 +94,7 @@ export class PacketPacker {
return this.toHexStr(this.packOidbPacket(0xfe1, 2, oidb_0xfe1_2));
}
packUploadForwardMsg(selfUid: string, msg: PacketForwardNode[], groupUin: number = 0): PacketHexStr {
packUploadForwardMsg(selfUid: string, msg: PacketMsg[], groupUin: number = 0): PacketHexStr {
// this.logger.logDebug("packUploadForwardMsg START!!!", selfUid, msg, groupUin);
const msgBody = this.packetBuilder.buildFakeMsg(selfUid, msg);
const longMsgResultData = new NapProtoMsg(LongMsgResult).encode(

View File

@ -38,6 +38,7 @@ export default class SetAvatar extends BaseAction<Payload, null> {
throw `头像${payload.file}设置失败,api无返回`;
}
// log(`头像设置返回:${JSON.stringify(ret)}`)
// @ts-ignore
if (ret['result'] == 1004022) {
throw `头像${payload.file}设置失败,文件可能不是图片格式`;
} else if (ret['result'] != 0) {

View File

@ -64,6 +64,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
});
this.app.use((req, res, next) => this.authorize(this.token, req, res, next));
// @ts-ignore
this.app.use((req, res) => this.handleRequest(req, res));
this.server.listen(this.port, () => {