mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-16 13:01:14 +00:00
feat & refactor: add more packetElement & refactor packetMsg
This commit is contained in:
parent
524fd258d8
commit
698e095364
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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 "[聊天记录]";
|
||||
}
|
||||
}
|
||||
|
@ -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>[]
|
||||
}
|
13
src/core/packet/msg/message.ts
Normal file
13
src/core/packet/msg/message.ts
Normal 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>[]
|
||||
}
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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, () => {
|
||||
|
Loading…
Reference in New Issue
Block a user