refactor: protobufjs给我似!

This commit is contained in:
手瓜一十雪
2024-09-29 20:06:11 +08:00
parent 78bac1dbd1
commit d332b199b5
6 changed files with 102 additions and 130 deletions

View File

@@ -13,7 +13,6 @@
"devDependencies": {
"@babel/preset-typescript": "^7.24.7",
"@log4js-node/log4js-api": "^1.0.2",
"@protobuf-ts/plugin": "^2.9.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/cors": "^2.8.17",
@@ -34,6 +33,7 @@
},
"dependencies": {
"ajv": "^8.13.0",
"@protobuf-ts/plugin": "^2.9.4",
"async-mutex": "^0.5.0",
"chalk": "^5.3.0",
"commander": "^12.1.0",
@@ -45,7 +45,6 @@
"image-size": "^1.1.1",
"json-schema-to-ts": "^3.1.0",
"log4js": "^6.9.1",
"protobufjs": "~7.4.0",
"qrcode-terminal": "^0.12.0",
"silk-wasm": "^3.6.1",
"ws": "^8.18.0"

View File

@@ -1,37 +1,46 @@
import * as pb from 'protobufjs';
import { MessageType, BinaryReader } from '@protobuf-ts/runtime';
export const BodyInner = new MessageType("BodyInner", [
{ no: 1, name: "msgType", kind: "scalar", T: 13 /* uint32 */, opt: true },
{ no: 2, name: "subType", kind: "scalar", T: 13 /* uint32 */, opt: true }
]);
export const BodyInner = new pb.Type("BodyInner")
.add(new pb.Field("msgType", 1, "uint32", "optional"))
.add(new pb.Field("subType", 2, "uint32", "optional"))
export const NoifyData = new MessageType("NoifyData", [
{ no: 1, name: "skip", kind: "scalar", T: 12 /* bytes */, opt: true },
{ no: 2, name: "innerData", kind: "scalar", T: 12 /* bytes */, opt: true }
]);
export const NoifyData = new pb.Type("NoifyData")
.add(new pb.Field("skip", 1, "bytes", "optional"))
.add(new pb.Field("innerData", 2, "bytes", "optional"))
export const MsgHead = new MessageType("MsgHead", [
{ no: 2, name: "bodyInner", kind: "message", T: () => BodyInner, opt: true },
{ no: 3, name: "noifyData", kind: "message", T: () => NoifyData, opt: true }
]);
export const MsgHead = new pb.Type("MsgHead")
.add(BodyInner)
.add(NoifyData)
.add(new pb.Field("bodyInner", 2, "BodyInner", "optional"))
.add(new pb.Field("noifyData", 3, "NoifyData", "optional"));
export const Message = new MessageType("Message", [
{ no: 1, name: "msgHead", kind: "message", T: () => MsgHead }
]);
export const Message = new pb.Type("Message")
.add(MsgHead)
.add(new pb.Field("msgHead", 1, "MsgHead"))
export const SubDetail = new MessageType("SubDetail", [
{ no: 1, name: "msgSeq", kind: "scalar", T: 13 /* uint32 */ },
{ no: 2, name: "msgTime", kind: "scalar", T: 13 /* uint32 */ },
{ no: 6, name: "senderUid", kind: "scalar", T: 9 /* string */ }
]);
export const SubDetail = new pb.Type("SubDetail")
.add(new pb.Field("msgSeq", 1, "uint32"))
.add(new pb.Field("msgTime", 2, "uint32"))
.add(new pb.Field("senderUid", 6, "string"))
export const RecallDetails = new MessageType("RecallDetails", [
{ no: 1, name: "operatorUid", kind: "scalar", T: 9 /* string */ },
{ no: 3, name: "subDetail", kind: "message", T: () => SubDetail }
]);
export const RecallDetails = new pb.Type("RecallDetails")
.add(SubDetail)
.add(new pb.Field("operatorUid", 1, "string"))
.add(new pb.Field("subDetail", 3, "SubDetail"))
export const RecallGroup = new pb.Type("RecallGroup")
.add(RecallDetails)
.add(new pb.Field("type", 1, "int32"))
.add(new pb.Field("peerUid", 4, "uint32"))
.add(new pb.Field("recallDetails", 11, "RecallDetails"))
.add(new pb.Field("grayTipsSeq", 37, "uint32"))
export const RecallGroup = new MessageType("RecallGroup", [
{ no: 1, name: "type", kind: "scalar", T: 5 /* int32 */ },
{ no: 4, name: "peerUid", kind: "scalar", T: 13 /* uint32 */ },
{ no: 11, name: "recallDetails", kind: "message", T: () => RecallDetails },
{ no: 37, name: "grayTipsSeq", kind: "scalar", T: 13 /* uint32 */ }
]);
export function decodeMessage(buffer: Uint8Array): any {
const reader = new BinaryReader(buffer);
return Message.internalBinaryRead(reader, reader.len, { readUnknownField: true, readerFactory: () => new BinaryReader(buffer) });
}
export function decodeRecallGroup(buffer: Uint8Array): any {
const reader = new BinaryReader(buffer);
return RecallGroup.internalBinaryRead(reader, reader.len, { readUnknownField: true, readerFactory: () => new BinaryReader(buffer) });
}

View File

@@ -1,95 +1,59 @@
import * as pb from 'protobufjs';
import { MessageType, BinaryReader, RepeatType } from '@protobuf-ts/runtime';
// Proto: from src/core/proto/ProfileLike.proto
// Author: Mlikiowa
export const LikeDetailType = new MessageType("LikeDetailType", [
{ no: 1, name: "txt", kind: "scalar", T: 9 /* string */ },
{ no: 2, name: "uin", kind: "scalar", T: 3 /* int64 */ },
{ no: 3, name: "nickname", kind: "scalar", T: 9 /* string */ }
]);
export interface LikeDetailType {
txt: string;
uin: pb.Long;
nickname: string;
}
export interface LikeMsgType {
times: number;
time: number;
detail: LikeDetailType;
export const LikeMsgType = new MessageType("LikeMsgType", [
{ no: 1, name: "times", kind: "scalar", T: 5 /* int32 */ },
{ no: 2, name: "time", kind: "scalar", T: 5 /* int32 */ },
{ no: 3, name: "detail", kind: "message", T: () => LikeDetailType }
]);
export const ProfileLikeSubTipType = new MessageType("ProfileLikeSubTipType", [
{ no: 1, name: "msg", kind: "message", T: () => LikeMsgType }
]);
export const ProfileLikeTipType = new MessageType("ProfileLikeTipType", [
{ no: 1, name: "msgType", kind: "scalar", T: 5 /* int32 */ },
{ no: 2, name: "subType", kind: "scalar", T: 5 /* int32 */ },
{ no: 3, name: "content", kind: "message", T: () => ProfileLikeSubTipType }
]);
export const SysMessageHeaderType = new MessageType("SysMessageHeaderType", [
{ no: 1, name: "id", kind: "scalar", T: 9 /* string */ },
{ no: 2, name: "timestamp", kind: "scalar", T: 5 /* int32 */ },
{ no: 3, name: "sender", kind: "scalar", T: 9 /* string */ }
]);
export const SysMessageMsgSpecType = new MessageType("SysMessageMsgSpecType", [
{ no: 1, name: "msgType", kind: "scalar", T: 5 /* int32 */ },
{ no: 2, name: "subType", kind: "scalar", T: 5 /* int32 */ },
{ no: 3, name: "subSubType", kind: "scalar", T: 5 /* int32 */ },
{ no: 4, name: "msgSeq", kind: "scalar", T: 5 /* int32 */ },
{ no: 5, name: "time", kind: "scalar", T: 5 /* int32 */ },
{ no: 6, name: "msgId", kind: "scalar", T: 3 /* int64 */ },
{ no: 7, name: "other", kind: "scalar", T: 5 /* int32 */ }
]);
export const SysMessageBodyWrapperType = new MessageType("SysMessageBodyWrapperType", [
{ no: 1, name: "wrappedBody", kind: "scalar", T: 12 /* bytes */ }
]);
export const SysMessageType = new MessageType("SysMessageType", [
{ no: 1, name: "header", kind: "message", T: () => SysMessageHeaderType, repeat: RepeatType.PACKED },
{ no: 2, name: "msgSpec", kind: "message", T: () => SysMessageMsgSpecType, repeat: RepeatType.PACKED },
{ no: 3, name: "bodyWrapper", kind: "message", T: () => SysMessageBodyWrapperType }
]);
export function decodeProfileLikeTip(buffer: Uint8Array): any {
const reader = new BinaryReader(buffer);
return ProfileLikeTipType.internalBinaryRead(reader, reader.len, { readUnknownField: true, readerFactory: () => new BinaryReader(buffer) });
}
export interface profileLikeSubTipType {
msg: LikeMsgType;
export function decodeSysMessage(buffer: Uint8Array): any {
const reader = new BinaryReader(buffer);
return SysMessageType.internalBinaryRead(reader, reader.len, { readUnknownField: true, readerFactory: () => new BinaryReader(buffer) });
}
export interface ProfileLikeTipType {
msgType: number;
subType: number;
content: profileLikeSubTipType;
}
export interface SysMessageHeaderType {
id: string;
timestamp: number;
sender: string;
}
export interface SysMessageMsgSpecType {
msgType: number;
subType: number;
subSubType: number;
msgSeq: number;
time: number;
msgId: pb.Long;
other: number;
}
export interface SysMessageBodyWrapperType {
wrappedBody: Uint8Array;
}
export interface SysMessageType {
header: SysMessageHeaderType[];
msgSpec: SysMessageMsgSpecType[];
bodyWrapper: SysMessageBodyWrapperType;
}
export const SysMessageHeader = new pb.Type("SysMessageHeader")
.add(new pb.Field("PeerNumber", 1, "uint32"))
.add(new pb.Field("PeerString", 2, "string"))
.add(new pb.Field("Uin", 5, "uint32"))
.add(new pb.Field("Uid", 6, "string", "optional"));
export const SysMessageMsgSpec = new pb.Type("SysMessageMsgSpec")
.add(new pb.Field("msgType", 1, "uint32"))
.add(new pb.Field("subType", 2, "uint32"))
.add(new pb.Field("subSubType", 3, "uint32"))
.add(new pb.Field("msgSeq", 5, "uint32"))
.add(new pb.Field("time", 6, "uint32"))
.add(new pb.Field("msgId", 12, "uint64"))
.add(new pb.Field("other", 13, "uint32"));
export const SysMessageBodyWrapper = new pb.Type("SysMessageBodyWrapper")
.add(new pb.Field("wrappedBody", 2, "bytes"));
export const SysMessage = new pb.Type("SysMessage")
.add(SysMessageHeader)
.add(SysMessageMsgSpec)
.add(SysMessageBodyWrapper)
.add(new pb.Field("header", 1, "SysMessageHeader", "repeated"))
.add(new pb.Field("msgSpec", 2, "SysMessageMsgSpec", "repeated"))
.add(new pb.Field("bodyWrapper", 3, "SysMessageBodyWrapper"));
export const likeDetail = new pb.Type("likeDetail")
.add(new pb.Field("txt", 1, "string"))
.add(new pb.Field("uin", 3, "int64"))
.add(new pb.Field("nickname", 5, "string"));
export const likeMsg = new pb.Type("likeMsg")
.add(likeDetail)
.add(new pb.Field("times", 1, "int32"))
.add(new pb.Field("time", 2, "int32"))
.add(new pb.Field("detail", 3, "likeDetail"));
export const profileLikeSubTip = new pb.Type("profileLikeSubTip")
.add(likeMsg)
.add(new pb.Field("msg", 14, "likeMsg"))
export const profileLikeTip = new pb.Type("profileLikeTip")
.add(profileLikeSubTip)
.add(new pb.Field("msgType", 1, "int32"))
.add(new pb.Field("subType", 2, "int32"))
.add(new pb.Field("content", 203, "profileLikeSubTip"));

View File

@@ -34,7 +34,7 @@ import { RequestUtil } from '@/common/request';
import fs from 'node:fs';
import fsPromise from 'node:fs/promises';
import { OB11FriendAddNoticeEvent } from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
import { SysMessage, SysMessageType } from '@/core/proto/ProfileLike';
import { decodeSysMessage } from '@/core/proto/ProfileLike';
type RawToOb11Converters = {
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
@@ -841,7 +841,7 @@ export class OneBotMsgApi {
return { path, fileName: inputdata.name ?? fileName };
}
async parseSysMessage(msg: number[]) {
const sysMsg = SysMessage.decode(Uint8Array.from(msg)) as unknown as SysMessageType;
const sysMsg = decodeSysMessage(Uint8Array.from(msg));
if (sysMsg.msgSpec.length === 0) {
return;
}

View File

@@ -1,5 +1,5 @@
import { NapCatCore } from '@/core';
import { profileLikeTip, ProfileLikeTipType } from '@/core/proto/ProfileLike';
import { decodeProfileLikeTip } from '@/core/proto/ProfileLike';
import { NapCatOneBot11Adapter } from '@/onebot';
import { OB11ProfileLikeEvent } from '../event/notice/OB11ProfileLikeEvent';
@@ -13,7 +13,7 @@ export class OneBotUserApi {
this.core = core;
}
async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> {
const likeTip = profileLikeTip.decode(Uint8Array.from(wrappedBody)) as unknown as ProfileLikeTipType;
const likeTip = decodeProfileLikeTip(Uint8Array.from(wrappedBody));
if (likeTip?.msgType !== 0 || likeTip?.subType !== 203) return;
this.core.context.logger.logDebug("收到点赞通知消息");
const likeMsg = likeTip.content.msg;

View File

@@ -45,7 +45,7 @@ import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecal
import { LRUCache } from '@/common/lru-cache';
import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener';
import { Native } from '@/native';
import { Message, RecallGroup } from '@/core/proto/Message';
import { decodeMessage, decodeRecallGroup, Message, RecallGroup } from '@/core/proto/Message';
//OneBot实现类
export class NapCatOneBot11Adapter {
@@ -82,7 +82,7 @@ export class NapCatOneBot11Adapter {
this.nativeCore = new Native(context.pathWrapper.binaryPath);
this.nativeCore.registerRecallCallback(async (hex: string) => {
try {
let data = Message.decode(Buffer.from(hex, 'hex')) as any;
let data = decodeMessage(Buffer.from(hex, 'hex')) as any;
//data.MsgHead.BodyInner.MsgType SubType
let bodyInner = data.msgHead?.bodyInner;
//context.logger.log("[appNative] Parse MsgType:" + bodyInner.msgType + " / SubType:" + bodyInner.subType);
@@ -91,7 +91,7 @@ export class NapCatOneBot11Adapter {
//跳过 4字节 群号 + 不知道的1字节 +2字节 长度
let uid = RecallData.readUint32BE();
const buffer = Buffer.from(RecallData.toString('hex').slice(14), 'hex');
let seq: number = (RecallGroup.decode(buffer) as any).recallDetails.subDetail.msgSeq;
let seq: number = decodeRecallGroup(buffer).recallDetails.subDetail.msgSeq;
let peer: Peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: uid.toString() };
context.logger.log("[Native] 群消息撤回 Peer: " + uid.toString() + " / MsgSeq:" + seq);
let msgs = await core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, seq.toString());