diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index cee1a91a..da899346 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -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({ diff --git a/src/core/proto/NapProto.ts b/src/core/proto/NapProto.ts index b7ab8396..a3f8ff2d 100644 --- a/src/core/proto/NapProto.ts +++ b/src/core/proto/NapProto.ts @@ -32,7 +32,7 @@ interface BaseProtoFieldType extends BaseProtoFieldType { @@ -51,55 +51,55 @@ type ProtoMessageType = { [key: string]: ProtoFieldType; }; -export function ProtoField(no: number, type: T, repeated?: R, optional?: O): ScalarProtoFieldType; -export function ProtoField ProtoMessageType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, repeated?: R, optional?: O): MessageProtoFieldType; -export function ProtoField(no: number, type: ScalarType | (() => ProtoMessageType), repeated?: boolean, optional?: boolean): ProtoFieldType { +export function ProtoField(no: number, type: T, optional?: O, repeat?: R): ScalarProtoFieldType; +export function ProtoField ProtoMessageType, O extends boolean = false, R extends O extends true ? false : boolean = false>(no: number, type: T, optional?: O, repeat?: R): MessageProtoFieldType; +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 extends ScalarProtoFieldType +type ProtoFieldReturnType = NonNullable extends ScalarProtoFieldType ? ScalarTypeToTsType - : T extends MessageProtoFieldType - ? ProtoStructType> + : T extends NonNullable> + ? NonNullable, E>> : never; -type RequiredFieldsType = { - [K in keyof T as T[K] extends { - optional: true - } | MessageProtoFieldType ? never : LowerCamelCase] - : T[K] extends { repeated: true } - ? ProtoFieldReturnType[] - : ProtoFieldReturnType -}; +type RequiredFieldsBaseType = { + [K in keyof T as T[K] extends { optional: true } ? never : LowerCamelCase]: + T[K] extends { repeat: true } + ? ProtoFieldReturnType[] + : ProtoFieldReturnType +} -type OptionalFieldsType = { - [K in keyof T as T[K] extends { - optional: true - } | MessageProtoFieldType ? LowerCamelCase : never]?: - T[K] extends { repeated: true } - ? ProtoFieldReturnType[] - : ProtoFieldReturnType -}; +type OptionalFieldsBaseType = { + [K in keyof T as T[K] extends { optional: true } ? LowerCamelCase : never]?: + T[K] extends { repeat: true } + ? ProtoFieldReturnType[] + : ProtoFieldReturnType +} -type ProtoStructType = RequiredFieldsType & OptionalFieldsType; +type RequiredFieldsType = E extends true ? Partial> : RequiredFieldsBaseType; -const NapProtoMsgCache = new Map>>(); +type OptionalFieldsType = E extends true ? Partial> : OptionalFieldsBaseType; + +type ProtoStructType = RequiredFieldsType & OptionalFieldsType; + +const NapProtoMsgCache = new Map>>(); export class NapProtoMsg { private readonly _msg: T; private readonly _field: PartialFieldInfo[]; - private readonly _proto_msg: MessageType>; + private readonly _proto_msg: MessageType>; 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 { 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>('nya', this._field); + this._proto_msg = new MessageType>('nya', this._field); } - encode(data: ProtoStructType): Uint8Array { - return this._proto_msg.toBinary(data); + encode(data: ProtoStructType): Uint8Array { + return this._proto_msg.toBinary(data) } - decode(data: Uint8Array): ProtoStructType { - return this._proto_msg.fromBinary(data); + decode(data: Uint8Array): ProtoStructType { + return this._proto_msg.fromBinary(data) as ProtoStructType; } } diff --git a/src/core/proto/message/message.ts b/src/core/proto/message/message.ts new file mode 100644 index 00000000..d81a90a7 --- /dev/null +++ b/src/core/proto/message/message.ts @@ -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), +} diff --git a/src/core/proto/oidb/Oidb.ed3_1.ts b/src/core/proto/oidb/Oidb.ed3_1.ts index 355ea6af..704cb2bb 100644 --- a/src/core/proto/oidb/Oidb.ed3_1.ts +++ b/src/core/proto/oidb/Oidb.ed3_1.ts @@ -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) -} \ No newline at end of file + groupUin: ProtoField(2, ScalarType.UINT32), + friendUin: ProtoField(5, ScalarType.UINT32), + ext: ProtoField(6, ScalarType.UINT32, true) +} diff --git a/src/core/proto/oidb/Oidb.fe1_2.ts b/src/core/proto/oidb/Oidb.fe1_2.ts index 0b2586e1..ee05eedd 100644 --- a/src/core/proto/oidb/Oidb.fe1_2.ts +++ b/src/core/proto/oidb/Oidb.fe1_2.ts @@ -1,8 +1,12 @@ -import { ScalarType } from "@protobuf-ts/runtime"; -import { ProtoField } from "../NapProto"; +import {ScalarType} from "@protobuf-ts/runtime"; +import {ProtoField} from "../NapProto"; +export const OidbSvcTrpcTcp0XFE1_2 = { + uid: ProtoField(1, ScalarType.STRING, true), + field2: ProtoField(2, ScalarType.UINT32), + key: ProtoField(3, () => OidbSvcTrpcTcp0XFE1_2Key, false, true), +} -export const OidbSvcTrpcTcp0XEE1_2 = { - uin: ProtoField(1, ScalarType.UINT32), - key: ProtoField(3, ScalarType.BYTES, false, true), -} \ No newline at end of file +export const OidbSvcTrpcTcp0XFE1_2Key = { + key: ProtoField(1, ScalarType.UINT32) +} diff --git a/src/core/proto/oidb/OidbBase.ts b/src/core/proto/oidb/OidbBase.ts index ac6538ee..67162a71 100644 --- a/src/core/proto/oidb/OidbBase.ts +++ b/src/core/proto/oidb/OidbBase.ts @@ -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) -} \ No newline at end of file + errorMsg: ProtoField(5, ScalarType.STRING), + isReserved: ProtoField(12, ScalarType.UINT32) +} diff --git a/src/core/proto/oidb/common/Ntv2.RichMedia.ts b/src/core/proto/oidb/common/Ntv2.RichMedia.ts index cea03121..0482f0e8 100644 --- a/src/core/proto/oidb/common/Ntv2.RichMedia.ts +++ b/src/core/proto/oidb/common/Ntv2.RichMedia.ts @@ -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), @@ -81,4 +80,4 @@ export const VideoExtInfo = { } export const MsgInfo = { -} \ No newline at end of file +}