mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
feat: add more msgElement
This commit is contained in:
@@ -372,6 +372,7 @@ export interface ReplyElement {
|
|||||||
senderUin: string;
|
senderUin: string;
|
||||||
senderUidStr?: string;
|
senderUidStr?: string;
|
||||||
replyMsgTime?: string;
|
replyMsgTime?: string;
|
||||||
|
replyMsgClientSeq?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SendReplyElement {
|
export interface SendReplyElement {
|
||||||
@@ -391,7 +392,7 @@ export interface SendMarketFaceElement {
|
|||||||
marketFaceElement: MarketFaceElement;
|
marketFaceElement: MarketFaceElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SendstructLongMsgElement {
|
export interface SendStructLongMsgElement {
|
||||||
elementType: ElementType.STRUCTLONGMSG;
|
elementType: ElementType.STRUCTLONGMSG;
|
||||||
elementId: string;
|
elementId: string;
|
||||||
structLongMsgElement: StructLongMsgElement;
|
structLongMsgElement: StructLongMsgElement;
|
||||||
|
@@ -127,7 +127,7 @@ export class PacketHighwaySession {
|
|||||||
extend
|
extend
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.logger.logError(`[Highway] get upload invalid ukey ${ukey}, don't need upload!`);
|
this.logger.logDebug(`[Highway] get upload invalid ukey ${ukey}, don't need upload!`);
|
||||||
}
|
}
|
||||||
img.msgInfo = preRespData.upload.msgInfo;
|
img.msgInfo = preRespData.upload.msgInfo;
|
||||||
// img.groupPicExt = new NapProtoMsg(CustomFace).decode(preRespData.tcpUpload.compatQMsg)
|
// img.groupPicExt = new NapProtoMsg(CustomFace).decode(preRespData.tcpUpload.compatQMsg)
|
||||||
|
@@ -14,8 +14,7 @@ export class PacketMsgBuilder {
|
|||||||
buildFakeMsg(selfUid: string, element: PacketForwardNode[]): NapProtoEncodeStructType<typeof PushMsgBody>[] {
|
buildFakeMsg(selfUid: string, element: PacketForwardNode[]): NapProtoEncodeStructType<typeof PushMsgBody>[] {
|
||||||
return element.map((node): 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.senderId}&spec=640&img_type=jpg`;
|
||||||
const msgElement = node.msg.map((msg) => msg.buildElement() ?? []);
|
const msgElement = node.msg.flatMap(msg => msg.buildElement() ?? []);
|
||||||
// this.logger.logDebug(`NOW MSG ELEMENT: ${JSON.stringify(msgElement)}`);
|
|
||||||
return {
|
return {
|
||||||
responseHead: {
|
responseHead: {
|
||||||
fromUid: "",
|
fromUid: "",
|
||||||
|
@@ -1,16 +1,27 @@
|
|||||||
import assert from "node:assert";
|
import assert from "node:assert";
|
||||||
|
import * as zlib from "node:zlib";
|
||||||
import {NapProtoEncodeStructType, NapProtoMsg} from "@/core/packet/proto/NapProto";
|
import {NapProtoEncodeStructType, NapProtoMsg} from "@/core/packet/proto/NapProto";
|
||||||
import {CustomFace, Elem, MentionExtra, NotOnlineImage} from "@/core/packet/proto/message/element";
|
import {
|
||||||
|
CustomFace,
|
||||||
|
Elem,
|
||||||
|
MarkdownData,
|
||||||
|
MentionExtra,
|
||||||
|
NotOnlineImage,
|
||||||
|
QBigFaceExtra,
|
||||||
|
QSmallFaceExtra
|
||||||
|
} from "@/core/packet/proto/message/element";
|
||||||
import {
|
import {
|
||||||
AtType,
|
AtType,
|
||||||
PicType,
|
PicType,
|
||||||
SendArkElement,
|
SendArkElement,
|
||||||
SendFaceElement,
|
SendFaceElement,
|
||||||
SendFileElement,
|
SendFileElement,
|
||||||
|
SendMarkdownElement,
|
||||||
SendMessageElement,
|
SendMessageElement,
|
||||||
SendPicElement,
|
SendPicElement,
|
||||||
SendPttElement,
|
SendPttElement,
|
||||||
SendReplyElement,
|
SendReplyElement,
|
||||||
|
SendStructLongMsgElement,
|
||||||
SendTextElement,
|
SendTextElement,
|
||||||
SendVideoElement
|
SendVideoElement
|
||||||
} from "@/core";
|
} from "@/core";
|
||||||
@@ -19,7 +30,8 @@ import {MsgInfo} from "@/core/packet/proto/oidb/common/Ntv2.RichMediaReq";
|
|||||||
// raw <-> packet
|
// raw <-> packet
|
||||||
// TODO: check ob11 -> raw impl!
|
// TODO: check ob11 -> raw impl!
|
||||||
// TODO: parse to raw element
|
// TODO: parse to raw element
|
||||||
export abstract class IPacketMsgElement<T extends SendMessageElement> {
|
// TODO: SendStructLongMsgElement
|
||||||
|
export abstract class IPacketMsgElement<T extends SendMessageElement | SendStructLongMsgElement> {
|
||||||
protected constructor(rawElement: T) {
|
protected constructor(rawElement: T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +39,7 @@ export abstract class IPacketMsgElement<T extends SendMessageElement> {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildElement(): NapProtoEncodeStructType<typeof Elem> | undefined {
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] | undefined {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,12 +52,12 @@ export class PacketMsgTextElement extends IPacketMsgElement<SendTextElement> {
|
|||||||
this.text = element.textElement.content;
|
this.text = element.textElement.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildElement(): NapProtoEncodeStructType<typeof Elem> {
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
return {
|
return [{
|
||||||
text: {
|
text: {
|
||||||
str: this.text
|
str: this.text
|
||||||
}
|
}
|
||||||
};
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,20 +71,19 @@ export class PacketMsgAtElement extends PacketMsgTextElement {
|
|||||||
this.atAll = element.textElement.atType === AtType.atAll;
|
this.atAll = element.textElement.atType === AtType.atAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildElement(): NapProtoEncodeStructType<typeof Elem> {
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
const res = new NapProtoMsg(MentionExtra).encode({
|
return [{
|
||||||
|
text: {
|
||||||
|
str: this.text,
|
||||||
|
pbReserve: new NapProtoMsg(MentionExtra).encode({
|
||||||
type: this.atAll ? 1 : 2,
|
type: this.atAll ? 1 : 2,
|
||||||
uin: 0,
|
uin: 0,
|
||||||
field5: 0,
|
field5: 0,
|
||||||
uid: this.targetUid,
|
uid: this.targetUid,
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
return {
|
|
||||||
text: {
|
|
||||||
str: this.text,
|
|
||||||
pbReserve: res
|
|
||||||
}
|
}
|
||||||
};
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,15 +111,112 @@ export class PacketMsgPicElement extends IPacketMsgElement<SendPicElement> {
|
|||||||
this.picType = element.picElement.picType;
|
this.picType = element.picElement.picType;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildElement(): NapProtoEncodeStructType<typeof Elem> {
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
assert(this.msgInfo !== null, 'msgInfo is null, expected not null');
|
assert(this.msgInfo !== null, 'msgInfo is null, expected not null');
|
||||||
return {
|
return [{
|
||||||
commonElem: {
|
commonElem: {
|
||||||
serviceType: 48,
|
serviceType: 48,
|
||||||
pbElem: new NapProtoMsg(MsgInfo).encode(this.msgInfo),
|
pbElem: new NapProtoMsg(MsgInfo).encode(this.msgInfo),
|
||||||
businessType: 10,
|
businessType: 10,
|
||||||
}
|
}
|
||||||
} as NapProtoEncodeStructType<typeof Elem>
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PacketMsgReplyElement extends IPacketMsgElement<SendReplyElement> {
|
||||||
|
messageId: bigint;
|
||||||
|
messageSeq: number;
|
||||||
|
messageClientSeq: number;
|
||||||
|
targetUin: number;
|
||||||
|
targetUid: string;
|
||||||
|
time: number;
|
||||||
|
|
||||||
|
constructor(element: SendReplyElement) {
|
||||||
|
super(element);
|
||||||
|
this.messageId = BigInt(element.replyElement.replayMsgId ?? 0);
|
||||||
|
this.messageSeq = Number(element.replyElement.replayMsgSeq ?? 0);
|
||||||
|
this.messageClientSeq = Number(element.replyElement.replyMsgClientSeq ?? 0);
|
||||||
|
this.targetUin = Number(element.replyElement.senderUin ?? 0);
|
||||||
|
this.targetUid = element.replyElement.senderUidStr ?? '';
|
||||||
|
this.time = Number(element.replyElement.replyMsgTime ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
get isGroupReply(): boolean {
|
||||||
|
return this.messageClientSeq !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
|
return [{
|
||||||
|
srcMsg: {
|
||||||
|
origSeqs: [this.isGroupReply ? this.messageClientSeq : this.messageSeq],
|
||||||
|
senderUin: BigInt(this.targetUin),
|
||||||
|
time: this.time,
|
||||||
|
elems: [], // TODO: in replyElement.sourceMsgTextElems
|
||||||
|
pbReserve: {
|
||||||
|
messageId: this.messageId,
|
||||||
|
},
|
||||||
|
toUin: BigInt(0),
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: this.isGroupReply ? {
|
||||||
|
str: 'nya~',
|
||||||
|
pbReserve: new NapProtoMsg(MentionExtra).encode({
|
||||||
|
type: this.targetUin === 0 ? 1 : 2,
|
||||||
|
uin: 0,
|
||||||
|
field5: 0,
|
||||||
|
uid: String(this.targetUid),
|
||||||
|
}),
|
||||||
|
} : undefined,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PacketMsgFaceElement extends IPacketMsgElement<SendFaceElement> {
|
||||||
|
faceId: number;
|
||||||
|
isLargeFace: boolean;
|
||||||
|
|
||||||
|
constructor(element: SendFaceElement) {
|
||||||
|
super(element);
|
||||||
|
this.faceId = element.faceElement.faceIndex;
|
||||||
|
this.isLargeFace = element.faceElement.faceType === 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
|
if (this.isLargeFace) {
|
||||||
|
return [{
|
||||||
|
commonElem: {
|
||||||
|
serviceType: 37,
|
||||||
|
pbElem: new NapProtoMsg(QBigFaceExtra).encode({
|
||||||
|
aniStickerPackId: "1",
|
||||||
|
aniStickerId: "8",
|
||||||
|
faceId: this.faceId,
|
||||||
|
field4: 1,
|
||||||
|
field6: "",
|
||||||
|
preview: "",
|
||||||
|
field9: 1
|
||||||
|
}),
|
||||||
|
businessType: 1
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
} else if (this.faceId < 260) {
|
||||||
|
return [{
|
||||||
|
face: {
|
||||||
|
index: this.faceId
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
return [{
|
||||||
|
commonElem: {
|
||||||
|
serviceType: 33,
|
||||||
|
pbElem: new NapProtoMsg(QSmallFaceExtra).encode({
|
||||||
|
faceId: this.faceId,
|
||||||
|
preview: "",
|
||||||
|
preview2: ""
|
||||||
|
}),
|
||||||
|
businessType: 1
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,33 +226,74 @@ export class PacketMsgPttElement extends IPacketMsgElement<SendPttElement> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class PacketMsgReplyElement extends IPacketMsgElement<SendReplyElement> {
|
|
||||||
constructor(element: SendReplyElement) {
|
|
||||||
super(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PacketMsgFaceElement extends IPacketMsgElement<SendFaceElement> {
|
|
||||||
constructor(element: SendFaceElement) {
|
|
||||||
super(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PacketMsgFileElement extends IPacketMsgElement<SendFileElement> {
|
|
||||||
constructor(element: SendFileElement) {
|
|
||||||
super(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PacketMsgVideoElement extends IPacketMsgElement<SendVideoElement> {
|
export class PacketMsgVideoElement extends IPacketMsgElement<SendVideoElement> {
|
||||||
constructor(element: SendVideoElement) {
|
constructor(element: SendVideoElement) {
|
||||||
super(element);
|
super(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PacketMsgLightAppElement extends IPacketMsgElement<SendArkElement> {
|
export class PacketMsgFileElement extends IPacketMsgElement<SendFileElement> {
|
||||||
constructor(element: SendArkElement) {
|
constructor(element: SendFileElement) {
|
||||||
super(element);
|
super(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PacketMsgLightAppElement extends IPacketMsgElement<SendArkElement> {
|
||||||
|
payload: string;
|
||||||
|
|
||||||
|
constructor(element: SendArkElement) {
|
||||||
|
super(element);
|
||||||
|
this.payload = element.arkElement.bytesData;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
|
return [{
|
||||||
|
lightAppElem: {
|
||||||
|
data: Buffer.concat([
|
||||||
|
Buffer.from([0x01]),
|
||||||
|
zlib.deflateSync(Buffer.from(this.payload, 'utf-8'))
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// export class PacketMsgMarkDownElement extends IPacketMsgElement<SendMarkdownElement> {
|
||||||
|
// content: string;
|
||||||
|
//
|
||||||
|
// constructor(element: SendMarkdownElement) {
|
||||||
|
// super(element);
|
||||||
|
// this.content = element.markdownElement.content;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||||
|
// return [{
|
||||||
|
// commonElem: {
|
||||||
|
// serviceType: 45,
|
||||||
|
// pbElem: new NapProtoMsg(MarkdownData).encode({
|
||||||
|
// content: this.content
|
||||||
|
// }),
|
||||||
|
// businessType: 1
|
||||||
|
// }
|
||||||
|
// }]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
// }]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
@@ -300,12 +300,19 @@ export const SrcMsg = {
|
|||||||
elems: ProtoField(5, () => Elem, false, true),
|
elems: ProtoField(5, () => Elem, false, true),
|
||||||
type: ProtoField(6, ScalarType.INT32, true),
|
type: ProtoField(6, ScalarType.INT32, true),
|
||||||
richMsg: ProtoField(7, ScalarType.BYTES, true),
|
richMsg: ProtoField(7, ScalarType.BYTES, true),
|
||||||
pbReserve: ProtoField(8, ScalarType.BYTES, true),
|
pbReserve: ProtoField(8, () => SrcMsgPbRes, true),
|
||||||
sourceMsg: ProtoField(9, ScalarType.BYTES, true),
|
sourceMsg: ProtoField(9, ScalarType.BYTES, true),
|
||||||
toUin: ProtoField(10, ScalarType.UINT64, true),
|
toUin: ProtoField(10, ScalarType.UINT64, true),
|
||||||
troopName: ProtoField(11, ScalarType.BYTES, true),
|
troopName: ProtoField(11, ScalarType.BYTES, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SrcMsgPbRes = {
|
||||||
|
messageId: ProtoField(3, ScalarType.UINT64),
|
||||||
|
senderUid: ProtoField(6, ScalarType.STRING, true),
|
||||||
|
receiverUid: ProtoField(7, ScalarType.STRING, true),
|
||||||
|
friendSeq: ProtoField(8, ScalarType.UINT32, true),
|
||||||
|
}
|
||||||
|
|
||||||
export const LightAppElem = {
|
export const LightAppElem = {
|
||||||
data: ProtoField(1, ScalarType.BYTES),
|
data: ProtoField(1, ScalarType.BYTES),
|
||||||
msgResid: ProtoField(2, ScalarType.BYTES, true),
|
msgResid: ProtoField(2, ScalarType.BYTES, true),
|
||||||
@@ -328,12 +335,12 @@ export const MentionExtra = {
|
|||||||
uid: ProtoField(9, ScalarType.STRING, true),
|
uid: ProtoField(9, ScalarType.STRING, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const QFaceExtra = {
|
export const QBigFaceExtra = {
|
||||||
field1: ProtoField(1, ScalarType.STRING, true),
|
AniStickerPackId: ProtoField(1, ScalarType.STRING, true),
|
||||||
field2: ProtoField(2, ScalarType.STRING, true),
|
AniStickerId: ProtoField(2, ScalarType.STRING, true),
|
||||||
faceId: ProtoField(3, ScalarType.INT32, true),
|
faceId: ProtoField(3, ScalarType.INT32, true),
|
||||||
field4: ProtoField(4, ScalarType.INT32, true),
|
Field4: ProtoField(4, ScalarType.INT32, true),
|
||||||
field5: ProtoField(5, ScalarType.INT32, true),
|
AniStickerType: ProtoField(5, ScalarType.INT32, true),
|
||||||
field6: ProtoField(6, ScalarType.STRING, true),
|
field6: ProtoField(6, ScalarType.STRING, true),
|
||||||
preview: ProtoField(7, ScalarType.STRING, true),
|
preview: ProtoField(7, ScalarType.STRING, true),
|
||||||
field9: ProtoField(9, ScalarType.INT32, true),
|
field9: ProtoField(9, ScalarType.INT32, true),
|
||||||
@@ -344,3 +351,7 @@ export const QSmallFaceExtra = {
|
|||||||
preview: ProtoField(2, ScalarType.STRING),
|
preview: ProtoField(2, ScalarType.STRING),
|
||||||
preview2: ProtoField(3, ScalarType.STRING),
|
preview2: ProtoField(3, ScalarType.STRING),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const MarkdownData = {
|
||||||
|
content: ProtoField(1, ScalarType.STRING)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user