mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
refactor: adjust NapProto
& proto structure
This commit is contained in:
@@ -63,6 +63,7 @@ export class NTQQGroupApi {
|
||||
let oidb_0xed3 = new NapProtoMsg(OidbSvcTrpcTcp0XED3_1).encode({
|
||||
uin: peer,
|
||||
groupUin: group,
|
||||
friendUin: group,
|
||||
ext: 0
|
||||
});
|
||||
let oidb_packet = new NapProtoMsg(OidbSvcTrpcTcpBase).encode({
|
||||
|
@@ -32,7 +32,7 @@ interface BaseProtoFieldType<T, O extends boolean, R extends O extends true ? fa
|
||||
no: number;
|
||||
type: T;
|
||||
optional: O;
|
||||
repeated: R;
|
||||
repeat: R;
|
||||
}
|
||||
|
||||
interface ScalarProtoFieldType<T extends ScalarType, O extends boolean, R extends O extends true ? false : boolean> extends BaseProtoFieldType<T, O, R> {
|
||||
@@ -51,55 +51,55 @@ type ProtoMessageType = {
|
||||
[key: string]: ProtoFieldType;
|
||||
};
|
||||
|
||||
export function ProtoField<T extends ScalarType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, repeated?: R, optional?: O): ScalarProtoFieldType<T, O, R>;
|
||||
export function ProtoField<T extends () => ProtoMessageType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, repeated?: R, optional?: O): MessageProtoFieldType<T, O, R>;
|
||||
export function ProtoField(no: number, type: ScalarType | (() => ProtoMessageType), repeated?: boolean, optional?: boolean): ProtoFieldType {
|
||||
export function ProtoField<T extends ScalarType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, optional?: O, repeat?: R): ScalarProtoFieldType<T, O, R>;
|
||||
export function ProtoField<T extends () => ProtoMessageType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, optional?: O, repeat?: R): MessageProtoFieldType<T, O, R>;
|
||||
export function ProtoField(no: number, type: ScalarType | (() => ProtoMessageType), optional?: boolean, repeat?: boolean): ProtoFieldType {
|
||||
if (typeof type === 'function') {
|
||||
return { kind: 'message', no: no, type: type, repeated: repeated ?? false, optional: optional ?? false };
|
||||
return { kind: 'message', no: no, type: type, optional: optional ?? false, repeat: repeat ?? false };
|
||||
} else {
|
||||
return { kind: 'scalar', no: no, type: type, repeated: repeated ?? false, optional: optional ?? false };
|
||||
return { kind: 'scalar', no: no, type: type, optional: optional ?? false, repeat: repeat ?? false };
|
||||
}
|
||||
}
|
||||
|
||||
type ProtoFieldReturnType<T> = T extends ScalarProtoFieldType<infer S, infer R, infer O>
|
||||
type ProtoFieldReturnType<T extends unknown, E extends boolean> = NonNullable<T> extends ScalarProtoFieldType<infer S, infer O, infer R>
|
||||
? ScalarTypeToTsType<S>
|
||||
: T extends MessageProtoFieldType<infer S, infer R, infer O>
|
||||
? ProtoStructType<ReturnType<S>>
|
||||
: T extends NonNullable<MessageProtoFieldType<infer S, infer O, infer R>>
|
||||
? NonNullable<ProtoStructType<ReturnType<S>, E>>
|
||||
: never;
|
||||
|
||||
type RequiredFieldsType<T> = {
|
||||
[K in keyof T as T[K] extends {
|
||||
optional: true
|
||||
} | MessageProtoFieldType<any, any, any> ? never : LowerCamelCase<K & string>]
|
||||
: T[K] extends { repeated: true }
|
||||
? ProtoFieldReturnType<T[K]>[]
|
||||
: ProtoFieldReturnType<T[K]>
|
||||
};
|
||||
type RequiredFieldsBaseType<T extends unknown, E extends boolean> = {
|
||||
[K in keyof T as T[K] extends { optional: true } ? never : LowerCamelCase<K & string>]:
|
||||
T[K] extends { repeat: true }
|
||||
? ProtoFieldReturnType<T[K], E>[]
|
||||
: ProtoFieldReturnType<T[K], E>
|
||||
}
|
||||
|
||||
type OptionalFieldsType<T> = {
|
||||
[K in keyof T as T[K] extends {
|
||||
optional: true
|
||||
} | MessageProtoFieldType<any, any, any> ? LowerCamelCase<K & string> : never]?:
|
||||
T[K] extends { repeated: true }
|
||||
? ProtoFieldReturnType<T[K]>[]
|
||||
: ProtoFieldReturnType<T[K]>
|
||||
};
|
||||
type OptionalFieldsBaseType<T extends unknown, E extends boolean> = {
|
||||
[K in keyof T as T[K] extends { optional: true } ? LowerCamelCase<K & string> : never]?:
|
||||
T[K] extends { repeat: true }
|
||||
? ProtoFieldReturnType<T[K], E>[]
|
||||
: ProtoFieldReturnType<T[K], E>
|
||||
}
|
||||
|
||||
type ProtoStructType<T> = RequiredFieldsType<T> & OptionalFieldsType<T>;
|
||||
type RequiredFieldsType<T extends unknown, E extends boolean> = E extends true ? Partial<RequiredFieldsBaseType<T, E>> : RequiredFieldsBaseType<T, E>;
|
||||
|
||||
const NapProtoMsgCache = new Map<ProtoMessageType, MessageType<ProtoStructType<ProtoMessageType>>>();
|
||||
type OptionalFieldsType<T extends unknown, E extends boolean> = E extends true ? Partial<OptionalFieldsBaseType<T, E>> : OptionalFieldsBaseType<T, E>;
|
||||
|
||||
type ProtoStructType<T extends unknown, E extends boolean> = RequiredFieldsType<T, E> & OptionalFieldsType<T, E>;
|
||||
|
||||
const NapProtoMsgCache = new Map<ProtoMessageType, MessageType<ProtoStructType<ProtoMessageType, boolean>>>();
|
||||
|
||||
export class NapProtoMsg<T extends ProtoMessageType> {
|
||||
private readonly _msg: T;
|
||||
private readonly _field: PartialFieldInfo[];
|
||||
private readonly _proto_msg: MessageType<ProtoStructType<T>>;
|
||||
private readonly _proto_msg: MessageType<ProtoStructType<T, boolean>>;
|
||||
|
||||
constructor(fields: T) {
|
||||
this._msg = fields;
|
||||
this._field = Object.keys(fields).map(key => {
|
||||
const field = fields[key];
|
||||
if (field.kind === 'scalar') {
|
||||
const repeatType = field.repeated
|
||||
const repeatType = field.repeat
|
||||
? [ScalarType.STRING, ScalarType.BYTES].includes(field.type)
|
||||
? RepeatType.UNPACKED
|
||||
: RepeatType.PACKED
|
||||
@@ -122,19 +122,19 @@ export class NapProtoMsg<T extends ProtoMessageType> {
|
||||
no: field.no,
|
||||
name: key,
|
||||
kind: 'message',
|
||||
repeat: field.repeated ? RepeatType.PACKED : RepeatType.NO,
|
||||
repeat: field.repeat ? RepeatType.PACKED : RepeatType.NO,
|
||||
T: () => rt,
|
||||
};
|
||||
}
|
||||
}) as PartialFieldInfo[];
|
||||
this._proto_msg = new MessageType<ProtoStructType<T>>('nya', this._field);
|
||||
this._proto_msg = new MessageType<ProtoStructType<T, boolean>>('nya', this._field);
|
||||
}
|
||||
|
||||
encode(data: ProtoStructType<T>): Uint8Array {
|
||||
return this._proto_msg.toBinary(data);
|
||||
encode(data: ProtoStructType<T, true>): Uint8Array {
|
||||
return this._proto_msg.toBinary(data)
|
||||
}
|
||||
|
||||
decode(data: Uint8Array): ProtoStructType<T> {
|
||||
return this._proto_msg.fromBinary(data);
|
||||
decode(data: Uint8Array): ProtoStructType<T, false> {
|
||||
return this._proto_msg.fromBinary(data) as ProtoStructType<T, false>;
|
||||
}
|
||||
}
|
||||
|
11
src/core/proto/message/message.ts
Normal file
11
src/core/proto/message/message.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import {ProtoField} from "@/core/proto/NapProto";
|
||||
import {ScalarType} from "@protobuf-ts/runtime";
|
||||
|
||||
export const ContentHead = {
|
||||
type: ProtoField(1, ScalarType.UINT32),
|
||||
subType: ProtoField(2, ScalarType.UINT32, true),
|
||||
msgId: ProtoField(4, ScalarType.UINT32),
|
||||
sequence: ProtoField(5, ScalarType.UINT32),
|
||||
timeStamp: ProtoField(6, ScalarType.UINT32),
|
||||
field7: ProtoField(7, ScalarType.UINT64),
|
||||
}
|
@@ -4,7 +4,7 @@ import { ProtoField } from "../NapProto";
|
||||
// Send Poke
|
||||
export const OidbSvcTrpcTcp0XED3_1 = {
|
||||
uin: ProtoField(1, ScalarType.UINT32),
|
||||
groupUin: ProtoField(2, ScalarType.UINT32, false, true),
|
||||
friendUin: ProtoField(5, ScalarType.BYTES, false, true),
|
||||
ext: ProtoField(6, ScalarType.UINT32)
|
||||
groupUin: ProtoField(2, ScalarType.UINT32),
|
||||
friendUin: ProtoField(5, ScalarType.UINT32),
|
||||
ext: ProtoField(6, ScalarType.UINT32, true)
|
||||
}
|
@@ -1,8 +1,12 @@
|
||||
import {ScalarType} from "@protobuf-ts/runtime";
|
||||
import {ProtoField} from "../NapProto";
|
||||
|
||||
|
||||
export const OidbSvcTrpcTcp0XEE1_2 = {
|
||||
uin: ProtoField(1, ScalarType.UINT32),
|
||||
key: ProtoField(3, ScalarType.BYTES, false, true),
|
||||
export const OidbSvcTrpcTcp0XFE1_2 = {
|
||||
uid: ProtoField(1, ScalarType.STRING, true),
|
||||
field2: ProtoField(2, ScalarType.UINT32),
|
||||
key: ProtoField(3, () => OidbSvcTrpcTcp0XFE1_2Key, false, true),
|
||||
}
|
||||
|
||||
export const OidbSvcTrpcTcp0XFE1_2Key = {
|
||||
key: ProtoField(1, ScalarType.UINT32)
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
import { ScalarType } from "@protobuf-ts/runtime";
|
||||
import { ProtoField } from "../NapProto";
|
||||
import { ScalarType } from '@protobuf-ts/runtime';
|
||||
|
||||
export const OidbSvcTrpcTcpBase = {
|
||||
command: ProtoField(1, ScalarType.UINT32),
|
||||
subCommand: ProtoField(2, ScalarType.UINT32),
|
||||
body: ProtoField(4, ScalarType.BYTES),
|
||||
isReserved: ProtoField(12, ScalarType.UINT32, false, true)
|
||||
errorMsg: ProtoField(5, ScalarType.STRING),
|
||||
isReserved: ProtoField(12, ScalarType.UINT32)
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
import { ScalarType } from "@protobuf-ts/runtime";
|
||||
import { ProtoField } from "../../NapProto";
|
||||
|
||||
|
||||
export const NTV2RichMediaReq = {
|
||||
ReqHead: ProtoField(1, ScalarType.BYTES),
|
||||
DownloadRKeyReq: ProtoField(4, ScalarType.BYTES),
|
||||
|
Reference in New Issue
Block a user