SnowLuma v2.4.2 source snapshot
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
This commit is contained in:
commit
fa9c73363d
1367 files changed
+355735
No files matched your search
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"name": "@snowluma/proto-defs",
|
||||
"version": "2.4.2",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "SnowLuma QQ/Lagrange wire-protobuf type definitions. Pure TypeScript interfaces with proton's `pb<N, T>` marker types — `@snowluma/proton`'s vite plugin compiles them into zero-runtime encoder/decoder functions at the call sites in `@snowluma/core` (and any downstream consumer). Exposed as per-file subpaths (`@snowluma/proto-defs/oidb`, `@snowluma/proto-defs/message`, …) so the import-site shape mirrors the legacy `bridge/proto/proton/*` layout and avoids name collisions across files (notably `highway.ts` and `oidb-actions/media.ts` share NTV2-prefixed names).",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./src/index.ts"
|
||||
},
|
||||
"./action": {
|
||||
"types": "./src/action.ts",
|
||||
"default": "./src/action.ts"
|
||||
},
|
||||
"./collection": {
|
||||
"types": "./src/collection.ts",
|
||||
"default": "./src/collection.ts"
|
||||
},
|
||||
"./qzone": {
|
||||
"types": "./src/qzone.ts",
|
||||
"default": "./src/qzone.ts"
|
||||
},
|
||||
"./dataline": {
|
||||
"types": "./src/dataline.ts",
|
||||
"default": "./src/dataline.ts"
|
||||
},
|
||||
"./element": {
|
||||
"types": "./src/element.ts",
|
||||
"default": "./src/element.ts"
|
||||
},
|
||||
"./highway": {
|
||||
"types": "./src/highway.ts",
|
||||
"default": "./src/highway.ts"
|
||||
},
|
||||
"./longmsg": {
|
||||
"types": "./src/longmsg.ts",
|
||||
"default": "./src/longmsg.ts"
|
||||
},
|
||||
"./message": {
|
||||
"types": "./src/message.ts",
|
||||
"default": "./src/message.ts"
|
||||
},
|
||||
"./get-group-msg": {
|
||||
"types": "./src/get-group-msg.ts",
|
||||
"default": "./src/get-group-msg.ts"
|
||||
},
|
||||
"./get-c2c-msg": {
|
||||
"types": "./src/get-c2c-msg.ts",
|
||||
"default": "./src/get-c2c-msg.ts"
|
||||
},
|
||||
"./qidian-corp": {
|
||||
"types": "./src/qidian-corp.ts",
|
||||
"default": "./src/qidian-corp.ts"
|
||||
},
|
||||
"./notify": {
|
||||
"types": "./src/notify.ts",
|
||||
"default": "./src/notify.ts"
|
||||
},
|
||||
"./ptt-trans": {
|
||||
"types": "./src/ptt-trans.ts",
|
||||
"default": "./src/ptt-trans.ts"
|
||||
},
|
||||
"./oidb": {
|
||||
"types": "./src/oidb.ts",
|
||||
"default": "./src/oidb.ts"
|
||||
},
|
||||
"./oidb-action": {
|
||||
"types": "./src/oidb-action.ts",
|
||||
"default": "./src/oidb-action.ts"
|
||||
},
|
||||
"./oidb-actions/*": {
|
||||
"types": "./src/oidb-actions/*.ts",
|
||||
"default": "./src/oidb-actions/*.ts"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@snowluma/proton": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^24.22.1 || >=26.12.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bytes } from '@snowluma/proton';
|
||||
import type { Elem } from './element';
|
||||
|
||||
// Routing
|
||||
export interface RoutingC2C {
|
||||
uin?: pb<1, uint_32>;
|
||||
uid?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface RoutingGroup {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
}
|
||||
|
||||
// 服务器限制 C2C 文件消息必须使用 Trans0x211 路由头(RoutingHead 字段 15)
|
||||
// 若误用常规 RoutingC2C 会被服务器拒绝。
|
||||
// 仅在包含 FileEntity 时触发,且 CcCmd 固定为 4。
|
||||
|
||||
export interface RoutingTrans0x211 {
|
||||
toUin?: pb<1, uint_64>;
|
||||
ccCmd?: pb<2, uint_32>;
|
||||
uid?: pb<8, string>;
|
||||
}
|
||||
|
||||
// Group temp-session routing head — RoutingHead field 3. Inner shape
|
||||
// { 群号 (source group), 对端 uid }.
|
||||
export interface RoutingGrpTmp {
|
||||
groupUin?: pb<3, uint_64>;
|
||||
toUid?: pb<4, string>;
|
||||
}
|
||||
|
||||
export interface RoutingHead {
|
||||
c2c?: pb<1, RoutingC2C>;
|
||||
grp?: pb<2, RoutingGroup>;
|
||||
grpTmp?: pb<3, RoutingGrpTmp>;
|
||||
trans0x211?: pb<15, RoutingTrans0x211>;
|
||||
}
|
||||
|
||||
// Content Head for send
|
||||
export interface SendContentHead {
|
||||
type?: pb<1, uint_32>;
|
||||
subType?: pb<2, uint_32>;
|
||||
c2cCmd?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
// Message Control
|
||||
export interface MessageControl {
|
||||
msgFlag?: pb<1, int_32>;
|
||||
}
|
||||
|
||||
// RichText for outgoing message elements.
|
||||
export interface SendRichText {
|
||||
elems?: pb_repeated<2, Elem>;
|
||||
}
|
||||
|
||||
// MessageBody (for send)
|
||||
export interface SendMessageBody<TRichText = SendRichText> {
|
||||
richText?: pb<1, TRichText>;
|
||||
// C2C 离线文件元数据(NotOnlineFile)必须序列化后塞入此字段
|
||||
// 服务器不会读取 richText.notOnlineFile。
|
||||
msgContent?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
// SendMessageRequest
|
||||
export interface SendMessageRequest<TRichText = SendRichText> {
|
||||
routingHead?: pb<1, RoutingHead>;
|
||||
contentHead?: pb<2, SendContentHead>;
|
||||
messageBody?: pb<3, SendMessageBody<TRichText>>;
|
||||
clientSequence?: pb<4, uint_32>;
|
||||
random?: pb<5, uint_32>;
|
||||
syncCookie?: pb<6, bytes>;
|
||||
via?: pb<8, uint_32>;
|
||||
dataStatist?: pb<9, uint_32>;
|
||||
ctrl?: pb<12, MessageControl>;
|
||||
multiSendSeq?: pb<14, uint_32>;
|
||||
}
|
||||
|
||||
// SendMessageResponse
|
||||
export interface SendMessageResponse {
|
||||
result?: pb<1, int_32>;
|
||||
errMsg?: pb<2, string>;
|
||||
timestamp1?: pb<3, uint_32>;
|
||||
reviewResult?: pb<6, int_32>;
|
||||
serverResult?: pb<7, SendMessageServerResult>;
|
||||
field10?: pb<10, uint_32>;
|
||||
groupSequence?: pb<11, uint_32>;
|
||||
timestamp2?: pb<12, uint_32>;
|
||||
privateSequence?: pb<14, uint_32>;
|
||||
}
|
||||
|
||||
export interface SendMessageServerResult {
|
||||
type?: pb<1, int_32>;
|
||||
code?: pb<2, int_32>;
|
||||
message?: pb<3, string>;
|
||||
}
|
||||
|
||||
// MentionExtra (for building @mention text element)
|
||||
export interface MentionExtraSend {
|
||||
type?: pb<3, int_32>;
|
||||
uin?: pb<4, uint_32>;
|
||||
field5?: pb<5, int_32>;
|
||||
uid?: pb<9, string>;
|
||||
}
|
||||
|
||||
// Markdown commonElem (svc=45). Official DecodeMarkdownElement reads
|
||||
// content / process_msg / summary / extType / mdExtInfo.
|
||||
// extType=1 dispatches to DecodeMdExtInfoFileTransfer.
|
||||
/** extInfo.thumbnail — cover download info, not raw image bytes. */
|
||||
export interface MarkdownFlashTransferThumbUrl {
|
||||
field1?: pb<1, uint_32>;
|
||||
downloadUrl?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface MarkdownFlashTransferThumb {
|
||||
fileId?: pb<1, string>;
|
||||
download?: pb<2, MarkdownFlashTransferThumbUrl>;
|
||||
sha1?: pb<3, string>;
|
||||
field4?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface MarkdownFlashTransferExt {
|
||||
filesetId?: pb<1, string>;
|
||||
name?: pb<2, string>;
|
||||
fileSize?: pb<3, uint_32>;
|
||||
thumbnail?: pb<4, MarkdownFlashTransferThumb>;
|
||||
expireTime?: pb<6, uint_32>;
|
||||
}
|
||||
|
||||
export interface MarkdownData {
|
||||
content?: pb<1, string>;
|
||||
field2?: pb<2, string>;
|
||||
field3?: pb<3, bytes>;
|
||||
processMsg?: pb<4, string>;
|
||||
summary?: pb<5, string>;
|
||||
extType?: pb<6, uint_32>;
|
||||
extInfo?: pb<7, MarkdownFlashTransferExt>;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
import type {
|
||||
bool,
|
||||
bytes,
|
||||
double,
|
||||
int_32,
|
||||
pb,
|
||||
pb_repeated,
|
||||
uint_32,
|
||||
uint_64,
|
||||
} from '@snowluma/proton';
|
||||
|
||||
/** Weiyun collector common request header. */
|
||||
export interface CollectionRequestHead {
|
||||
uin?: pb<1, uint_64>;
|
||||
sequence?: pb<2, uint_32>;
|
||||
commandType?: pb<3, uint_32>;
|
||||
operationId?: pb<4, uint_32>;
|
||||
clientVersion?: pb<5, uint_64>;
|
||||
platform?: pb<6, uint_32>;
|
||||
ticketType?: pb<7, uint_32>;
|
||||
reserved?: pb<10, uint_32>;
|
||||
ticket?: pb<11, string>;
|
||||
field14?: pb<14, uint_32>;
|
||||
field15?: pb<15, uint_32>;
|
||||
}
|
||||
|
||||
/** Weiyun collector common response header. */
|
||||
export interface CollectionResponseHead {
|
||||
retCode?: pb<101, int_32>;
|
||||
retMsg?: pb<102, string>;
|
||||
promptMsg?: pb<103, string>;
|
||||
}
|
||||
|
||||
export interface GetCollectionListRequest {
|
||||
field1?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
timeStamp?: pb<4, uint_64>;
|
||||
orderType?: pb<5, uint_32>;
|
||||
groupId?: pb<6, uint_64>;
|
||||
count?: pb<7, uint_32>;
|
||||
searchDown?: pb<8, uint_32>;
|
||||
field9?: pb<9, uint_32>;
|
||||
}
|
||||
|
||||
export interface CollectionRequestOperation {
|
||||
getCollectionList?: pb<20000, GetCollectionListRequest>;
|
||||
}
|
||||
|
||||
export interface CollectionRequestBody {
|
||||
operation?: pb<1, CollectionRequestOperation>;
|
||||
}
|
||||
|
||||
export interface CollectionAuthor {
|
||||
type?: pb<1, uint_32>;
|
||||
numId?: pb<2, uint_64>;
|
||||
strId?: pb<3, string>;
|
||||
groupId?: pb<4, uint_64>;
|
||||
groupName?: pb<5, string>;
|
||||
uid?: pb<6, string>;
|
||||
}
|
||||
|
||||
export interface CollectionPictureInfo {
|
||||
url?: pb<1, string>;
|
||||
field2?: pb<2, bytes>;
|
||||
field3?: pb<3, bytes>;
|
||||
field4?: pb<4, string>;
|
||||
field5?: pb<5, string>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, uint_32>;
|
||||
field8?: pb<8, uint_32>;
|
||||
field9?: pb<9, uint_32>;
|
||||
author?: pb<10, CollectionAuthor>;
|
||||
field11?: pb<11, string>;
|
||||
}
|
||||
|
||||
export interface CollectionFileInfo {
|
||||
field1?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_64>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, string>;
|
||||
field5?: pb<5, string>;
|
||||
field6?: pb<6, uint_64>;
|
||||
field7?: pb<7, bytes>;
|
||||
field8?: pb<8, bytes>;
|
||||
field9?: pb<9, uint_32>;
|
||||
field10?: pb<10, string>;
|
||||
}
|
||||
|
||||
export interface CollectionTextSummary {
|
||||
text?: pb<1, string>;
|
||||
truncated?: pb<2, bool>;
|
||||
}
|
||||
|
||||
export interface CollectionRichMediaSummary {
|
||||
title?: pb<1, string>;
|
||||
subTitle?: pb<2, string>;
|
||||
brief?: pb<3, string>;
|
||||
picList?: pb_repeated<4, CollectionPictureInfo>;
|
||||
contentType?: pb<5, uint_32>;
|
||||
originalUri?: pb<6, string>;
|
||||
publisher?: pb<7, string>;
|
||||
richMediaVersion?: pb<8, uint_32>;
|
||||
}
|
||||
|
||||
export interface CollectionGallerySummary {
|
||||
picList?: pb_repeated<1, CollectionPictureInfo>;
|
||||
field2?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface CollectionAudioSummary {
|
||||
field1?: pb<1, uint_32>;
|
||||
field2?: pb<2, string>;
|
||||
field3?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface CollectionVideoSummary {
|
||||
field1?: pb<1, string>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field10?: pb<10, uint_32>;
|
||||
field20?: pb<20, uint_32>;
|
||||
picture?: pb<21, CollectionPictureInfo>;
|
||||
field30?: pb<30, uint_32>;
|
||||
file?: pb<31, CollectionFileInfo>;
|
||||
}
|
||||
|
||||
export interface CollectionFileSummary {
|
||||
first?: pb<1, CollectionFileInfo>;
|
||||
second?: pb<2, CollectionFileInfo>;
|
||||
}
|
||||
|
||||
export interface CollectionLocationSummary {
|
||||
name?: pb<1, string>;
|
||||
latitude?: pb<2, double>;
|
||||
longitude?: pb<3, double>;
|
||||
altitude?: pb<4, double>;
|
||||
field5?: pb<5, string>;
|
||||
field6?: pb<6, string>;
|
||||
}
|
||||
|
||||
export interface CollectionLinkSummary {
|
||||
url?: pb<1, string>;
|
||||
title?: pb<2, string>;
|
||||
publisher?: pb<3, string>;
|
||||
brief?: pb<4, string>;
|
||||
picList?: pb_repeated<5, CollectionPictureInfo>;
|
||||
contentType?: pb<6, uint_32>;
|
||||
field7?: pb<7, string>;
|
||||
}
|
||||
|
||||
export interface CollectionSummary {
|
||||
textSummary?: pb<1, CollectionTextSummary>;
|
||||
linkSummary?: pb<2, CollectionLinkSummary>;
|
||||
gallerySummary?: pb<3, CollectionGallerySummary>;
|
||||
audioSummary?: pb<4, CollectionAudioSummary>;
|
||||
videoSummary?: pb<5, CollectionVideoSummary>;
|
||||
fileSummary?: pb<6, CollectionFileSummary>;
|
||||
locationSummary?: pb<7, CollectionLocationSummary>;
|
||||
richMediaSummary?: pb<8, CollectionRichMediaSummary>;
|
||||
}
|
||||
|
||||
export interface CollectionItem {
|
||||
cid?: pb<1, string>;
|
||||
type?: pb<2, uint_32>;
|
||||
status?: pb<3, uint_32>;
|
||||
author?: pb<4, CollectionAuthor>;
|
||||
bid?: pb<5, uint_32>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, string>;
|
||||
category?: pb<8, uint_32>;
|
||||
createTime?: pb<9, uint_64>;
|
||||
collectTime?: pb<10, uint_64>;
|
||||
modifyTime?: pb<11, uint_64>;
|
||||
sequence?: pb<12, uint_64>;
|
||||
field13?: pb<13, string>;
|
||||
field14?: pb_repeated<14, string>;
|
||||
summary?: pb<15, CollectionSummary>;
|
||||
field16?: pb<16, bool>;
|
||||
field17?: pb<17, uint_64>;
|
||||
shareUrl?: pb<18, string>;
|
||||
field19?: pb<19, uint_32>;
|
||||
customGroupId?: pb<20, uint_32>;
|
||||
securityBeat?: pb<21, bool>;
|
||||
field506?: pb<506, string>;
|
||||
}
|
||||
|
||||
export interface GetCollectionListResponse {
|
||||
items?: pb_repeated<1, CollectionItem>;
|
||||
totalCount?: pb<2, uint_32>;
|
||||
reachedBottom?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
export interface CollectionResponseOperation {
|
||||
getCollectionList?: pb<20000, GetCollectionListResponse>;
|
||||
}
|
||||
|
||||
export interface CollectionResponseBody {
|
||||
operation?: pb<2, CollectionResponseOperation>;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { pb, pb_repeated, uint_32, uint_64, bytes } from '@snowluma/proton';
|
||||
|
||||
/** Header identifying the source/destination device on a my-device chat. */
|
||||
export interface DatalineMsgHeader {
|
||||
srcAppId?: pb<1, uint_32>;
|
||||
srcInstId?: pb<2, uint_32>;
|
||||
dstAppId?: pb<3, uint_32>;
|
||||
dstInstId?: pb<4, uint_32>;
|
||||
dstUin?: pb<5, uint_64>;
|
||||
srcUin?: pb<6, uint_64>;
|
||||
srcUinType?: pb<7, uint_32>;
|
||||
dstUinType?: pb<8, uint_32>;
|
||||
srcTerType?: pb<9, uint_32>;
|
||||
dstTerType?: pb<10, uint_32>;
|
||||
}
|
||||
|
||||
/** File notify carried on a my-device transfer. */
|
||||
export interface DatalineFtnNotify {
|
||||
sessionId?: pb<1, uint_64>;
|
||||
fileName?: pb<2, string>;
|
||||
fileIndex?: pb<3, string>;
|
||||
fileMd5?: pb<4, bytes>;
|
||||
fileKey?: pb<5, string>;
|
||||
fileLen?: pb<6, uint_64>;
|
||||
}
|
||||
|
||||
/** Generic my-device command; text lives in `buf`. */
|
||||
export interface DatalineGenericSubCmd {
|
||||
sessionId?: pb<1, uint_64>;
|
||||
size?: pb<2, uint_32>;
|
||||
index?: pb<3, uint_32>;
|
||||
type?: pb<4, uint_32>;
|
||||
buf?: pb<5, bytes>;
|
||||
}
|
||||
|
||||
export interface DatalineTextItem {
|
||||
type?: pb<1, uint_32>;
|
||||
text?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface DatalineTextMsg {
|
||||
items?: pb_repeated<1, DatalineTextItem>;
|
||||
}
|
||||
|
||||
export interface DatalineMsgBody {
|
||||
subCmd?: pb<1, uint_32>;
|
||||
header?: pb<2, DatalineMsgHeader>;
|
||||
ftn?: pb_repeated<3, DatalineFtnNotify>;
|
||||
generic?: pb<6, DatalineGenericSubCmd>;
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bool, bytes } from '@snowluma/proton';
|
||||
|
||||
// Nested / helper schemas
|
||||
export interface CustomFacePbReserve {
|
||||
subType?: pb<1, int_32>;
|
||||
summary?: pb<9, string>;
|
||||
}
|
||||
|
||||
export interface NotOnlineImagePbReserve2 {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, string>;
|
||||
field3?: pb<3, int_32>;
|
||||
field4?: pb<4, int_32>;
|
||||
field5?: pb<5, int_32>;
|
||||
field7?: pb<7, string>;
|
||||
}
|
||||
|
||||
export interface NotOnlineImagePbReserve {
|
||||
subType?: pb<1, int_32>;
|
||||
field3?: pb<3, int_32>;
|
||||
field4?: pb<4, int_32>;
|
||||
summary?: pb<8, string>;
|
||||
field10?: pb<10, int_32>;
|
||||
field20?: pb<20, NotOnlineImagePbReserve2>;
|
||||
url?: pb<30, string>;
|
||||
md5Str?: pb<31, string>;
|
||||
}
|
||||
|
||||
// Core element schemas
|
||||
export interface TextElem {
|
||||
str?: pb<1, string>;
|
||||
link?: pb<2, string>;
|
||||
attr6Buf?: pb<3, bytes>;
|
||||
attr7Buf?: pb<4, bytes>;
|
||||
buf?: pb<11, bytes>;
|
||||
pbReserve?: pb<12, bytes>;
|
||||
}
|
||||
|
||||
export interface FaceElem {
|
||||
index?: pb<1, int_32>;
|
||||
oldData?: pb<2, bytes>;
|
||||
buf?: pb<11, bytes>;
|
||||
}
|
||||
|
||||
export interface OnlineImage {
|
||||
guid?: pb<1, bytes>;
|
||||
filePath?: pb<2, bytes>;
|
||||
oldVerSendFile?: pb<3, bytes>;
|
||||
}
|
||||
|
||||
export interface NotOnlineImage {
|
||||
filePath?: pb<1, string>;
|
||||
fileLen?: pb<2, uint_32>;
|
||||
downloadPath?: pb<3, string>;
|
||||
oldVerSendFile?: pb<4, bytes>;
|
||||
imgType?: pb<5, int_32>;
|
||||
previewsImage?: pb<6, bytes>;
|
||||
picMd5?: pb<7, bytes>;
|
||||
picHeight?: pb<8, uint_32>;
|
||||
picWidth?: pb<9, uint_32>;
|
||||
resId?: pb<10, string>;
|
||||
flag?: pb<11, bytes>;
|
||||
thumbUrl?: pb<12, string>;
|
||||
original?: pb<13, int_32>;
|
||||
bigUrl?: pb<14, string>;
|
||||
origUrl?: pb<15, string>;
|
||||
bizType?: pb<16, int_32>;
|
||||
result?: pb<17, int_32>;
|
||||
index?: pb<18, int_32>;
|
||||
opFaceBuf?: pb<19, bytes>;
|
||||
oldPicMd5?: pb<20, bool>;
|
||||
thumbWidth?: pb<21, int_32>;
|
||||
thumbHeight?: pb<22, int_32>;
|
||||
fileId?: pb<23, int_32>;
|
||||
showLen?: pb<24, uint_32>;
|
||||
downloadLen?: pb<25, uint_32>;
|
||||
x400Url?: pb<26, string>;
|
||||
x400Width?: pb<27, int_32>;
|
||||
x400Height?: pb<28, int_32>;
|
||||
pbRes?: pb<29, NotOnlineImagePbReserve>;
|
||||
}
|
||||
|
||||
export interface TransElem {
|
||||
elemType?: pb<1, int_32>;
|
||||
elemValue?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
// MarketFace.pbReserve(13) inner message. NapCat/Lagrange set field8=1 on
|
||||
// send (marks the sticker as a "magic"/animated face). We encode it via
|
||||
// protobuf_encode<MarketFacePbReserve> into the bytes field — same pattern as
|
||||
// the mention pbReserve in element-builder.makeMentionElem.
|
||||
export interface MarketFacePbReserve {
|
||||
field8?: pb<8, uint_32>;
|
||||
}
|
||||
|
||||
export interface MarketFace {
|
||||
faceName?: pb<1, string>;
|
||||
itemType?: pb<2, uint_32>;
|
||||
faceInfo?: pb<3, uint_32>;
|
||||
faceId?: pb<4, bytes>;
|
||||
tabId?: pb<5, uint_32>;
|
||||
subType?: pb<6, uint_32>;
|
||||
// `key` is a short ASCII token (e.g. "0"); Lagrange.Core and NapCat both
|
||||
// type it as a string. Kept as string so it round-trips verbatim through
|
||||
// the receive→`emoji_id` marker→re-send path without a bytes/utf8 hop.
|
||||
key?: pb<7, string>;
|
||||
param?: pb<8, bytes>;
|
||||
mediaType?: pb<9, uint_32>;
|
||||
imageWidth?: pb<10, uint_32>;
|
||||
imageHeight?: pb<11, uint_32>;
|
||||
mobileParam?: pb<12, bytes>;
|
||||
pbReserve?: pb<13, bytes>;
|
||||
}
|
||||
|
||||
export interface CustomFace {
|
||||
guid?: pb<1, bytes>;
|
||||
filePath?: pb<2, string>;
|
||||
shortcut?: pb<3, string>;
|
||||
buffer?: pb<4, bytes>;
|
||||
flag?: pb<5, bytes>;
|
||||
oldData?: pb<6, bytes>;
|
||||
fileId?: pb<7, uint_32>;
|
||||
serverIp?: pb<8, int_32>;
|
||||
serverPort?: pb<9, int_32>;
|
||||
fileType?: pb<10, int_32>;
|
||||
signature?: pb<11, bytes>;
|
||||
useful?: pb<12, int_32>;
|
||||
md5?: pb<13, bytes>;
|
||||
thumbUrl?: pb<14, string>;
|
||||
bigUrl?: pb<15, string>;
|
||||
origUrl?: pb<16, string>;
|
||||
bizType?: pb<17, int_32>;
|
||||
repeatIndex?: pb<18, int_32>;
|
||||
repeatImage?: pb<19, int_32>;
|
||||
imageType?: pb<20, int_32>;
|
||||
index?: pb<21, int_32>;
|
||||
width?: pb<22, int_32>;
|
||||
height?: pb<23, int_32>;
|
||||
source?: pb<24, int_32>;
|
||||
size?: pb<25, uint_32>;
|
||||
origin?: pb<26, int_32>;
|
||||
thumbWidth?: pb<27, int_32>;
|
||||
thumbHeight?: pb<28, int_32>;
|
||||
showLen?: pb<29, int_32>;
|
||||
downloadLen?: pb<30, int_32>;
|
||||
x400Url?: pb<31, string>;
|
||||
x400Width?: pb<32, int_32>;
|
||||
x400Height?: pb<33, int_32>;
|
||||
pbRes?: pb<34, CustomFacePbReserve>;
|
||||
}
|
||||
|
||||
export interface RichMsg {
|
||||
template1?: pb<1, bytes>;
|
||||
serviceId?: pb<2, int_32>;
|
||||
msgResId?: pb<3, bytes>;
|
||||
rand?: pb<4, int_32>;
|
||||
seq?: pb<5, uint_32>;
|
||||
}
|
||||
|
||||
export interface GroupFileElem {
|
||||
filename?: pb<1, string>;
|
||||
fileSize?: pb<2, uint_64>;
|
||||
fileId?: pb<3, string>;
|
||||
batchId?: pb<4, string>;
|
||||
fileKey?: pb<5, string>;
|
||||
mark?: pb<6, bytes>;
|
||||
sequence?: pb<7, uint_64>;
|
||||
batchItemId?: pb<8, bytes>;
|
||||
feedMsgTime?: pb<9, int_32>;
|
||||
pbReserve?: pb<10, bytes>;
|
||||
}
|
||||
|
||||
export interface ExtraInfo {
|
||||
nick?: pb<1, bytes>;
|
||||
groupCard?: pb<2, bytes>;
|
||||
level?: pb<3, int_32>;
|
||||
flags?: pb<4, int_32>;
|
||||
groupMask?: pb<5, int_32>;
|
||||
msgTailId?: pb<6, int_32>;
|
||||
senderTitle?: pb<7, bytes>;
|
||||
apnsTips?: pb<8, bytes>;
|
||||
uin?: pb<9, uint_64>;
|
||||
msgStateFlag?: pb<10, int_32>;
|
||||
apnsSoundType?: pb<11, int_32>;
|
||||
newGroupFlag?: pb<12, int_32>;
|
||||
}
|
||||
|
||||
export interface VideoFile {
|
||||
fileUuid?: pb<1, string>;
|
||||
fileMd5?: pb<2, bytes>;
|
||||
fileName?: pb<3, string>;
|
||||
fileFormat?: pb<4, int_32>;
|
||||
fileTime?: pb<5, int_32>;
|
||||
fileSize?: pb<6, int_32>;
|
||||
thumbWidth?: pb<7, int_32>;
|
||||
thumbHeight?: pb<8, int_32>;
|
||||
thumbFileMd5?: pb<9, bytes>;
|
||||
source?: pb<10, bytes>;
|
||||
thumbFileSize?: pb<11, int_32>;
|
||||
busiType?: pb<12, int_32>;
|
||||
fromChatType?: pb<13, int_32>;
|
||||
toChatType?: pb<14, int_32>;
|
||||
supportProgressive?: pb<15, bool>;
|
||||
fileWidth?: pb<16, int_32>;
|
||||
fileHeight?: pb<17, int_32>;
|
||||
subBusiType?: pb<18, int_32>;
|
||||
videoAttr?: pb<19, int_32>;
|
||||
pbReserve?: pb<24, bytes>;
|
||||
}
|
||||
|
||||
export interface SrcMsg {
|
||||
origSeqs?: pb_repeated<1, uint_32>;
|
||||
senderUin?: pb<2, uint_64>;
|
||||
time?: pb<3, int_32>;
|
||||
flag?: pb<4, int_32>;
|
||||
elemsRaw?: pb_repeated<5, bytes>;
|
||||
type?: pb<6, int_32>;
|
||||
richMsg?: pb<7, bytes>;
|
||||
pbReserve?: pb<8, bytes>;
|
||||
sourceMsg?: pb<9, bytes>;
|
||||
toUin?: pb<10, uint_64>;
|
||||
troopName?: pb<11, bytes>;
|
||||
}
|
||||
|
||||
// Decoded content of SrcMsg.pbReserve(8). `friendSequence` is a friendship-side
|
||||
// counter observed in QQNT, not the conversation-wide C2C NT message sequence;
|
||||
// private reply resolution therefore uses SrcMsg.origSeqs plus direction/time.
|
||||
export interface SrcMsgPbReserve {
|
||||
receiverUid?: pb<7, string>;
|
||||
friendSequence?: pb<8, uint_32>;
|
||||
}
|
||||
|
||||
export interface LightAppElem {
|
||||
data?: pb<1, bytes>;
|
||||
msgResid?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface CommonElem {
|
||||
serviceType?: pb<1, int_32>;
|
||||
pbElem?: pb<2, bytes>;
|
||||
businessType?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
/** CommonElem services 46/50/51, business type 1. */
|
||||
export interface InlineKeyboardPermission {
|
||||
type?: pb<1, uint_32>;
|
||||
specifyRoleIds?: pb_repeated<2, string>;
|
||||
specifyUserIds?: pb_repeated<3, string>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardAction {
|
||||
type?: pb<1, uint_32>;
|
||||
permission?: pb<2, InlineKeyboardPermission>;
|
||||
clickLimit?: pb<3, uint_32>;
|
||||
unsupportedTips?: pb<4, string>;
|
||||
data?: pb<5, string>;
|
||||
atBotShowChannelList?: pb<6, bool>;
|
||||
reply?: pb<7, bool>;
|
||||
enter?: pb<8, bool>;
|
||||
anchor?: pb<9, uint_32>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardRenderData {
|
||||
label?: pb<1, string>;
|
||||
visitedLabel?: pb<2, string>;
|
||||
style?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardButton {
|
||||
id?: pb<1, string>;
|
||||
renderData?: pb<2, InlineKeyboardRenderData>;
|
||||
action?: pb<3, InlineKeyboardAction>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardRow {
|
||||
buttons?: pb_repeated<1, InlineKeyboardButton>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardData {
|
||||
rows?: pb_repeated<1, InlineKeyboardRow>;
|
||||
botAppid?: pb<2, uint_64>;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardExtra {
|
||||
keyboard?: pb<1, InlineKeyboardData>;
|
||||
}
|
||||
|
||||
/** Payload carried by CommonElem serviceType=2 for private window shakes. */
|
||||
export interface PokeExtra {
|
||||
type?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface GeneralFlags {
|
||||
bubbleDiyTextId?: pb<1, int_32>;
|
||||
groupFlagNew?: pb<2, int_32>;
|
||||
uin?: pb<3, uint_64>;
|
||||
longTextFlag?: pb<6, int_32>;
|
||||
longTextResId?: pb<7, string>;
|
||||
}
|
||||
|
||||
// Elem (union of all element types)
|
||||
|
||||
export interface Elem {
|
||||
text?: pb<1, TextElem>;
|
||||
face?: pb<2, FaceElem>;
|
||||
onlineImage?: pb<3, OnlineImage>;
|
||||
notOnlineImage?: pb<4, NotOnlineImage>;
|
||||
transElem?: pb<5, TransElem>;
|
||||
marketFace?: pb<6, MarketFace>;
|
||||
customFace?: pb<8, CustomFace>;
|
||||
richMsg?: pb<12, RichMsg>;
|
||||
groupFile?: pb<13, GroupFileElem>;
|
||||
extraInfo?: pb<16, ExtraInfo>;
|
||||
videoFile?: pb<19, VideoFile>;
|
||||
generalFlags?: pb<37, GeneralFlags>;
|
||||
srcMsg?: pb<45, SrcMsg>;
|
||||
lightApp?: pb<51, LightAppElem>;
|
||||
commonElem?: pb<53, CommonElem>;
|
||||
}
|
||||
|
||||
// Extra decode types (for CommonElem.pbElem sub-messages)
|
||||
|
||||
export interface MentionExtra {
|
||||
type?: pb<3, int_32>;
|
||||
uin?: pb<4, uint_32>;
|
||||
field5?: pb<5, int_32>;
|
||||
uid?: pb<9, string>;
|
||||
}
|
||||
|
||||
export interface QFaceExtra {
|
||||
packId?: pb<1, string>;
|
||||
stickerId?: pb<2, string>;
|
||||
qsid?: pb<3, int_32>;
|
||||
sourceType?: pb<4, int_32>;
|
||||
stickerType?: pb<5, int_32>;
|
||||
resultId?: pb<6, string>;
|
||||
text?: pb<7, string>;
|
||||
randomType?: pb<9, int_32>;
|
||||
}
|
||||
|
||||
export interface QSmallFaceExtra {
|
||||
faceId?: pb<1, uint_32>;
|
||||
preview?: pb<2, string>;
|
||||
preview2?: pb<3, string>;
|
||||
}
|
||||
|
||||
// NTQQ MsgInfo types (CommonElem service_type 48)
|
||||
|
||||
export interface FileType {
|
||||
type?: pb<1, uint_32>;
|
||||
picFormat?: pb<2, uint_32>;
|
||||
videoFormat?: pb<3, uint_32>;
|
||||
voiceFormat?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface FileInfo {
|
||||
fileSize?: pb<1, uint_32>;
|
||||
fileHash?: pb<2, string>;
|
||||
fileSha1?: pb<3, string>;
|
||||
fileName?: pb<4, string>;
|
||||
type?: pb<5, FileType>;
|
||||
width?: pb<6, uint_32>;
|
||||
height?: pb<7, uint_32>;
|
||||
time?: pb<8, uint_32>;
|
||||
original?: pb<9, uint_32>;
|
||||
}
|
||||
|
||||
export interface IndexNode {
|
||||
info?: pb<1, FileInfo>;
|
||||
fileUuid?: pb<2, string>;
|
||||
storeId?: pb<3, uint_32>;
|
||||
uploadTime?: pb<4, uint_32>;
|
||||
ttl?: pb<5, uint_32>;
|
||||
subType?: pb<6, uint_32>;
|
||||
}
|
||||
|
||||
export interface PicUrlExtInfo {
|
||||
originalParameter?: pb<1, string>;
|
||||
bigParameter?: pb<2, string>;
|
||||
thumbParameter?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface PictureInfo {
|
||||
urlPath?: pb<1, string>;
|
||||
ext?: pb<2, PicUrlExtInfo>;
|
||||
domain?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface PicExtData {
|
||||
subType?: pb<1, uint_32>;
|
||||
textSummary?: pb<9, string>;
|
||||
}
|
||||
|
||||
export interface PicExtBizInfo {
|
||||
bizType?: pb<1, uint_32>;
|
||||
textSummary?: pb<2, string>;
|
||||
bytesPbReserveC2c?: pb<11, bytes>;
|
||||
extData?: pb<12, PicExtData>;
|
||||
fromScene?: pb<1001, uint_32>;
|
||||
toScene?: pb<1002, uint_32>;
|
||||
oldFileId?: pb<1003, uint_32>;
|
||||
}
|
||||
|
||||
export interface VideoExtBizInfo {
|
||||
fromScene?: pb<1, uint_32>;
|
||||
toScene?: pb<2, uint_32>;
|
||||
bytesPbReserve?: pb<3, bytes>;
|
||||
}
|
||||
|
||||
/** Encoded payload of `PttExtBizInfo.waveform`. Count must equal amplitudes. */
|
||||
export interface PttWaveform {
|
||||
size?: pb<1, uint_32>;
|
||||
amplitudes?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface PttExtBizInfo {
|
||||
srcUin?: pb<1, uint_64>;
|
||||
pttScene?: pb<2, uint_32>;
|
||||
pttType?: pb<3, uint_32>;
|
||||
changeVoice?: pb<4, uint_32>;
|
||||
waveform?: pb<5, bytes>;
|
||||
autoConvertText?: pb<6, uint_32>;
|
||||
bytesReserve?: pb<11, bytes>;
|
||||
bytesPbReserve?: pb<12, bytes>;
|
||||
bytesGeneralFlags?: pb<13, bytes>;
|
||||
}
|
||||
|
||||
export interface ExtBizInfo {
|
||||
pic?: pb<1, PicExtBizInfo>;
|
||||
video?: pb<2, VideoExtBizInfo>;
|
||||
ptt?: pb<3, PttExtBizInfo>;
|
||||
busiType?: pb<10, uint_32>;
|
||||
}
|
||||
|
||||
export interface C2cSource {
|
||||
friendUid?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface TroopSource {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface HashSum {
|
||||
bytesPbReserveC2c?: pb<201, C2cSource>;
|
||||
troopSource?: pb<202, TroopSource>;
|
||||
}
|
||||
|
||||
export interface MsgInfoBody {
|
||||
index?: pb<1, IndexNode>;
|
||||
picture?: pb<2, PictureInfo>;
|
||||
fileExist?: pb<5, bool>;
|
||||
hashSum?: pb<6, HashSum>;
|
||||
}
|
||||
|
||||
export interface MsgInfo {
|
||||
msgInfoBody?: pb_repeated<1, MsgInfoBody>;
|
||||
extBizInfo?: pb<2, ExtBizInfo>;
|
||||
}
|
||||
|
||||
// 群文件附加信息 (TransElem type=24)
|
||||
// 旧版 Schema 字段 5-7 错位曾导致服务器返回 result=79 并拒收消息。
|
||||
// 字段 5 为 uint32 占位符。
|
||||
export interface GroupFileInfo {
|
||||
busId?: pb<1, uint_32>;
|
||||
fileId?: pb<2, string>;
|
||||
fileSize?: pb<3, uint_64>;
|
||||
fileName?: pb<4, string>;
|
||||
field5?: pb<5, uint_32>; // 关键:必须是 uint32 占位符,错位会导致 SHA 字节流污染此字段
|
||||
fileSha?: pb<6, bytes>;
|
||||
extInfoString?: pb<7, string>;
|
||||
fileMd5?: pb<8, bytes>;
|
||||
}
|
||||
|
||||
export interface GroupFileExtraInner {
|
||||
info?: pb<2, GroupFileInfo>;
|
||||
}
|
||||
|
||||
// 新版服务器强校验外层结构。缺少 field1 (Magic Tag)、fileName 或 display 槽位,消息将被直接拒绝。
|
||||
export interface GroupFileExtra {
|
||||
field1?: pb<1, uint_32>; // NapCat 硬编码固定为 6 (Magic Op Tag)
|
||||
fileName?: pb<2, string>; // 镜像同步内部的 info.fileName
|
||||
display?: pb<3, string>; // UI 预览槽位,可留空但必须声明
|
||||
inner?: pb<7, GroupFileExtraInner>;
|
||||
}
|
||||
|
||||
// 消息回执保留信息
|
||||
export interface Preserve {
|
||||
messageId?: pb<3, uint_64>;
|
||||
senderUid?: pb<6, string>;
|
||||
receiverUid?: pb<7, string>;
|
||||
clientSequence?: pb<8, uint_32>;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { pb, pb_repeated, uint_32, int_32, bool } from '@snowluma/proton';
|
||||
import type { PushMsgBody } from './message';
|
||||
|
||||
// trpc.msg.register_proxy.RegisterProxy.SsoGetC2cMsg — fetch private (c2c)
|
||||
// message history from the server by conversation-wide NT sequence range.
|
||||
// Reference: Lagrange.Core
|
||||
// Internal/Service/Message/GetC2cMessageService.cs + Packets/Message/Action/
|
||||
// SsoGetC2cMsg(.Response).cs. The peer is the friend's UID (not uin); the
|
||||
// response carries the same `PushMsgBody` shape as a live message.
|
||||
|
||||
export interface SsoGetC2cMsg {
|
||||
friendUid?: pb<2, string>;
|
||||
startSequence?: pb<3, uint_32>;
|
||||
endSequence?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface SsoGetC2cMsgResponse {
|
||||
result?: pb<1, int_32>;
|
||||
errorMessage?: pb<2, string>;
|
||||
friendUid?: pb<4, string>;
|
||||
messages?: pb_repeated<7, PushMsgBody>;
|
||||
}
|
||||
|
||||
// trpc.msg.register_proxy.RegisterProxy.SsoGetRoamMsg — fetch private
|
||||
// history before a timestamp cursor. This is QQ's latest-page C2C history
|
||||
// endpoint; unlike SsoGetC2cMsg it does not require a locally known sequence.
|
||||
export interface SsoGetRoamMsg {
|
||||
friendUid?: pb<1, string>;
|
||||
time?: pb<2, uint_32>;
|
||||
random?: pb<3, uint_32>;
|
||||
count?: pb<4, uint_32>;
|
||||
direction?: pb<5, bool>;
|
||||
}
|
||||
|
||||
export interface SsoGetRoamMsgResponse {
|
||||
result?: pb<1, uint_32>;
|
||||
errorMessage?: pb<2, string>;
|
||||
friendUid?: pb<3, string>;
|
||||
isComplete?: pb<4, bool>;
|
||||
timestamp?: pb<5, uint_32>;
|
||||
random?: pb<6, uint_32>;
|
||||
messages?: pb_repeated<7, PushMsgBody>;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { pb, pb_repeated, uint_32, bool } from '@snowluma/proton';
|
||||
import type { PushMsgBody } from './message';
|
||||
|
||||
// trpc.msg.register_proxy.RegisterProxy.SsoGetGroupMsg — fetch group message
|
||||
// history from the server by sequence range. Reference: Lagrange.Core
|
||||
// Internal/Service/Message/GetGroupMessageService.cs + Packets/Message/Action/
|
||||
// SsoGetGroupMsg(.Response).cs. The response carries the same `PushMsgBody`
|
||||
// shape as a live OlPush message, so the existing msg-push decoders parse it.
|
||||
|
||||
export interface SsoGetGroupMsgInfo {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
startSequence?: pb<2, uint_32>;
|
||||
endSequence?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
export interface SsoGetGroupMsg {
|
||||
info?: pb<1, SsoGetGroupMsgInfo>;
|
||||
direction?: pb<2, bool>; // true (Lagrange hard-codes this)
|
||||
}
|
||||
|
||||
export interface SsoGetGroupMsgResponseBody {
|
||||
groupUin?: pb<3, uint_32>;
|
||||
startSequence?: pb<4, uint_32>;
|
||||
endSequence?: pb<5, uint_32>;
|
||||
messages?: pb_repeated<6, PushMsgBody>;
|
||||
}
|
||||
|
||||
export interface SsoGetGroupMsgResponse {
|
||||
body?: pb<3, SsoGetGroupMsgResponseBody>;
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
import type {
|
||||
pb,
|
||||
pb_repeated,
|
||||
int_32,
|
||||
uint_32,
|
||||
uint_64,
|
||||
fixed_32,
|
||||
bool,
|
||||
bytes,
|
||||
} from '@snowluma/proton';
|
||||
import type {
|
||||
IndexNode,
|
||||
PictureInfo,
|
||||
HashSum,
|
||||
PicExtBizInfo,
|
||||
VideoExtBizInfo,
|
||||
PttExtBizInfo,
|
||||
} from './element';
|
||||
|
||||
// DataHighwayHead
|
||||
|
||||
export interface DataHighwayHead {
|
||||
version?: pb<1, uint_32>;
|
||||
uin?: pb<2, string>;
|
||||
command?: pb<3, string>;
|
||||
seq?: pb<4, uint_32>;
|
||||
retryTimes?: pb<5, uint_32>;
|
||||
appId?: pb<6, uint_32>;
|
||||
dataFlag?: pb<7, uint_32>;
|
||||
commandId?: pb<8, uint_32>;
|
||||
}
|
||||
|
||||
export interface SegHead {
|
||||
serviceId?: pb<1, uint_32>;
|
||||
filesize?: pb<2, uint_64>;
|
||||
dataOffset?: pb<3, uint_64>;
|
||||
dataLength?: pb<4, uint_32>;
|
||||
retCode?: pb<5, uint_32>;
|
||||
serviceTicket?: pb<6, bytes>;
|
||||
flag?: pb<7, uint_32>;
|
||||
md5?: pb<8, bytes>;
|
||||
fileMd5?: pb<9, bytes>;
|
||||
cacheAddr?: pb<10, uint_32>;
|
||||
cachePort?: pb<13, uint_32>;
|
||||
}
|
||||
|
||||
export interface LoginSigHead {
|
||||
loginSigType?: pb<1, uint_32>;
|
||||
appId?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
export interface ReqDataHighwayHead {
|
||||
msgBaseHead?: pb<1, DataHighwayHead>;
|
||||
msgSegHead?: pb<2, SegHead>;
|
||||
bytesReqExtendInfo?: pb<3, bytes>;
|
||||
timestamp?: pb<4, uint_64>;
|
||||
msgLoginSigHead?: pb<5, LoginSigHead>;
|
||||
}
|
||||
|
||||
export interface RespDataHighwayHead {
|
||||
msgBaseHead?: pb<1, DataHighwayHead>;
|
||||
msgSegHead?: pb<2, SegHead>;
|
||||
errorCode?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
// Highway extend (NTV2RichMediaHighwayExt)
|
||||
|
||||
export interface HighwayDomain {
|
||||
isEnable?: pb<1, bool>;
|
||||
ip?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface HighwayIPv4 {
|
||||
domain?: pb<1, HighwayDomain>;
|
||||
port?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface HighwayNetwork {
|
||||
ipv4s?: pb_repeated<1, HighwayIPv4>;
|
||||
}
|
||||
|
||||
export interface HighwayHash {
|
||||
fileSha1?: pb_repeated<1, bytes>;
|
||||
}
|
||||
|
||||
export interface HighwayMsgInfoBody {
|
||||
index?: pb<1, IndexNode>;
|
||||
picture?: pb<2, PictureInfo>;
|
||||
fileExist?: pb<5, bool>;
|
||||
hashSum?: pb<6, HashSum>;
|
||||
}
|
||||
|
||||
export interface NTV2RichMediaHighwayExt {
|
||||
fileUuid?: pb<1, string>;
|
||||
uKey?: pb<2, string>;
|
||||
network?: pb<5, HighwayNetwork>;
|
||||
msgInfoBody?: pb_repeated<6, HighwayMsgInfoBody>;
|
||||
blockSize?: pb<10, uint_32>;
|
||||
hash?: pb<11, HighwayHash>;
|
||||
}
|
||||
|
||||
// File upload extend (group/private file highway)
|
||||
|
||||
export interface FileUploadUrl {
|
||||
unknown?: pb<1, int_32>;
|
||||
host?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface FileUploadHost {
|
||||
url?: pb<1, FileUploadUrl>;
|
||||
port?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface FileUploadHostConfig {
|
||||
hosts?: pb_repeated<200, FileUploadHost>;
|
||||
}
|
||||
|
||||
export interface FileUploadNameInfo {
|
||||
fileName?: pb<100, string>;
|
||||
}
|
||||
|
||||
export interface FileUploadClientInfo {
|
||||
clientType?: pb<100, int_32>;
|
||||
appId?: pb<200, string>;
|
||||
terminalType?: pb<300, int_32>;
|
||||
clientVer?: pb<400, string>;
|
||||
unknown?: pb<600, int_32>;
|
||||
}
|
||||
|
||||
export interface FileUploadFileEntry {
|
||||
fileSize?: pb<100, uint_64>;
|
||||
md5?: pb<200, bytes>;
|
||||
checkKey?: pb<300, bytes>;
|
||||
md5S2?: pb<400, bytes>;
|
||||
fileId?: pb<600, string>;
|
||||
uploadKey?: pb<700, bytes>;
|
||||
}
|
||||
|
||||
export interface FileUploadBusiInfo {
|
||||
busId?: pb<1, int_32>;
|
||||
senderUin?: pb<100, uint_64>;
|
||||
receiverUin?: pb<200, uint_64>;
|
||||
groupCode?: pb<400, uint_64>;
|
||||
}
|
||||
|
||||
export interface FileUploadEntry {
|
||||
busiBuff?: pb<100, FileUploadBusiInfo>;
|
||||
fileEntry?: pb<200, FileUploadFileEntry>;
|
||||
clientInfo?: pb<300, FileUploadClientInfo>;
|
||||
fileNameInfo?: pb<400, FileUploadNameInfo>;
|
||||
host?: pb<500, FileUploadHostConfig>;
|
||||
}
|
||||
|
||||
export interface FileUploadExt {
|
||||
unknown1?: pb<1, int_32>;
|
||||
unknown2?: pb<2, int_32>;
|
||||
unknown3?: pb<3, int_32>;
|
||||
entry?: pb<100, FileUploadEntry>;
|
||||
unknown200?: pb<200, int_32>;
|
||||
}
|
||||
|
||||
// Encodable MsgInfo (for embedding in message element)
|
||||
|
||||
export interface EncodableMediaExtBizInfo {
|
||||
pic?: pb<1, PicExtBizInfo>;
|
||||
video?: pb<2, VideoExtBizInfo>;
|
||||
ptt?: pb<3, PttExtBizInfo>;
|
||||
busiType?: pb<10, uint_32>;
|
||||
}
|
||||
|
||||
export interface EncodableMediaMsgInfo {
|
||||
msgInfoBody?: pb_repeated<1, HighwayMsgInfoBody>;
|
||||
extBizInfo?: pb<2, EncodableMediaExtBizInfo>;
|
||||
}
|
||||
|
||||
// HttpConn.0x6ff_501 (highway session)
|
||||
|
||||
export interface HttpConn {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, int_32>;
|
||||
field3?: pb<3, int_32>;
|
||||
field4?: pb<4, int_32>;
|
||||
field6?: pb<6, int_32>;
|
||||
serviceTypes?: pb_repeated<7, uint_32>;
|
||||
field9?: pb<9, int_32>;
|
||||
field10?: pb<10, int_32>;
|
||||
field11?: pb<11, int_32>;
|
||||
ver?: pb<15, string>;
|
||||
}
|
||||
|
||||
export interface HttpConn0x6FF501Request {
|
||||
httpConn?: pb<0x501, HttpConn>;
|
||||
}
|
||||
|
||||
export interface ServerAddr {
|
||||
type?: pb<1, uint_32>;
|
||||
ip?: pb<2, fixed_32>;
|
||||
port?: pb<3, uint_32>;
|
||||
area?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface ServerInfo {
|
||||
serviceType?: pb<1, uint_32>;
|
||||
serverAddrs?: pb_repeated<2, ServerAddr>;
|
||||
}
|
||||
|
||||
export interface HttpConnResponse {
|
||||
sigSession?: pb<1, bytes>;
|
||||
sessionKey?: pb<2, bytes>;
|
||||
serverInfos?: pb_repeated<3, ServerInfo>;
|
||||
}
|
||||
|
||||
export interface HttpConn0x6FF501Response {
|
||||
httpConn?: pb<0x501, HttpConnResponse>;
|
||||
}
|
||||
|
||||
// NTV2 Upload Request (for OIDB 0x11C4/0x11C5)
|
||||
|
||||
export interface NTV2FileType {
|
||||
type?: pb<1, uint_32>;
|
||||
picFormat?: pb<2, uint_32>;
|
||||
videoFormat?: pb<3, uint_32>;
|
||||
voiceFormat?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2FileInfo {
|
||||
fileSize?: pb<1, uint_32>;
|
||||
fileHash?: pb<2, string>;
|
||||
fileSha1?: pb<3, string>;
|
||||
fileName?: pb<4, string>;
|
||||
type?: pb<5, NTV2FileType>;
|
||||
width?: pb<6, uint_32>;
|
||||
height?: pb<7, uint_32>;
|
||||
time?: pb<8, uint_32>;
|
||||
original?: pb<9, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadInfo {
|
||||
fileInfo?: pb<1, NTV2FileInfo>;
|
||||
subFileType?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
// NTV2 上传请求/响应扩展信息(与消息解码结构共用,参考 bridge/proto/highway.ts)
|
||||
// 必须包含 video.fromScene 和 toScene 字段,否则私聊发送视频时会被服务器返回 result=79 拒绝。
|
||||
export interface NTV2ExtBizInfo {
|
||||
pic?: pb<1, PicExtBizInfo>;
|
||||
video?: pb<2, VideoExtBizInfo>;
|
||||
ptt?: pb<3, PttExtBizInfo>;
|
||||
busiType?: pb<10, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadReq {
|
||||
uploadInfo?: pb_repeated<1, NTV2UploadInfo>;
|
||||
tryFastUploadCompleted?: pb<2, bool>;
|
||||
srvSendMsg?: pb<3, bool>;
|
||||
clientRandomId?: pb<4, uint_64>;
|
||||
compatQmsgSceneType?: pb<5, uint_32>;
|
||||
extBizInfo?: pb<6, NTV2ExtBizInfo>;
|
||||
clientSeq?: pb<7, uint_32>;
|
||||
noNeedCompatMsg?: pb<8, bool>;
|
||||
}
|
||||
|
||||
export interface NTV2C2CUserInfo {
|
||||
accountType?: pb<1, uint_32>;
|
||||
targetUid?: pb<2, string>;
|
||||
routingHead?: pb<3, bytes>;
|
||||
}
|
||||
|
||||
export interface NTV2GroupInfo {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadSceneInfo {
|
||||
requestType?: pb<101, uint_32>;
|
||||
businessType?: pb<102, uint_32>;
|
||||
sceneType?: pb<200, uint_32>;
|
||||
c2c?: pb<201, NTV2C2CUserInfo>;
|
||||
group?: pb<202, NTV2GroupInfo>;
|
||||
}
|
||||
|
||||
export interface NTV2CommonHead {
|
||||
requestId?: pb<1, uint_32>;
|
||||
command?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2ClientMeta {
|
||||
agentType?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadReqHead {
|
||||
common?: pb<1, NTV2CommonHead>;
|
||||
scene?: pb<2, NTV2UploadSceneInfo>;
|
||||
client?: pb<3, NTV2ClientMeta>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadRichMediaReq {
|
||||
reqHead?: pb<1, NTV2UploadReqHead>;
|
||||
upload?: pb<2, NTV2UploadReq>;
|
||||
}
|
||||
|
||||
// NTV2 Upload Response
|
||||
export interface NTV2IPv4 {
|
||||
outIp?: pb<1, uint_32>;
|
||||
outPort?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface NTV2SubFileInfoResp {
|
||||
subType?: pb<1, uint_32>;
|
||||
uKey?: pb<2, string>;
|
||||
uKeyTtl?: pb<3, uint_32>;
|
||||
ipv4s?: pb_repeated<4, NTV2IPv4>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadRespMsgInfo {
|
||||
msgInfoBody?: pb_repeated<1, HighwayMsgInfoBody>;
|
||||
extBizInfo?: pb<2, NTV2ExtBizInfo>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadRespBody {
|
||||
uKey?: pb<1, string>;
|
||||
uKeyTtl?: pb<2, uint_32>;
|
||||
ipv4s?: pb_repeated<3, NTV2IPv4>;
|
||||
msgSeq?: pb<5, uint_64>;
|
||||
msgInfo?: pb<6, NTV2UploadRespMsgInfo>;
|
||||
compatQMsg?: pb<8, bytes>;
|
||||
subFileInfos?: pb_repeated<10, NTV2SubFileInfoResp>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadRespHead {
|
||||
common?: pb<1, NTV2CommonHead>;
|
||||
retCode?: pb<2, uint_32>;
|
||||
message?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface NTV2UploadRichMediaResp {
|
||||
respHead?: pb<1, NTV2UploadRespHead>;
|
||||
upload?: pb<2, NTV2UploadRespBody>;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// SnowLuma wire-protobuf type definitions.
|
||||
//
|
||||
// This barrel exists so `@snowluma/proto-defs` can be resolved by a
|
||||
// plain `import {} from '@snowluma/proto-defs'` (consumers that don't
|
||||
// know which sub-namespace they want, or just want to see what's
|
||||
// available). The package itself is otherwise consumed via the
|
||||
// per-file subpath exports declared in package.json — that's the
|
||||
// recommended import shape because it mirrors the legacy
|
||||
// `bridge/proto/proton/<sub>` paths 1:1 and avoids name collisions.
|
||||
//
|
||||
// ─── Collision note ───
|
||||
//
|
||||
// `highway.ts` and `oidb-actions/media.ts` each define their own
|
||||
// `NTV2*` types (NTV2CommonHead, NTV2ClientMeta, NTV2C2CUserInfo,
|
||||
// NTV2FileInfo, NTV2FileType, NTV2GroupInfo). The two definitions
|
||||
// are NOT compatible — they describe different wire shapes for
|
||||
// different protocol surfaces and happen to share the same name in
|
||||
// the upstream Lagrange schema. `export *` silently drops one side
|
||||
// when names collide, so a consumer that grabs an `NTV2CommonHead`
|
||||
// off the barrel might end up with the wrong one. Prefer the subpath
|
||||
// imports below for any NTV2-named type.
|
||||
|
||||
export type * from './action.js';
|
||||
export type * from './collection.js';
|
||||
export type * from './qzone.js';
|
||||
export type * from './element.js';
|
||||
// NOTE: `highway.ts` intentionally NOT re-exported here — see note above.
|
||||
export type * from './longmsg.js';
|
||||
export type * from './message.js';
|
||||
export type * from './get-group-msg.js';
|
||||
export type * from './get-c2c-msg.js';
|
||||
export type * from './notify.js';
|
||||
export type * from './oidb.js';
|
||||
export type * from './oidb-action.js';
|
||||
export type * from './oidb-actions/base.js';
|
||||
export type * from './oidb-actions/group-album.js';
|
||||
export type * from './oidb-actions/group-file.js';
|
||||
// NOTE: `oidb-actions/media.ts` intentionally NOT re-exported — see note above.
|
||||
@@ -0,0 +1,69 @@
|
||||
import type { pb, pb_repeated, uint_32, bool, bytes } from '@snowluma/proton';
|
||||
import type { PushMsgBody } from './message';
|
||||
|
||||
export interface LongMsgUid {
|
||||
uid?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface LongMsgSettings {
|
||||
field1?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface SendLongMsgInfo {
|
||||
type?: pb<1, uint_32>;
|
||||
uid?: pb<2, LongMsgUid>;
|
||||
groupUin?: pb<3, uint_32>;
|
||||
payload?: pb<4, bytes>;
|
||||
}
|
||||
|
||||
export interface SendLongMsgReq {
|
||||
info?: pb<2, SendLongMsgInfo>;
|
||||
settings?: pb<15, LongMsgSettings>;
|
||||
}
|
||||
|
||||
export interface SendLongMsgRespResult {
|
||||
resId?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface SendLongMsgResp {
|
||||
result?: pb<2, SendLongMsgRespResult>;
|
||||
settings?: pb<15, LongMsgSettings>;
|
||||
}
|
||||
|
||||
export interface RecvLongMsgInfo {
|
||||
uid?: pb<1, LongMsgUid>;
|
||||
resId?: pb<2, string>;
|
||||
acquire?: pb<3, bool>;
|
||||
}
|
||||
|
||||
export interface RecvLongMsgReq {
|
||||
info?: pb<1, RecvLongMsgInfo>;
|
||||
settings?: pb<15, LongMsgSettings>;
|
||||
}
|
||||
|
||||
export interface RecvLongMsgRespResult {
|
||||
resId?: pb<3, string>;
|
||||
payload?: pb<4, bytes>;
|
||||
}
|
||||
|
||||
export interface RecvLongMsgResp {
|
||||
result?: pb<1, RecvLongMsgRespResult>;
|
||||
settings?: pb<15, LongMsgSettings>;
|
||||
}
|
||||
|
||||
// Schemas that reach into PushMsgBody
|
||||
export interface LongMsgContent {
|
||||
msgBody?: pb_repeated<1, PushMsgBody>;
|
||||
}
|
||||
|
||||
export interface LongMsgAction {
|
||||
actionCommand?: pb<1, string>;
|
||||
actionData?: pb<2, LongMsgContent>;
|
||||
}
|
||||
|
||||
export interface LongMsgResult {
|
||||
action?: pb_repeated<2, LongMsgAction>;
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bytes } from '@snowluma/proton';
|
||||
import type { Elem } from './element';
|
||||
|
||||
export interface GroupCardPart {
|
||||
control?: pb<1, bytes>;
|
||||
text?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface RichGroupCard {
|
||||
parts?: pb_repeated<1, GroupCardPart>;
|
||||
}
|
||||
|
||||
/** Join-origin metadata used by QQ's member-add notification handler. */
|
||||
export interface GroupJoinOrigin {
|
||||
/** 1 names a QR-code sharer rather than an inviter. */
|
||||
type?: pb<1, uint_32>;
|
||||
uid?: pb<3, bytes>;
|
||||
}
|
||||
|
||||
export interface GroupJoinExtra {
|
||||
origin?: pb<1, GroupJoinOrigin>;
|
||||
}
|
||||
|
||||
export interface GroupMessageKey {
|
||||
joinExtra?: pb<4, GroupJoinExtra>;
|
||||
}
|
||||
|
||||
// ResponseHead.Grp
|
||||
export interface ResponseGrp {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
/** Sender display name as populated by the group-history fetch (SsoGetGroupMsg).
|
||||
* Empty on live OlPush pushes and merged-forward nodes — those use `memberCard`
|
||||
* (field 4) instead. */
|
||||
memberName?: pb<2, string>;
|
||||
/** Sender display name (group card if set, else nickname) as populated on live
|
||||
* group pushes AND merged-forward nodes. Verified on-target (#201): a live
|
||||
* message shows "星屿"/"墨梓柒111" (the card) here while field 2 is empty, and
|
||||
* forward nodes carry per-node sender names here. Lagrange labels this
|
||||
* `MemberName`; we keep `memberName` for the field-2 group-history slot. */
|
||||
memberCard?: pb<4, bytes>;
|
||||
/** Type 2 carries the literal sender nickname. Other values may carry a RichGroupCard. */
|
||||
memberCardType?: pb<5, uint_32>;
|
||||
/** The real group name (Lagrange: GroupName). "测试123" on-target. */
|
||||
groupName?: pb<7, string>;
|
||||
messageKey?: pb<8, GroupMessageKey>;
|
||||
}
|
||||
|
||||
export interface ResponseForward {
|
||||
tempGroupUin?: pb<5, uint_32>;
|
||||
friendName?: pb<6, string>;
|
||||
}
|
||||
|
||||
// ResponseHead
|
||||
export interface ResponseHead {
|
||||
fromUin?: pb<1, uint_32>;
|
||||
fromUid?: pb<2, string>;
|
||||
type?: pb<3, uint_32>;
|
||||
sigMap?: pb<4, uint_32>;
|
||||
toUin?: pb<5, uint_32>;
|
||||
toUid?: pb<6, string>;
|
||||
forward?: pb<7, ResponseForward>;
|
||||
grp?: pb<8, ResponseGrp>;
|
||||
}
|
||||
|
||||
// ContentHead
|
||||
export interface ContentHead {
|
||||
msgType?: pb<1, uint_32>;
|
||||
subType?: pb<2, uint_32>;
|
||||
// C2C command / sub-message-type. QQ NT (msg_header_codec_helper.cc::
|
||||
// DecodeRoutingHead) reads this as `c2c_cmd` and uses it to route C2C-family
|
||||
// pushes (msgType 141/166/167) as system/control signals via OnRecvSysMsg
|
||||
// rather than chat bubbles. A fixed set of values is excluded from the chat
|
||||
// list — see `isC2cControlPush` in msg-push/blank-filter.ts.
|
||||
c2cCmd?: pb<3, uint_32>;
|
||||
msgId?: pb<4, uint_32>;
|
||||
sequence?: pb<5, uint_32>;
|
||||
timestamp?: pb<6, uint_32>;
|
||||
field7?: pb<7, uint_64>;
|
||||
/** QQ sets a nonzero value for automatic replies. */
|
||||
autoReply?: pb<10, uint_32>;
|
||||
/** Conversation-wide C2C sequence. Unlike field 5, this advances across
|
||||
* messages sent by either participant and is the sequence accepted by
|
||||
* SsoGetC2cMsg. It is absent on group messages. */
|
||||
ntMsgSeq?: pb<11, uint_32>;
|
||||
newId?: pb<12, uint_64>;
|
||||
}
|
||||
|
||||
// Ptt (voice)
|
||||
export interface Ptt {
|
||||
fileType?: pb<1, uint_32>;
|
||||
fileId?: pb<2, uint_64>;
|
||||
fileUuid?: pb<3, bytes>;
|
||||
fileMd5?: pb<4, bytes>;
|
||||
fileName?: pb<5, string>;
|
||||
fileSize?: pb<6, uint_32>;
|
||||
groupFileKey?: pb<10, string>;
|
||||
fileKey?: pb<14, bytes>;
|
||||
time?: pb<19, uint_32>;
|
||||
format?: pb<29, uint_32>;
|
||||
}
|
||||
|
||||
// C2C 离线文件结构
|
||||
// 1. 发送端必填:字段 9/50/55(subcmd=1, dangerEvel=0, expireTime=当前时间+7天)。
|
||||
// 2. 接收端只读:核心标识槽位(Uuid/Md5/Name/Size/Hash)。
|
||||
export interface NotOnlineFile {
|
||||
fileType?: pb<1, uint_32>;
|
||||
fileUuid?: pb<3, string>;
|
||||
fileMd5?: pb<4, bytes>;
|
||||
fileName?: pb<5, string>;
|
||||
fileSize?: pb<6, uint_64>;
|
||||
subcmd?: pb<9, uint_32>; // 发送必填:固定为 1
|
||||
downloadFlag?: pb<12, uint_32>; // 2 = 对方已下载的回执,不是一条新文件消息
|
||||
dangerEvel?: pb<50, uint_32>; // 发送必填:固定为 0
|
||||
expireTime?: pb<55, uint_32>; // 发送必填:过期时间戳(now + 7 days)
|
||||
pbReserve?: pb<56, bytes>;
|
||||
fileHash?: pb<57, string>;
|
||||
}
|
||||
|
||||
// RichText
|
||||
export interface RichText {
|
||||
elems?: pb_repeated<2, Elem>;
|
||||
notOnlineFile?: pb<3, NotOnlineFile>;
|
||||
ptt?: pb<4, Ptt>;
|
||||
}
|
||||
|
||||
// MessageBody
|
||||
export interface MessageBody {
|
||||
richText?: pb<1, RichText>;
|
||||
msgContent?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
// C2C 文件附加信息
|
||||
// 统一使用与线上数据对齐的 NotOnlineFile 结构,修复收发双向的解析问题。
|
||||
//
|
||||
// `field6` 携带服务器签发的下载路由(来自 0xE37_800 finalize 响应的
|
||||
// metadata)。发送 c2c 文件时缺了它,接收方点开会"文件传输失败"——
|
||||
// `file` 只是元数据,真正的下载凭证在这里。字段 tag 对照 NapCat
|
||||
// `message/component.ts: PrivateFileExtra / PrivateFileExtraField2`。
|
||||
export interface PrivateFileExtraField2 {
|
||||
field1?: pb<1, uint_32>; // ← finalize metadata.field110
|
||||
fileUuid?: pb<4, string>;
|
||||
fileName?: pb<5, string>;
|
||||
field6?: pb<6, uint_32>; // ← finalize metadata.field3
|
||||
field7?: pb<7, bytes>; // ← finalize metadata.field101
|
||||
field8?: pb<8, bytes>; // ← finalize metadata.field100
|
||||
timestamp1?: pb<9, uint_32>; // ← finalize metadata.timestamp1
|
||||
fileHash?: pb<14, string>;
|
||||
selfUid?: pb<15, string>;
|
||||
destUid?: pb<16, string>;
|
||||
}
|
||||
export interface PrivateFileExtra {
|
||||
field2?: pb<2, PrivateFileExtraField2>;
|
||||
}
|
||||
export interface FileExtra {
|
||||
file?: pb<1, NotOnlineFile>;
|
||||
field6?: pb<6, PrivateFileExtra>;
|
||||
}
|
||||
|
||||
// PushMsgBody
|
||||
export interface PushMsgBody {
|
||||
responseHead?: pb<1, ResponseHead>;
|
||||
contentHead?: pb<2, ContentHead>;
|
||||
body?: pb<3, MessageBody>;
|
||||
}
|
||||
|
||||
// PushMsg (top-level)
|
||||
export interface PushMsg {
|
||||
message?: pb<1, PushMsgBody>;
|
||||
status?: pb<3, int_32>;
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bool, bytes } from '@snowluma/proton';
|
||||
|
||||
export interface OperatorField1 {
|
||||
uid?: pb<1, string>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, bytes>;
|
||||
field4?: pb<4, uint_32>;
|
||||
field5?: pb<5, bytes>;
|
||||
}
|
||||
|
||||
export interface OperatorInfo {
|
||||
operatorField?: pb<1, OperatorField1>;
|
||||
}
|
||||
|
||||
export interface FriendRemarkChangedTarget {
|
||||
uin?: pb<3, uint_64>;
|
||||
uid?: pb<7, string>;
|
||||
}
|
||||
|
||||
export interface FriendRemarkChangedValue {
|
||||
target?: pb<1, FriendRemarkChangedTarget>;
|
||||
remark?: pb<2, string>;
|
||||
}
|
||||
|
||||
/** Event0x210 / subType 364 — server-authoritative friend remark update. */
|
||||
export interface FriendRemarkChangedNotify {
|
||||
change?: pb<1, FriendRemarkChangedValue>;
|
||||
updateTime?: pb<3, uint_32>;
|
||||
nickname?: pb<4, string>;
|
||||
changeType?: pb<5, uint_32>;
|
||||
}
|
||||
|
||||
export interface GroupChange {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
flag?: pb<2, uint_32>;
|
||||
memberUid?: pb<3, string>;
|
||||
/** Shared member-change operation code; used by both increase and decrease pushes. */
|
||||
decreaseType?: pb<4, uint_32>;
|
||||
operatorBytes?: pb<5, bytes>;
|
||||
increaseType?: pb<6, uint_32>;
|
||||
field7?: pb<7, bytes>;
|
||||
}
|
||||
|
||||
export interface GroupAdminExtra {
|
||||
adminUid?: pb<1, string>;
|
||||
isPromote?: pb<2, bool>;
|
||||
}
|
||||
|
||||
export interface GroupAdminBody {
|
||||
extraDisable?: pb<1, GroupAdminExtra>;
|
||||
extraEnable?: pb<2, GroupAdminExtra>;
|
||||
}
|
||||
|
||||
export interface GroupAdmin {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
flag?: pb<2, uint_32>;
|
||||
isPromote?: pb<3, bool>;
|
||||
body?: pb<4, GroupAdminBody>;
|
||||
}
|
||||
|
||||
export interface InvitationInner {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, uint_32>;
|
||||
targetUid?: pb<5, string>;
|
||||
invitorUid?: pb<6, string>;
|
||||
field7?: pb<7, uint_32>;
|
||||
field9?: pb<9, uint_32>;
|
||||
field10?: pb<10, bytes>;
|
||||
field11?: pb<11, uint_32>;
|
||||
field12?: pb<12, string>;
|
||||
}
|
||||
|
||||
export interface InvitationInfo {
|
||||
inner?: pb<1, InvitationInner>;
|
||||
}
|
||||
|
||||
export interface GroupInvitation {
|
||||
cmd?: pb<1, int_32>;
|
||||
info?: pb<2, InvitationInfo>;
|
||||
}
|
||||
|
||||
export interface GroupInvite {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, uint_32>;
|
||||
invitorUid?: pb<5, string>;
|
||||
hashes?: pb<6, bytes>;
|
||||
}
|
||||
|
||||
export interface GroupJoin {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
targetUid?: pb<3, string>;
|
||||
field4?: pb<4, uint_32>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, string>;
|
||||
field8?: pb<8, uint_32>;
|
||||
field9?: pb<9, bytes>;
|
||||
}
|
||||
|
||||
export interface FriendRequestInfo {
|
||||
targetUid?: pb<1, string>;
|
||||
sourceUid?: pb<2, string>;
|
||||
newSource?: pb<5, string>;
|
||||
message?: pb<10, string>;
|
||||
source?: pb<11, string>;
|
||||
}
|
||||
|
||||
export interface FriendRequest {
|
||||
info?: pb<1, FriendRequestInfo>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Online-device snapshot carried by Event 0x210 / subType 349.
|
||||
*
|
||||
* Field numbers were recovered from QQ NT's OnRecvOnLineDev decoder. The
|
||||
* outer four fields describe the current client, while field 5 contains the
|
||||
* online-device entries exposed by getOnLineDev's kernel cache.
|
||||
*/
|
||||
export interface OnlineDeviceNotifyItem {
|
||||
appId?: pb<1, uint_32>;
|
||||
instanceId?: pb<2, uint_32>;
|
||||
/** Packed terminal value; QQ normalizes it to the low byte before use. */
|
||||
clientType?: pb<3, uint_32>;
|
||||
platform?: pb<4, uint_32>;
|
||||
deviceName?: pb<5, string>;
|
||||
}
|
||||
|
||||
export interface OnlineDeviceNotify {
|
||||
appId?: pb<1, uint_32>;
|
||||
instanceId?: pb<2, uint_32>;
|
||||
clientType?: pb<3, uint_32>;
|
||||
platform?: pb<4, uint_32>;
|
||||
devices?: pb_repeated<5, OnlineDeviceNotifyItem>;
|
||||
}
|
||||
|
||||
export interface FriendRecallTipInfo {
|
||||
tip?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface FriendRecallInfo {
|
||||
fromUid?: pb<1, string>;
|
||||
toUid?: pb<2, string>;
|
||||
clientSequence?: pb<3, uint_32>;
|
||||
newId?: pb<4, uint_64>;
|
||||
time?: pb<5, uint_32>;
|
||||
random?: pb<6, uint_32>;
|
||||
pkgNum?: pb<7, uint_32>;
|
||||
pkgIndex?: pb<8, uint_32>;
|
||||
divSeq?: pb<9, uint_32>;
|
||||
tipInfo?: pb<13, FriendRecallTipInfo>;
|
||||
}
|
||||
|
||||
export interface FriendRecall {
|
||||
info?: pb<1, FriendRecallInfo>;
|
||||
instId?: pb<2, uint_32>;
|
||||
appId?: pb<3, uint_32>;
|
||||
longMessageFlag?: pb<4, uint_32>;
|
||||
reserved?: pb<5, bytes>;
|
||||
}
|
||||
|
||||
// 新好友通知 (0x210 子类型 179 / 226)
|
||||
// 触发场景:双向同意好友申请(179:对方同意 Bot;226:Bot 同意对方)。
|
||||
export interface NewFriendInfo {
|
||||
uid?: pb<1, string>;
|
||||
field2?: pb<2, uint_32>;
|
||||
time?: pb<3, uint_32>; // Unix 时间戳 (Wire 层为 fixed32)
|
||||
message?: pb<4, string>;
|
||||
nickName?: pb<5, string>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, uint_32>;
|
||||
toUid?: pb<9, string>;
|
||||
}
|
||||
|
||||
export interface NewFriend {
|
||||
field1?: pb<1, uint_32>;
|
||||
info?: pb<2, NewFriendInfo>;
|
||||
}
|
||||
|
||||
// Bot 自身进群通知 (PkgType 85)
|
||||
// 触发场景:Bot 成功加入群聊(管理员通过申请 或 接受邀请进群)。
|
||||
export interface SelfJoinInGroup {
|
||||
groupUin?: pb<1, uint_64>;
|
||||
field2?: pb<2, uint_32>;
|
||||
operatorUid?: pb<3, string>; // 操作人 UID (如批准申请的管理员)
|
||||
field4?: pb<4, uint_32>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, string>;
|
||||
}
|
||||
|
||||
export interface GroupMuteState {
|
||||
targetUid?: pb<1, string>;
|
||||
duration?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface GroupMuteData {
|
||||
timestamp?: pb<1, uint_32>;
|
||||
type?: pb<2, uint_32>;
|
||||
state?: pb<3, GroupMuteState>;
|
||||
}
|
||||
|
||||
export interface GroupMute {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
subType?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
operatorUid?: pb<4, string>;
|
||||
data?: pb<5, GroupMuteData>;
|
||||
}
|
||||
|
||||
export interface RecallMessage {
|
||||
sequence?: pb<1, uint_32>;
|
||||
time?: pb<2, uint_32>;
|
||||
random?: pb<3, uint_32>;
|
||||
type?: pb<4, uint_32>;
|
||||
flag?: pb<5, uint_32>;
|
||||
authorUid?: pb<6, string>;
|
||||
}
|
||||
|
||||
export interface GroupRecallTipInfo {
|
||||
tip?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface GroupRecall {
|
||||
operatorUid?: pb<1, string>;
|
||||
recallMessages?: pb_repeated<3, RecallMessage>;
|
||||
userDef?: pb<5, bytes>;
|
||||
groupType?: pb<6, int_32>;
|
||||
opType?: pb<7, int_32>;
|
||||
tipInfo?: pb<9, GroupRecallTipInfo>;
|
||||
}
|
||||
|
||||
export interface TemplParam {
|
||||
name?: pb<1, string>;
|
||||
value?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface GeneralGrayTipInfo {
|
||||
busiType?: pb<1, uint_64>;
|
||||
busiId?: pb<2, uint_64>;
|
||||
ctrlFlag?: pb<3, uint_32>;
|
||||
c2cType?: pb<4, uint_32>;
|
||||
serviceType?: pb<5, uint_32>;
|
||||
templId?: pb<6, uint_64>;
|
||||
msgTemplParam?: pb_repeated<7, TemplParam>;
|
||||
content?: pb<8, string>;
|
||||
}
|
||||
|
||||
export interface EssenceMessage {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
msgSequence?: pb<2, uint_32>;
|
||||
random?: pb<3, uint_32>;
|
||||
setFlag?: pb<4, uint_32>;
|
||||
memberUin?: pb<5, uint_32>;
|
||||
operatorUin?: pb<6, uint_32>;
|
||||
timestamp?: pb<7, uint_32>;
|
||||
msgSequence2?: pb<8, uint_32>;
|
||||
operatorNickname?: pb<9, string>;
|
||||
memberNickname?: pb<10, string>;
|
||||
setFlag2?: pb<11, uint_32>;
|
||||
}
|
||||
|
||||
export interface NotifyMessageBody {
|
||||
type?: pb<1, uint_32>;
|
||||
groupUin?: pb<4, uint_32>;
|
||||
eventParam?: pb<5, bytes>;
|
||||
recall?: pb<11, GroupRecall>;
|
||||
field13?: pb<13, uint_32>;
|
||||
operatorUid?: pb<21, string>;
|
||||
generalGrayTip?: pb<26, GeneralGrayTipInfo>;
|
||||
essenceMessage?: pb<33, EssenceMessage>;
|
||||
msgSequence?: pb<37, uint_32>;
|
||||
field39?: pb<39, uint_32>;
|
||||
}
|
||||
|
||||
// Event0x2DC subType=16: GroupMsgEmojiLike
|
||||
export interface GroupReactionDataInnerDataTarget {
|
||||
seq?: pb<1, uint_64>;
|
||||
}
|
||||
|
||||
export interface GroupReactionDataContent {
|
||||
code?: pb<1, string>;
|
||||
count?: pb<3, uint_32>;
|
||||
operatorUid?: pb<4, string>;
|
||||
type?: pb<5, uint_32>;
|
||||
}
|
||||
|
||||
export interface GroupReactionDataInnerData {
|
||||
groupReactionTarget?: pb<2, GroupReactionDataInnerDataTarget>;
|
||||
groupReactionDataContent?: pb<3, GroupReactionDataContent>;
|
||||
}
|
||||
|
||||
export interface GroupReactionDataInner {
|
||||
data?: pb<1, GroupReactionDataInnerData>;
|
||||
}
|
||||
|
||||
export interface GroupReactionData {
|
||||
data?: pb<1, GroupReactionDataInner>;
|
||||
}
|
||||
|
||||
export interface GroupReactNotify {
|
||||
groupUin?: pb<4, uint_64>;
|
||||
field13?: pb<13, uint_32>;
|
||||
groupReactionData?: pb<44, GroupReactionData>;
|
||||
}
|
||||
|
||||
// Forced-offline ("被迫下线") push — SSO cmd
|
||||
// `trpc.qq_new_tech.status_svc.StatusService.KickNT`. QQ NT's unified offline
|
||||
// notification (kick / login-elsewhere / risk-control-triggered offline all
|
||||
// arrive here; the reason is in the strings). Field layout RE'd from
|
||||
// wrapper.linux.node (log fmt "tips_title:{} tips_content:{}") + Lagrange's
|
||||
// ServiceKickNTResponse: f4 = tips_title (short title), f3 = tips_content (desc).
|
||||
export interface KickNTResponse {
|
||||
uin?: pb<1, uint_32>;
|
||||
tips?: pb<3, string>; // tips_content — the longer description
|
||||
title?: pb<4, string>; // tips_title — the short title
|
||||
}
|
||||
|
||||
// Group-name change (Event 0x2DC subType 16, NotifyMessageBody.field13 == 12).
|
||||
// Rides in `NotifyMessageBody.eventParam` (field 5). Field layout matches
|
||||
// Lagrange's `GroupNameChange` (RE'd from wrapper.linux.node): only the new
|
||||
// name at field 2. The operator uid is `NotifyMessageBody.operatorUid` (f21).
|
||||
export interface GroupNameChange {
|
||||
name?: pb<2, string>;
|
||||
}
|
||||
|
||||
// Group special-title granted (Event 0x2DC subType 16, NotifyMessageBody.field13
|
||||
// == 6). Rides in `NotifyMessageBody.eventParam` (field 5). Field layout captured
|
||||
// on-wire: f2 = the gray-tip template text ("恭喜<{…}>获得群主授予的<{…"text":TITLE…}>头衔"),
|
||||
// f5 = the member uin who received the title. The title text itself is embedded in
|
||||
// the last `<{…}>` rich token of f2 (the kernel parses that template into a clean
|
||||
// string; on the raw wire we parse it ourselves).
|
||||
export interface GroupSpecialTitleChange {
|
||||
tipText?: pb<2, string>;
|
||||
memberUin?: pb<5, uint_32>;
|
||||
}
|
||||
|
||||
// Profile-like ("名片赞") notify — Event 0x210 subType 39, whose body.msgContent
|
||||
// decodes as this ProfileLikeTip. subType 39 is multiplexed; only inner
|
||||
// msgType==0 && subType==203 is a like. Field numbers CONFIRMED byte-exact against
|
||||
// real on-wire captures (detail.txt = "赞了我的资料卡N次", f3=liker uin, f5=nick);
|
||||
// the like count is parsed from `detail.txt`.
|
||||
export interface ProfileLikeDetail {
|
||||
txt?: pb<1, string>;
|
||||
uin?: pb<3, uint_64>;
|
||||
nickname?: pb<5, string>;
|
||||
}
|
||||
|
||||
export interface ProfileLikeMsg {
|
||||
times?: pb<1, int_32>;
|
||||
time?: pb<2, int_32>;
|
||||
detail?: pb<3, ProfileLikeDetail>;
|
||||
}
|
||||
|
||||
export interface ProfileLikeSubTip {
|
||||
msg?: pb<14, ProfileLikeMsg>;
|
||||
}
|
||||
|
||||
export interface ProfileLikeTip {
|
||||
msgType?: pb<1, int_32>;
|
||||
subType?: pb<2, int_32>;
|
||||
content?: pb<203, ProfileLikeSubTip>;
|
||||
}
|
||||
|
||||
// C2C input-status notify — the "对方正在输入…" push. Delivered as a system
|
||||
// message (msgType 0x210 / subMsgType 0x115) whose `MsgBody.msgContent` carries
|
||||
// this body. Field layout RE'd from `wrapper.linux.node`
|
||||
// `aio_input_state_worker.cc::ProcessInputStateNotifySysMsg` (reads f1=fromUid,
|
||||
// f2=toUid, f3=notifyItem; the item's f4 is the event type).
|
||||
export interface InputStatusNotifyItem {
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_64>;
|
||||
eventType?: pb<4, uint_32>; // 1 = 正在输入 (typing), 3 = 正在讲话 (recording voice)
|
||||
field5?: pb<5, uint_32>;
|
||||
statusText?: pb<6, string>;
|
||||
}
|
||||
|
||||
export interface InputStatusNotify {
|
||||
fromUid?: pb<1, string>;
|
||||
toUid?: pb<2, string>;
|
||||
notifyItem?: pb<3, InputStatusNotifyItem>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export type * from './oidb-actions';
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,77 @@
|
||||
// Recommend-contact ARK card protobufs, RE'd from QQNT wrapper.linux.node.
|
||||
//
|
||||
// Buddy: OidbSvcTrpcTcp.0x12b6_0 (getBuddyRecommendContactArkJson) —
|
||||
// request writes {1:uin, 2:phone, 3:jump_url}; response reads {1:ark}.
|
||||
// Group: OidbSvcTrpcTcp.0x8b7_5 (getGroupRecommendContactArkJson) — encoder
|
||||
// `group_get_ark_json_worker.cc::EncodeRequest` writes {1:reqType=1,
|
||||
// 2:groupCode,5:flag=1}; response (group_info_mgr.cc `[gp_get_ark_json]`)
|
||||
// reads {1:bussness_error_code, 5:ark_json}.
|
||||
// Both return a server-built ark JSON string (the share card payload).
|
||||
|
||||
import type { pb, pb_optional, pb_repeated, uint_32 } from '@snowluma/proton';
|
||||
|
||||
export interface OidbBuddyRecommendArkReq {
|
||||
uin?: pb<1, uint_32>;
|
||||
phoneNumber?: pb<2, string>;
|
||||
jumpUrl?: pb<3, string>;
|
||||
}
|
||||
export interface OidbBuddyRecommendArkResp {
|
||||
ark?: pb<1, string>;
|
||||
}
|
||||
|
||||
export interface OidbGroupRecommendArkReq {
|
||||
reqType?: pb<1, uint_32>;
|
||||
groupCode?: pb<2, uint_32>;
|
||||
flag?: pb<5, uint_32>;
|
||||
}
|
||||
export interface OidbGroupRecommendArkResp {
|
||||
errCode?: pb<1, uint_32>;
|
||||
arkJson?: pb<5, string>;
|
||||
}
|
||||
|
||||
// 0xdc2_34 — send a custom 图文 (URL-share) ark card to a C2C peer or group.
|
||||
// Field layout RE'd from QQ Android 9.3.25 captures. Default SSO: OidbSvcTrpcTcp.0xdc2_34.
|
||||
// appId = 100446242 is fixed for this ark type.
|
||||
// targetId (UIN or group_id) appears at AppInfo[11] AND Meta[2].
|
||||
// Meta.peerType: 0 = C2C, 1 = group.
|
||||
// peerType, field3, and previewUrl are pb_optional — proton preserves 0/empty on wire.
|
||||
export interface Oidb0xdc2CardField5 {
|
||||
field1?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2CardContent {
|
||||
flag?: pb<1, uint_32>;
|
||||
title?: pb<10, string>;
|
||||
desc?: pb<11, string>;
|
||||
summary?: pb<12, string>;
|
||||
jumpUrl?: pb<13, string>;
|
||||
previewUrl?: pb_optional<14, string>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2AppInfo {
|
||||
appId?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field5?: pb<5, Oidb0xdc2CardField5>;
|
||||
targetId?: pb<11, uint_32>;
|
||||
content?: pb<12, Oidb0xdc2CardContent>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2Meta {
|
||||
peerType?: pb_optional<1, uint_32>;
|
||||
targetId?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2_34Req {
|
||||
appInfo?: pb<1, Oidb0xdc2AppInfo>;
|
||||
meta?: pb<2, Oidb0xdc2Meta>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2CardResult {
|
||||
errorCode?: pb<4, uint_32>;
|
||||
errorMessage?: pb<5, string>;
|
||||
}
|
||||
|
||||
export interface Oidb0xdc2_34Resp {
|
||||
results?: pb_repeated<1, Oidb0xdc2CardResult>;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Filtered friend requests: listing, approval, and rejection have distinct
|
||||
// request contracts. List responses can carry an account number or a UID.
|
||||
|
||||
import type { pb, pb_optional, pb_repeated, uint_32, uint_64 } from '@snowluma/proton';
|
||||
|
||||
export interface OidbDoubtGetReqInner {
|
||||
num?: pb<1, uint_32>;
|
||||
uk?: pb<2, string>;
|
||||
}
|
||||
export interface OidbDoubtGetReq {
|
||||
field1?: pb<1, uint_32>;
|
||||
inner?: pb<2, OidbDoubtGetReqInner>;
|
||||
}
|
||||
|
||||
export interface OidbDoubtItem {
|
||||
uid?: pb<1, string>;
|
||||
nick?: pb<2, string>;
|
||||
age?: pb<3, uint_32>;
|
||||
sex?: pb<4, uint_32>;
|
||||
msg?: pb<5, string>;
|
||||
source?: pb<6, string>;
|
||||
reason?: pb<7, string>;
|
||||
reqTime?: pb<8, uint_64>;
|
||||
groupCode?: pb<9, uint_64>;
|
||||
commFriendNum?: pb<10, uint_32>;
|
||||
}
|
||||
export interface OidbDoubtGetRespBody {
|
||||
list?: pb_repeated<1, OidbDoubtItem>;
|
||||
reason?: pb<2, string>;
|
||||
}
|
||||
export interface OidbDoubtGetResp {
|
||||
status?: pb<1, uint_32>;
|
||||
body?: pb<2, OidbDoubtGetRespBody>;
|
||||
}
|
||||
|
||||
export interface OidbDoubtApprovalReq {
|
||||
selfUid?: pb<1, string>;
|
||||
targetUid?: pb<2, string>;
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field4?: pb_optional<4, string>;
|
||||
}
|
||||
|
||||
// Reject an existing filtered friend request.
|
||||
export interface OidbDoubtDelReqInner {
|
||||
uid?: pb<1, string>;
|
||||
}
|
||||
export interface OidbDoubtDelReq {
|
||||
field1?: pb<1, uint_32>;
|
||||
inner?: pb<3, OidbDoubtDelReqInner>;
|
||||
}
|
||||
@@ -0,0 +1,551 @@
|
||||
// OIDB 0x93cf-0x9427, 0x12a9 — QQ 闪传(FlashTransfer / fileset)协议类型。
|
||||
// 响应成功靠 OIDB envelope 的 errorCode(f3=0),业务体无 retCode。
|
||||
|
||||
import type { pb, pb_optional, pb_repeated, uint_32, uint_64, bytes } from '@snowluma/proton';
|
||||
|
||||
// ─────────────── 共用:文件条目(0x93d2/0x93d3 响应里的每个文件/fileset) ───────────────
|
||||
|
||||
/** f9.f2 — 下载信息(f1=类型,f2=下载URL,URL 里已含 rkey 或 fldc)。 */
|
||||
export interface FlashFileDownloadInfo {
|
||||
field1?: pb<1, uint_32>;
|
||||
downloadUrl?: pb<2, string>;
|
||||
}
|
||||
|
||||
/** f9 — fileId + 下载信息。 */
|
||||
export interface FlashFileIdWrap {
|
||||
fileId?: pb<1, string>;
|
||||
download?: pb<2, FlashFileDownloadInfo>;
|
||||
}
|
||||
|
||||
/** f8 — 上传/分享 URL(qfile.qq.com/q/<code>)。 */
|
||||
export interface FlashFileUploadUrl {
|
||||
uploadUrl?: pb<1, string>;
|
||||
}
|
||||
|
||||
/** 文件条目。0x93d3 响应 f1(单条);0x93d2 响应 f1(repeated,多个 fileset)。 */
|
||||
export interface FlashFileEntry {
|
||||
filesetUuid?: pb<1, string>;
|
||||
fileName?: pb<2, string>;
|
||||
origName?: pb<3, string>;
|
||||
fileType?: pb<4, uint_32>;
|
||||
fileSize?: pb<5, uint_64>;
|
||||
uploadUrlWrap?: pb<8, FlashFileUploadUrl>;
|
||||
fileIdWrap?: pb<9, FlashFileIdWrap>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93d3 — 拉取文件集详情(点分享显示链接时触发) ───────────────
|
||||
|
||||
export interface FlashGetDetailReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
field2?: pb<2, uint_32>; // 7
|
||||
}
|
||||
export interface FlashGetDetailResp {
|
||||
entries?: pb_repeated<1, FlashFileEntry>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93d2 — 查询 fileset 列表 ───────────────
|
||||
|
||||
export interface FlashListFilesetsReq {
|
||||
field1?: pb<1, uint_32>; // 3
|
||||
field2?: pb<2, string>; // ""
|
||||
field3?: pb<3, uint_32>; // 10
|
||||
}
|
||||
export interface FlashListFilesetsResp {
|
||||
entries?: pb_repeated<1, FlashFileEntry>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93d4 — 拉取下载URL(完整参数 + fldc) ───────────────
|
||||
|
||||
export interface FlashGetDownloadUrlReqInner {
|
||||
field1?: pb<1, string>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, string>;
|
||||
field5?: pb<5, FlashGetDownloadUrlReqInner5>;
|
||||
field6?: pb<6, FlashGetDownloadUrlReqInner6>;
|
||||
}
|
||||
export interface FlashGetDownloadUrlReqInner5 {
|
||||
field1?: pb<1, uint_32>;
|
||||
}
|
||||
export interface FlashGetDownloadUrlReqInner6 {
|
||||
field1?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface FlashGetDownloadUrlReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
inner?: pb<2, FlashGetDownloadUrlReqInner>;
|
||||
field3?: pb<3, uint_32>; // 7
|
||||
field4?: pb<4, uint_32>; // 1
|
||||
}
|
||||
/** 0x93d4 响应 f1.f3.f13.f2 — downloadUrl 包装(结构不同于 0x93d3 的 FlashFileDownloadInfo)。 */
|
||||
export interface FlashDownloadUrlWrap {
|
||||
field1?: pb<1, uint_32>; // 2
|
||||
downloadUrl?: pb<2, string>;
|
||||
}
|
||||
/** 0x93d4 响应 f1.f3.f13 — fileId + downloadUrl + sha1/md5/宽高。 */
|
||||
export interface FlashDownloadUrlInfo {
|
||||
fileId?: pb<1, string>;
|
||||
download?: pb<2, FlashDownloadUrlWrap>;
|
||||
sha1?: pb<3, string>;
|
||||
field4?: pb<4, uint_32>;
|
||||
md5?: pb<5, string>;
|
||||
width?: pb<6, uint_32>;
|
||||
height?: pb<7, uint_32>;
|
||||
}
|
||||
/** 0x93d4 响应 f1.f3.f14 — 主文件 fileId(无 downloadUrl,下载 URL 需 0x12a9 sub=200)。 */
|
||||
export interface FlashDownloadMainFile {
|
||||
fileId?: pb<1, string>;
|
||||
field3?: pb<3, uint_32>; // 2
|
||||
}
|
||||
/** 0x93d4 响应 f1.f3 — 文件信息(字段号不同于 0x93d3 的 FlashFileEntry)。 */
|
||||
export interface FlashDownloadFileInfo {
|
||||
filesetUuid?: pb<1, string>;
|
||||
fileUuid?: pb<2, string>;
|
||||
field5?: pb<5, uint_32>;
|
||||
field6?: pb<6, uint_32>;
|
||||
field7?: pb<7, uint_32>;
|
||||
fileName?: pb<8, string>;
|
||||
origName?: pb<9, string>;
|
||||
fileSize?: pb<11, uint_64>;
|
||||
downloadInfo?: pb<13, FlashDownloadUrlInfo>;
|
||||
mainFile?: pb<14, FlashDownloadMainFile>;
|
||||
}
|
||||
/** 0x93d4 响应 f1 — entry wrapper。多文件 fileset 时 f3 含每个文件的 fileInfo。 */
|
||||
export interface FlashDownloadEntry {
|
||||
field2?: pb<2, uint_32>; // 1
|
||||
/** repeated:多文件 fileset 时每个文件一个 fileInfo(f6=文件序号,f14=主文件 fileId)。 */
|
||||
fileInfo?: pb_repeated<3, FlashDownloadFileInfo>;
|
||||
field4?: pb<4, string>; // JSON:{"offset":N,"cursor_time":"..."}
|
||||
field5?: pb<5, uint_32>; // 1
|
||||
}
|
||||
/** 0x93d4 响应 — downloadUrl 在 f1.f3.f13.f2.f2(深层嵌套,非 0x93d3 的 f9.fileIdWrap)。 */
|
||||
export interface FlashGetDownloadUrlResp {
|
||||
entry?: pb<1, FlashDownloadEntry>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x9407 — 删除闪传文件(额外,OneBot 标准未定义) ───────────────
|
||||
|
||||
export interface FlashDeleteFileReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
field2?: pb<2, string>; // ""
|
||||
field3?: pb<3, uint_32>; // 7
|
||||
}
|
||||
export interface FlashDeleteFileResp {}
|
||||
|
||||
// ─────────────── 0x9427 — 重命名闪传文件(额外,OneBot 标准未定义) ───────────────
|
||||
|
||||
export interface FlashRenameFileReqName {
|
||||
newName?: pb<1, string>;
|
||||
displayName?: pb<2, string>;
|
||||
}
|
||||
export interface FlashRenameFileReqFlag {
|
||||
field1?: pb<1, uint_32>;
|
||||
}
|
||||
export interface FlashRenameFileReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
name?: pb<2, FlashRenameFileReqName>;
|
||||
flag?: pb<3, FlashRenameFileReqFlag>;
|
||||
}
|
||||
export interface FlashRenameFileResp {}
|
||||
|
||||
// ─────────────── 0x93cf — 申请创建 fileSet(上传起点) ───────────────
|
||||
|
||||
/** 空占位 message(Uploader.f4 / CommitInfo.f4 / f24 为空 message)。 */
|
||||
export interface FlashEmpty {}
|
||||
|
||||
export interface FlashUploader {
|
||||
uin?: pb<1, string>;
|
||||
nickname?: pb<2, string>;
|
||||
uid?: pb<3, string>;
|
||||
field4?: pb<4, FlashEmpty>;
|
||||
}
|
||||
|
||||
/** 0x93cf 请求 f2 — 文件信息。 */
|
||||
export interface FlashUploadFileInfo {
|
||||
fileName?: pb<2, string>;
|
||||
origName?: pb<3, string>;
|
||||
fileType?: pb<4, uint_32>;
|
||||
fileSize?: pb<5, uint_64>;
|
||||
uploader?: pb<10, FlashUploader>;
|
||||
field16?: pb<16, uint_32>;
|
||||
field20?: pb<20, uint_32>;
|
||||
field21?: pb<21, uint_32>;
|
||||
}
|
||||
|
||||
export interface FlashApplyFilesetReq {
|
||||
field1?: pb<1, uint_32>; // 1
|
||||
fileInfo?: pb<2, FlashUploadFileInfo>;
|
||||
/** 文件类型码:rar=2, png/mp4=7(按扩展名映射,FlashTransferApi.fileTypeCode)。 */
|
||||
typeCode?: pb<3, uint_32>;
|
||||
field12?: pb<12, uint_32>; // 1
|
||||
}
|
||||
export interface FlashApplyFilesetResp {
|
||||
filesetUuid?: pb<1, string>;
|
||||
/** 上传会话 key(与 f1 同值)。 */
|
||||
uploadKey?: pb<2, string>;
|
||||
/** 上传 URL https://qfile.qq.com/q/<code>。 */
|
||||
uploadUrl?: pb<3, string>;
|
||||
expire?: pb<4, uint_64>;
|
||||
ttl?: pb<5, uint_32>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93d0 — 单文件上传完成上报(commit) ───────────────
|
||||
|
||||
export interface FlashCommitFileInfo {
|
||||
filesetUuid?: pb<1, string>;
|
||||
fileUuid?: pb<2, string>;
|
||||
/** pb_optional 强制 0 值上 wire(服务端多文件严格校验字段存在,省略 0 会导致文件不计入)。 */
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field4?: pb<4, FlashEmpty>;
|
||||
field5?: pb_optional<5, uint_32>;
|
||||
/** 文件序号:fileset 内从 1 递增(1,2,3...),多文件时每条各不相同。
|
||||
* 必须与 0x12a9 sub=100/103 filesetWrap.f4 一致,否则服务端不把文件计入 fileset。 */
|
||||
field6?: pb_optional<6, uint_32>;
|
||||
/** 格式码:rar=4, mp4=2, png=26(按扩展名映射)。 */
|
||||
formatCode?: pb_optional<7, uint_32>;
|
||||
fileName?: pb<8, string>;
|
||||
origName?: pb<9, string>;
|
||||
field10?: pb_optional<10, uint_32>;
|
||||
fileSize?: pb<11, uint_64>;
|
||||
field12?: pb_optional<12, uint_32>;
|
||||
field24?: pb<24, FlashEmpty>;
|
||||
}
|
||||
|
||||
export interface FlashCommitFileReq {
|
||||
field1?: pb<1, uint_32>; // 1
|
||||
filesetUuid?: pb<2, string>;
|
||||
uploadKey?: pb<3, string>; // 同 filesetUuid
|
||||
/** repeated:一个 0x93d0 请求同时携带 fileset 内所有文件条目(多文件机制)。
|
||||
* 每条 field6=文件序号(1,2,3...)。单文件时只有一个条目。 */
|
||||
commitInfo?: pb_repeated<4, FlashCommitFileInfo>;
|
||||
field5?: pb<5, uint_32>; // 1
|
||||
field6?: pb<6, uint_32>; // 1
|
||||
}
|
||||
export interface FlashCommitFileResp {
|
||||
field1?: pb<1, uint_32>;
|
||||
filesetUuid?: pb<2, string>;
|
||||
uploadKey?: pb<3, string>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93db — fileSet 完成 ───────────────
|
||||
|
||||
export interface FlashCompleteFilesetReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
field2?: pb<2, string>; // ""
|
||||
}
|
||||
export interface FlashCompleteFilesetResp {}
|
||||
|
||||
// ─────────────── 0x93d1 — 设置 fileSet 状态 ───────────────
|
||||
|
||||
export interface FlashSetStatusReq {
|
||||
filesetUuid?: pb<1, string>;
|
||||
status?: pb<2, uint_32>; // 6
|
||||
}
|
||||
export interface FlashSetStatusResp {}
|
||||
|
||||
// ─────────────── sliceupload(大文件分片上传) ───────────────
|
||||
|
||||
/** sliceupload f107.f6 — 累积 SHA1 state list。每片对应从文件开头到该片末尾的
|
||||
* SHA1 中间 state(不 finalize,小端 20B),最后一片是标准整文件 SHA1。
|
||||
* 服务端按此校验分片完整性,传独立分片 SHA1 会被拒(报 "file range data sha1 not match")。 */
|
||||
export interface FlashSha1StateV {
|
||||
state?: pb_repeated<1, bytes>;
|
||||
}
|
||||
|
||||
/** sliceupload body f107 — 切片 payload。 */
|
||||
export interface FlashSlicePayload {
|
||||
field1?: pb<1, FlashEmpty>;
|
||||
rkey?: pb<2, string>; // 上传凭证(来自 sub=100 响应)
|
||||
start?: pb_optional<3, uint_32>; // 本片字节 offset
|
||||
end?: pb_optional<4, uint_32>; // start + chunkLen - 1
|
||||
sha1?: pb<5, bytes>; // 当前片 SHA1
|
||||
sha1StateV?: pb<6, FlashSha1StateV>;
|
||||
chunk?: pb<7, bytes>; // 本片文件字节
|
||||
}
|
||||
|
||||
/** sliceupload HTTP body — POST multimedia.qfile.qq.com/sliceupload。 */
|
||||
export interface FlashSliceUploadBody {
|
||||
field1?: pb_optional<1, uint_32>; // 0
|
||||
appid?: pb<2, uint_32>; // 14901(与 fileId 的 appid 不同)
|
||||
field3?: pb_optional<3, uint_32>; // 2
|
||||
payload?: pb<107, FlashSlicePayload>;
|
||||
}
|
||||
|
||||
/** sliceupload HTTP 响应 — f5=status,"success" 表示该片已落盘。 */
|
||||
export interface FlashSliceUploadResp {
|
||||
status?: pb<5, string>;
|
||||
}
|
||||
|
||||
/** sub=103 wrapper.f2 fileId — 客户端构造的 protobuf,base64url 编码。
|
||||
* appid 用 14902:下载 URL(0x93d4 返回)的 appid 也是 14902,两者必须一致,
|
||||
* 否则下载报 "appid is not match"。sliceupload body 的 appid 则用 14901。 */
|
||||
export interface FlashFileId {
|
||||
sha1?: pb<2, bytes>; // 整文件 SHA1
|
||||
fileSize?: pb<3, uint_32>;
|
||||
appid?: pb<4, uint_32>; // 14902
|
||||
timestamp?: pb<5, uint_64>; // 微秒时间戳
|
||||
env?: pb<6, string>; // "prod"
|
||||
ttl?: pb<10, uint_32>; // 1209600(14 天)
|
||||
sessionId?: pb<11, bytes>; // 16B,随机生成
|
||||
field15?: pb<15, bytes>; // 3B
|
||||
region?: pb<16, string>; // "gz"
|
||||
}
|
||||
|
||||
// ─────────────── 0x12a9 sub=100/103 — prepare/apply-upload ───────────────
|
||||
// sub=100 与 sub=103 的 payload 字段号不同:sub=100 在 f2,sub=103 在 f12。
|
||||
// sub=100 返回 sliceupload rkey;sub=103 注册 fileId,响应无 rkey。
|
||||
// 下面的类型描述 sub=103 的 f12 结构(sub=100 的 f2 结构对应 FlashPrepareUploadPayload)。
|
||||
|
||||
/** FileInfo.f5 — f4 是 varint,与 FlashApplyPayloadField3.f4 的 message 类型不同。
|
||||
* pb_optional 保证 0 值显式上 wire,服务端要求字段存在。 */
|
||||
export interface FlashApplyFileInfo5 {
|
||||
field1?: pb_optional<1, uint_32>; // sub=100=1 / sub=103=0
|
||||
field2?: pb_optional<2, uint_32>;
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field4?: pb_optional<4, uint_32>;
|
||||
}
|
||||
|
||||
/** f12.f3 — f4 是空 message,与 FileInfo5.f4 的 varint 类型不同。 */
|
||||
export interface FlashApplyPayloadField3 {
|
||||
field1?: pb_optional<1, uint_32>;
|
||||
field2?: pb_optional<2, uint_32>;
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field4?: pb<4, FlashEmpty>;
|
||||
}
|
||||
|
||||
/** f12.f10 — fileset 包装(filesetUuid + fileUuid + flags)。 */
|
||||
export interface FlashApplyFilesetWrap {
|
||||
filesetUuid?: pb_optional<1, string>;
|
||||
uploadKey?: pb_optional<2, string>; // 同 filesetUuid
|
||||
fileUuid?: pb_optional<3, string>;
|
||||
field4?: pb_optional<4, uint_32>; // 1
|
||||
field5?: pb_optional<5, uint_32>; // 0
|
||||
field6?: pb_optional<6, uint_32>; // sub=100=0 / sub=103=1
|
||||
field7?: pb_optional<7, uint_32>; // 2
|
||||
field8?: pb<8, FlashEmpty>;
|
||||
field9?: pb_optional<9, uint_32>; // 1
|
||||
field10?: pb_optional<10, uint_32>;
|
||||
field11?: pb_optional<11, uint_32>;
|
||||
field12?: pb_optional<12, uint_32>;
|
||||
field13?: pb_optional<13, uint_32>;
|
||||
field14?: pb_optional<14, uint_32>;
|
||||
}
|
||||
|
||||
/** 0x12a9 f12.f1.f1 — FileInfo。 */
|
||||
export interface FlashApplyFileInfo {
|
||||
fileSize?: pb_optional<1, uint_32>;
|
||||
md5?: pb_optional<2, string>; // 32 hex(sub=100 空,sub=103 有)
|
||||
sha1?: pb_optional<3, string>; // 40 hex
|
||||
fileName?: pb_optional<4, string>;
|
||||
field5?: pb<5, FlashApplyFileInfo5>;
|
||||
field6?: pb_optional<6, uint_32>;
|
||||
field7?: pb_optional<7, uint_32>;
|
||||
field8?: pb_optional<8, uint_32>;
|
||||
field9?: pb_optional<9, uint_32>; // sub=100=0 / sub=103=1
|
||||
}
|
||||
|
||||
/** 0x12a9 f12.f1 — wrapper(FileInfo + fileId + 时间戳/TTL)。 */
|
||||
export interface FlashApplyUploadWrapper {
|
||||
fileInfo?: pb<1, FlashApplyFileInfo>;
|
||||
fileId?: pb_optional<2, string>; // sub=100 不带,sub=103 带
|
||||
field3?: pb_optional<3, uint_32>; // 1
|
||||
field4?: pb_optional<4, uint_32>; // 时间戳
|
||||
field5?: pb_optional<5, uint_32>; // TTL 1209600(14 天)
|
||||
field6?: pb_optional<6, uint_32>;
|
||||
}
|
||||
|
||||
/** 0x12a9 f12 — apply-upload payload。 */
|
||||
export interface FlashApplyUploadPayload {
|
||||
wrapper?: pb<1, FlashApplyUploadWrapper>;
|
||||
flag2?: pb<2, FlashApplyFlag2>; // {f1:2}
|
||||
field3?: pb<3, FlashApplyPayloadField3>; // {f1:0,f2:0,f3:0,f4:{}}
|
||||
filesetWrap?: pb<10, FlashApplyFilesetWrap>;
|
||||
}
|
||||
export interface FlashApplyFlag2 {
|
||||
field1?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
/** 0x12a9 请求 f1 — head(seq + sub + config)。 */
|
||||
export interface FlashApplyHeadSub {
|
||||
seq?: pb<1, uint_32>;
|
||||
sub?: pb<2, uint_32>;
|
||||
}
|
||||
export interface FlashApplyHeadConfig {
|
||||
field101?: pb<101, uint_32>;
|
||||
field102?: pb<102, uint_32>;
|
||||
field103?: pb<103, uint_32>; // 文件类型:jpg=24 / png=23 / mp4=22
|
||||
field200?: pb<200, uint_32>;
|
||||
}
|
||||
export interface FlashApplyHead {
|
||||
sub?: pb<1, FlashApplyHeadSub>;
|
||||
config?: pb<2, FlashApplyHeadConfig>;
|
||||
field3?: pb<3, FlashApplyFlag2>; // {f1:1}
|
||||
}
|
||||
|
||||
/** 0x12a9 sub=103 请求(payload @ f12)。 */
|
||||
export interface FlashApplyUploadReq {
|
||||
head?: pb<1, FlashApplyHead>;
|
||||
payload?: pb<12, FlashApplyUploadPayload>;
|
||||
}
|
||||
|
||||
/** 0x12a9 apply-upload 响应 — rkey 在 f2。 */
|
||||
export interface FlashApplyUploadResp {
|
||||
head?: pb<1, FlashApplyHeadResp>;
|
||||
rkeyWrap?: pb<2, FlashRkeyWrap>;
|
||||
}
|
||||
export interface FlashApplyHeadResp {
|
||||
sub?: pb<1, FlashApplyHeadSub>;
|
||||
msg?: pb<3, string>; // "success"
|
||||
}
|
||||
export interface FlashRkeyWrap {
|
||||
rkey?: pb<1, string>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x12a9 sub=100 — prepare-upload ───────────────
|
||||
// sub=100 的 payload 在 f2(sub=103 在 f12),filesetWrap 在 f9(sub=103 在 f10),
|
||||
// wrapper.f2 是 varint 0(sub=103 是 fileId string)。
|
||||
/** sub=100 payload.f6.f1。 */
|
||||
export interface FlashPreparePayloadF6F1 {
|
||||
field1?: pb_optional<1, uint_32>;
|
||||
field2?: pb<2, FlashEmpty>;
|
||||
}
|
||||
/** sub=100 payload.f6.f2。 */
|
||||
export interface FlashPreparePayloadF6F2 {
|
||||
field3?: pb<3, FlashEmpty>;
|
||||
}
|
||||
/** sub=100 payload.f6.f3。 */
|
||||
export interface FlashPreparePayloadF6F3 {
|
||||
field11?: pb<11, FlashEmpty>;
|
||||
field12?: pb<12, FlashEmpty>;
|
||||
}
|
||||
/** sub=100 payload.f6 — 嵌套 message(固定值)。 */
|
||||
export interface FlashPreparePayloadF6 {
|
||||
field1?: pb<1, FlashPreparePayloadF6F1>;
|
||||
field2?: pb<2, FlashPreparePayloadF6F2>;
|
||||
field3?: pb<3, FlashPreparePayloadF6F3>;
|
||||
field10?: pb_optional<10, uint_32>;
|
||||
}
|
||||
/** sub=100 wrapper — f2 是 varint 0(sub=103 是 fileId)。 */
|
||||
export interface FlashPrepareWrapper {
|
||||
fileInfo?: pb<1, FlashApplyFileInfo>;
|
||||
field2?: pb_optional<2, uint_32>;
|
||||
}
|
||||
/** sub=100 payload。 */
|
||||
export interface FlashPrepareUploadPayload {
|
||||
wrapper?: pb<1, FlashPrepareWrapper>;
|
||||
field2?: pb_optional<2, uint_32>; // 1
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
field4?: pb_optional<4, uint_32>;
|
||||
field5?: pb_optional<5, uint_32>;
|
||||
field6?: pb<6, FlashPreparePayloadF6>;
|
||||
field7?: pb_optional<7, uint_32>;
|
||||
field8?: pb_optional<8, uint_32>;
|
||||
filesetWrap?: pb<9, FlashApplyFilesetWrap>; // f9(sub=103 在 f10);f6=0(sub=103=1)
|
||||
}
|
||||
/** sub=100 请求 — payload 在 f2(sub=103 在 f12)。 */
|
||||
export interface FlashPrepareUploadReq {
|
||||
head?: pb<1, FlashApplyHead>;
|
||||
payload?: pb<2, FlashPrepareUploadPayload>;
|
||||
}
|
||||
/** sub=100 响应 — f2.f1 是 sliceupload rkey;秒传时 f1 缺失(deserialize 返回 null)。 */
|
||||
export interface FlashPrepareUploadResp {
|
||||
head?: pb<1, FlashApplyHeadResp>;
|
||||
rkeyWrap?: pb<2, FlashRkeyWrap>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x93d7 — 发送闪传文件给用户(send_flash_msg) ───────────────
|
||||
// 请求 f1={f1:1, f2:{f1:targetUid}}, f2=filesetUuid(私聊);
|
||||
// f1={f1:2, f3:{f1:groupId}}, f2=filesetUuid(群聊)。响应仅回显目标(无 message_id)。
|
||||
/** 0x93d7 请求 f1.f2 — 私聊目标 uid 包装。 */
|
||||
export interface FlashSendTargetUid {
|
||||
targetUid?: pb<1, string>;
|
||||
}
|
||||
/** 0x93d7 请求 f1.f3 — 群聊目标 groupId 包装。 */
|
||||
export interface FlashSendTargetGroupId {
|
||||
groupId?: pb<1, uint_32>;
|
||||
}
|
||||
/** 0x93d7 请求 f1 — 发送目标。私聊 f1=1+f2(uid),群聊 f1=2+f3(groupId)。 */
|
||||
export interface FlashSendTarget {
|
||||
field1?: pb<1, uint_32>;
|
||||
targetUid?: pb<2, FlashSendTargetUid>;
|
||||
targetGroup?: pb<3, FlashSendTargetGroupId>;
|
||||
}
|
||||
/** 0x93d7 请求。 */
|
||||
export interface FlashSendReq {
|
||||
target?: pb<1, FlashSendTarget>;
|
||||
filesetUuid?: pb<2, string>;
|
||||
}
|
||||
/** 0x93d7 响应 f1.f3 — 回显目标。 */
|
||||
export interface FlashSendRespEcho {
|
||||
target?: pb<3, FlashSendTarget>;
|
||||
}
|
||||
/** 0x93d7 响应 — 仅回显目标,无 message_id(分享 fileset,非传统消息)。 */
|
||||
export interface FlashSendResp {
|
||||
echo?: pb<1, FlashSendRespEcho>;
|
||||
}
|
||||
|
||||
// ─────────────── 0x12a9 sub=200 — get-download(主文件下载直链)───────────────
|
||||
// 请求 payload @ f3(不同于 sub=100 的 f2 / sub=103 的 f12)。响应 f3 含 rkey + 主文件下载 URL。
|
||||
// 主文件下载 URL(appid=14901)的唯一来源;0x93d3/0x93d4 的 downloadUrl 是缩略图。
|
||||
/** sub=200 请求 f3.f1.f1 — FileInfo(简化,只 fileName)。 */
|
||||
export interface FlashGetDownloadFileInfo {
|
||||
field1?: pb<1, uint_32>; // 0
|
||||
field4?: pb<4, string>; // fileName
|
||||
field5?: pb<5, FlashApplyFileInfo5>; // {0,0,0,0}
|
||||
field6?: pb<6, uint_32>; // 0
|
||||
field7?: pb<7, uint_32>; // 0
|
||||
field8?: pb<8, uint_32>; // 0
|
||||
field9?: pb<9, uint_32>; // 0
|
||||
}
|
||||
/** sub=200 请求 f3.f1 — wrapper(FileInfo + 主文件 fileId)。 */
|
||||
export interface FlashGetDownloadWrapper {
|
||||
fileInfo?: pb<1, FlashGetDownloadFileInfo>;
|
||||
fileId?: pb<2, string>; // 主文件 fileId(来自 0x93d4 f14.f1)
|
||||
field3?: pb<3, uint_32>; // 0
|
||||
field4?: pb<4, uint_32>; // 0
|
||||
field5?: pb<5, uint_32>; // 0
|
||||
field6?: pb<6, uint_32>; // 0
|
||||
}
|
||||
/** sub=200 请求 f3.f2.f2 — 固定下载参数(真客户端实测值,未观察到随文件变化)。 */
|
||||
export interface FlashGetDownloadParam {
|
||||
field1?: pb<1, uint_32>; // 4294967294
|
||||
field3?: pb<3, uint_32>; // 4294967295
|
||||
field5?: pb<5, uint_32>; // 111
|
||||
field6?: pb<6, FlashGetDownloadParam6>;
|
||||
}
|
||||
export interface FlashGetDownloadParam6 {
|
||||
field1?: pb<1, uint_32>; // 3403722988
|
||||
}
|
||||
export interface FlashGetDownloadFlag4 {
|
||||
field1?: pb<1, uint_32>;
|
||||
}
|
||||
/** sub=200 请求 f3.f2.f10 — filesetWrap(filesetUuid + fileUuid)。 */
|
||||
export interface FlashGetDownloadFilesetWrap {
|
||||
filesetUuid?: pb<1, string>;
|
||||
fileUuid?: pb<2, string>;
|
||||
field3?: pb<3, uint_32>; // 2
|
||||
field4?: pb<4, string>; // fileUuid
|
||||
}
|
||||
/** sub=200 请求 f3.f2。 */
|
||||
export interface FlashGetDownloadPayload2 {
|
||||
field2?: pb<2, FlashGetDownloadParam>;
|
||||
field4?: pb<4, FlashGetDownloadFlag4>;
|
||||
filesetWrap?: pb<10, FlashGetDownloadFilesetWrap>;
|
||||
}
|
||||
/** sub=200 请求 f3 — payload。 */
|
||||
export interface FlashGetDownloadPayload {
|
||||
wrapper?: pb<1, FlashGetDownloadWrapper>;
|
||||
field2?: pb<2, FlashGetDownloadPayload2>;
|
||||
field3?: pb<3, uint_32>; // 0
|
||||
}
|
||||
/** sub=200 请求 — payload @ f3。 */
|
||||
export interface FlashGetDownloadReq {
|
||||
head?: pb<1, FlashApplyHead>; // sub:200
|
||||
payload?: pb<3, FlashGetDownloadPayload>;
|
||||
}
|
||||
/** sub=200 响应 — f3 含 rkey + 主文件下载 URL(bytes,deserialize 正则提取 URL)。 */
|
||||
export interface FlashGetDownloadResp {
|
||||
head?: pb<1, FlashApplyHeadResp>;
|
||||
body?: pb<3, bytes>;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import type { pb, pb_optional, pb_repeated, bytes, uint_32, uint_64 } from '@snowluma/proton';
|
||||
|
||||
export interface GroupAdminPermissionItem {
|
||||
item?: pb<1, uint_32>;
|
||||
value?: pb<2, uint_32>;
|
||||
extra?: pb<3, bytes>;
|
||||
}
|
||||
|
||||
export interface GroupAdminKickLimit {
|
||||
maxKickPerDay?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface SetGroupAdminPermissionsRequest {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
memberUin?: pb<2, uint_64>;
|
||||
permissions?: pb_repeated<3, GroupAdminPermissionItem>;
|
||||
}
|
||||
|
||||
export interface GroupAdminPermissionsFilter {
|
||||
permissions?: pb<52, bytes>;
|
||||
}
|
||||
|
||||
export interface GetGroupAdminPermissionsRequest {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
memberUins?: pb_repeated<2, uint_64>;
|
||||
filter?: pb<4, GroupAdminPermissionsFilter>;
|
||||
}
|
||||
|
||||
export interface GroupAdminPermissions {
|
||||
items?: pb_repeated<1, GroupAdminPermissionItem>;
|
||||
}
|
||||
|
||||
export interface GroupAdminPermissionsExt {
|
||||
permissions?: pb<52, GroupAdminPermissions>;
|
||||
}
|
||||
|
||||
export interface GroupAdminPermissionsMember {
|
||||
memberUin?: pb<1, uint_64>;
|
||||
ext?: pb<3, GroupAdminPermissionsExt>;
|
||||
}
|
||||
|
||||
export interface GetGroupAdminPermissionsResponse {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
members?: pb_repeated<3, GroupAdminPermissionsMember>;
|
||||
}
|
||||
|
||||
export interface GroupAdminReceiveVerifyOperation {
|
||||
adminUins?: pb_repeated<1, uint_64>;
|
||||
authority?: pb<2, uint_32>;
|
||||
operate?: pb_optional<3, uint_32>;
|
||||
}
|
||||
|
||||
export interface SetGroupAdminReceiveVerifyRequest {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
operation?: pb<2, GroupAdminReceiveVerifyOperation>;
|
||||
}
|
||||
|
||||
export interface GroupAdminReceiveVerifyResult {
|
||||
successfulUins?: pb_repeated<1, uint_64>;
|
||||
}
|
||||
|
||||
export interface SetGroupAdminReceiveVerifyResponse {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
result?: pb<2, GroupAdminReceiveVerifyResult>;
|
||||
}
|
||||
|
||||
export interface GroupAdminReceiveVerifyIdentity {
|
||||
uid?: pb<2, string>;
|
||||
uin?: pb_optional<4, uint_64>;
|
||||
}
|
||||
|
||||
export interface GroupAdminReceiveVerifyFilter {
|
||||
memberFlagExt?: pb<104, uint_32>;
|
||||
}
|
||||
|
||||
export interface GetGroupAdminReceiveVerifyRequest {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb_optional<3, uint_32>;
|
||||
filter?: pb<4, GroupAdminReceiveVerifyFilter>;
|
||||
members?: pb_repeated<5, GroupAdminReceiveVerifyIdentity>;
|
||||
}
|
||||
|
||||
export interface GroupAdminReceiveVerifyMember {
|
||||
identity?: pb<1, GroupAdminReceiveVerifyIdentity>;
|
||||
memberFlagExt?: pb_optional<104, uint_32>;
|
||||
}
|
||||
|
||||
export interface GetGroupAdminReceiveVerifyResponse {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
members?: pb_repeated<2, GroupAdminReceiveVerifyMember>;
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
import type {
|
||||
pb,
|
||||
pb_optional,
|
||||
pb_repeated,
|
||||
int_32,
|
||||
uint_32,
|
||||
uint_64,
|
||||
bool,
|
||||
bytes,
|
||||
} from '@snowluma/proton';
|
||||
|
||||
export interface ExtMapEntry {
|
||||
key?: pb<1, string>;
|
||||
value?: pb<2, string>;
|
||||
}
|
||||
|
||||
// QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.GetAlbumList
|
||||
//
|
||||
// Recovered from QQ NT's AlbumService codec. The service uses the same
|
||||
// common request/response envelope as the other QunAlbum methods in this
|
||||
// file; the operation-specific request body only contains the group id and
|
||||
// the pagination cursor.
|
||||
export interface GetAlbumListReqData {
|
||||
groupId?: pb<1, string>;
|
||||
attachInfo?: pb_optional<2, string>;
|
||||
}
|
||||
export interface GetAlbumListRequest {
|
||||
seq?: pb<1, int_32>;
|
||||
field2?: pb_optional<2, bytes>;
|
||||
field3?: pb_optional<3, bytes>;
|
||||
data?: pb<4, GetAlbumListReqData>;
|
||||
traceId?: pb<5, string>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface AlbumCreator {
|
||||
uid?: pb<1, string>;
|
||||
nick?: pb<2, string>;
|
||||
isSweet?: pb<5, bool>;
|
||||
isSpecial?: pb<6, bool>;
|
||||
isSuperLike?: pb<7, bool>;
|
||||
customId?: pb<8, string>;
|
||||
polyId?: pb<9, string>;
|
||||
portrait?: pb<10, string>;
|
||||
canFollow?: pb<11, int_32>;
|
||||
isFollowed?: pb<12, int_32>;
|
||||
uin?: pb<13, string>;
|
||||
dittoUin?: pb<14, string>;
|
||||
}
|
||||
export interface GroupAlbumInfo {
|
||||
albumId?: pb<1, string>;
|
||||
owner?: pb<2, string>;
|
||||
name?: pb<3, string>;
|
||||
description?: pb<4, string>;
|
||||
createTime?: pb<5, uint_64>;
|
||||
modifyTime?: pb<6, uint_64>;
|
||||
lastUploadTime?: pb<7, uint_64>;
|
||||
uploadNumber?: pb<8, uint_64>;
|
||||
// QQ NT AlbumCodec_DecodeAlbumInfo tag 9 reuses the media-list MediaInfo codec.
|
||||
cover?: pb<9, MediaInfo>;
|
||||
creator?: pb<10, AlbumCreator>;
|
||||
topFlag?: pb<11, uint_64>;
|
||||
busiType?: pb<12, int_32>;
|
||||
status?: pb<13, int_32>;
|
||||
allowShare?: pb<15, bool>;
|
||||
isSubscribe?: pb<16, bool>;
|
||||
bitmap?: pb<17, string>;
|
||||
isShareAlbum?: pb<18, bool>;
|
||||
qzAlbumType?: pb<20, int_32>;
|
||||
coverType?: pb<23, int_32>;
|
||||
defaultDesc?: pb<26, string>;
|
||||
sortType?: pb<30, int_32>;
|
||||
}
|
||||
export interface GetAlbumListRspData {
|
||||
albumList?: pb_repeated<1, GroupAlbumInfo>;
|
||||
attachInfo?: pb<2, string>;
|
||||
hasMore?: pb<3, bool>;
|
||||
}
|
||||
export interface GetAlbumListResponse {
|
||||
seq?: pb<1, int_32>;
|
||||
result?: pb<2, int_32>;
|
||||
errorText?: pb<3, string>;
|
||||
data?: pb<4, GetAlbumListRspData>;
|
||||
}
|
||||
|
||||
export interface ReqInfo {
|
||||
groupId?: pb<1, string>;
|
||||
albumId?: pb<2, string>;
|
||||
field3?: pb<3, int_32>;
|
||||
field4?: pb<4, string>;
|
||||
pageInfo?: pb<5, string>;
|
||||
}
|
||||
export interface GetMediaListRequest {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, bytes>;
|
||||
field3?: pb<3, bytes>;
|
||||
reqInfo?: pb<4, ReqInfo>;
|
||||
traceId?: pb<5, string>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface UrlInfo {
|
||||
url?: pb<1, string>;
|
||||
width?: pb<2, uint_32>;
|
||||
height?: pb<3, uint_32>;
|
||||
}
|
||||
export interface PhotoUrl {
|
||||
spec?: pb<1, uint_32>;
|
||||
url?: pb<2, UrlInfo>;
|
||||
}
|
||||
export interface ImageInfo {
|
||||
name?: pb<1, string>;
|
||||
sloc?: pb<2, string>;
|
||||
lloc?: pb<3, string>;
|
||||
photoUrls?: pb_repeated<4, PhotoUrl>;
|
||||
defaultUrl?: pb<5, UrlInfo>;
|
||||
isGif?: pb<6, bool>;
|
||||
hasRaw?: pb<7, bool>;
|
||||
}
|
||||
export interface VideoInfo {
|
||||
id?: pb<1, string>;
|
||||
url?: pb<2, string>;
|
||||
cover?: pb<3, ImageInfo>;
|
||||
width?: pb<4, uint_32>;
|
||||
height?: pb<5, uint_32>;
|
||||
videoTime?: pb<6, uint_64>;
|
||||
videoUrl?: pb_repeated<7, PhotoUrl>;
|
||||
}
|
||||
export interface MediaInfo {
|
||||
type?: pb<1, uint_32>;
|
||||
image?: pb<2, ImageInfo>;
|
||||
video?: pb<3, VideoInfo>;
|
||||
uploader?: pb<6, string>;
|
||||
batchId?: pb<7, uint_64>;
|
||||
uploadTime?: pb<8, uint_64>;
|
||||
}
|
||||
export interface GetMediaListAlbumInfo {
|
||||
albumId?: pb<1, string>;
|
||||
owner?: pb<2, string>;
|
||||
name?: pb<3, string>;
|
||||
}
|
||||
export interface GetMediaListRspData {
|
||||
albumInfo?: pb<1, GetMediaListAlbumInfo>;
|
||||
mediaList?: pb_repeated<3, MediaInfo>;
|
||||
prevAttachInfo?: pb<4, string>;
|
||||
nextAttachInfo?: pb<5, string>;
|
||||
}
|
||||
export interface GetMediaListResponse {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, bytes>;
|
||||
field3?: pb<3, bytes>;
|
||||
data?: pb<4, GetMediaListRspData>;
|
||||
}
|
||||
export interface CommentContentItem {
|
||||
// Text cells on the wire include type 0. A plain pb<> field would omit it.
|
||||
type?: pb_optional<1, uint_32>;
|
||||
content?: pb<2, string>;
|
||||
}
|
||||
export interface CommentUser {
|
||||
uin?: pb<13, string>;
|
||||
uinNum?: pb<14, uint_64>;
|
||||
}
|
||||
export interface CommentReqContent {
|
||||
user?: pb<2, CommentUser>;
|
||||
// QQ NT FeedWorker writes StComment content cells as a repeated field.
|
||||
contents?: pb_repeated<3, CommentContentItem>;
|
||||
clientKey?: pb<7, string>;
|
||||
}
|
||||
// QQ NT FeedWorker copies StFeed media cells with the MediaInfo codec.
|
||||
export interface CommentReqPhotoInfo {
|
||||
medias?: pb_repeated<1, MediaInfo>;
|
||||
albumId?: pb<3, string>;
|
||||
batchId?: pb<5, uint_64>;
|
||||
}
|
||||
export interface CommentReqBodyHeader {
|
||||
// Fallback only. A successful write copies the feed cellCommon bytes,
|
||||
// which also carry type, the 421 locator, and field 6.
|
||||
type?: pb<1, uint_32>;
|
||||
time?: pb<3, uint_64>;
|
||||
feedId?: pb<4, string>;
|
||||
cellId?: pb<5, string>;
|
||||
field6?: pb<6, uint_32>;
|
||||
}
|
||||
export interface CommentReqBodyUserWrap {
|
||||
field1?: pb<1, CommentUser>;
|
||||
}
|
||||
export interface CommentReqBody {
|
||||
// Raw length-delimited cells from GetQunFeedDetail. Re-encoding them
|
||||
// through the typed schemas drops fields QZone requires.
|
||||
field1?: pb<1, bytes>;
|
||||
field2?: pb<2, bytes>;
|
||||
field5?: pb<5, bytes>;
|
||||
}
|
||||
export interface DoQunCommentRequestBody {
|
||||
groupId?: pb<2, string>;
|
||||
field3?: pb<3, uint_32>;
|
||||
reqBody?: pb<4, CommentReqBody>;
|
||||
field5?: pb<5, CommentReqContent>;
|
||||
}
|
||||
export interface DoQunCommentRequest {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb_optional<2, bytes>;
|
||||
field3?: pb_optional<3, bytes>;
|
||||
body?: pb<4, DoQunCommentRequestBody>;
|
||||
traceId?: pb<5, string>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface CommentRespUser {
|
||||
uin?: pb<13, string>;
|
||||
}
|
||||
export interface CommentRespContent {
|
||||
type?: pb<1, uint_32>;
|
||||
content?: pb<2, string>;
|
||||
}
|
||||
export interface CommentRespData {
|
||||
id?: pb<1, string>;
|
||||
user?: pb<2, CommentRespUser>;
|
||||
content?: pb_repeated<3, CommentRespContent>;
|
||||
time?: pb<4, uint_64>;
|
||||
clientKey?: pb<7, string>;
|
||||
}
|
||||
export interface DoQunCommentResponseComment {
|
||||
id?: pb<1, string>;
|
||||
data?: pb<2, CommentRespData>;
|
||||
content?: pb_repeated<3, CommentRespContent>;
|
||||
time?: pb<4, uint_64>;
|
||||
clientKey?: pb<7, string>;
|
||||
}
|
||||
export interface DoQunCommentResponse {
|
||||
field1?: pb<1, int_32>;
|
||||
result?: pb<2, int_32>;
|
||||
errorText?: pb<3, string>;
|
||||
comment?: pb<4, DoQunCommentResponseComment>;
|
||||
}
|
||||
export interface DoQunLikeReqLikeInfo {
|
||||
id?: pb<1, string>;
|
||||
status?: pb<3, uint_32>;
|
||||
}
|
||||
export interface DoQunLikeReqCellCommon {
|
||||
time?: pb<3, uint_64>;
|
||||
feedId?: pb<4, string>;
|
||||
}
|
||||
export interface DoQunLikeReqCellUser {
|
||||
uin?: pb<13, string>;
|
||||
}
|
||||
export interface DoQunLikeReqCellUserInfo {
|
||||
user?: pb<1, DoQunLikeReqCellUser>;
|
||||
}
|
||||
export interface DoQunLikeReqCellQunInfo {
|
||||
qunId?: pb<1, string>;
|
||||
}
|
||||
export interface DoQunLikeReqCellMedia {
|
||||
albumId?: pb<3, string>;
|
||||
batchId?: pb<5, uint_64>;
|
||||
}
|
||||
export interface DoQunLikeReqFeedPublish {
|
||||
cellCommon?: pb<1, DoQunLikeReqCellCommon>;
|
||||
cellUserInfo?: pb<2, DoQunLikeReqCellUserInfo>;
|
||||
cellMedia?: pb<5, DoQunLikeReqCellMedia>;
|
||||
cellQunInfo?: pb<12, DoQunLikeReqCellQunInfo>;
|
||||
}
|
||||
export interface DoQunLikeReqBody {
|
||||
type?: pb<2, uint_32>;
|
||||
like?: pb<3, DoQunLikeReqLikeInfo>;
|
||||
publish?: pb<4, DoQunLikeReqFeedPublish>;
|
||||
clientKey?: pb<5, string>;
|
||||
}
|
||||
export interface DoQunLikeRequest {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, string>;
|
||||
field3?: pb<3, string>;
|
||||
body?: pb<4, DoQunLikeReqBody>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface DoQunLikeRespBody {
|
||||
like?: pb<2, DoQunLikeReqLikeInfo>;
|
||||
}
|
||||
export interface DoQunLikeResponse {
|
||||
field1?: pb<1, int_32>;
|
||||
body?: pb<4, DoQunLikeRespBody>;
|
||||
}
|
||||
// QunAlbum.trpc.qzone.webapp_qun_feeds.FeedsReader.GetQunFeedDetail
|
||||
//
|
||||
// Official album comments look this feed up first (empty feed id + album /
|
||||
// batch / lloc) and then copy the returned cell into DoQunComment.
|
||||
export interface GetQunFeedDetailReqData {
|
||||
groupId?: pb<2, string>;
|
||||
feedId?: pb<3, string>;
|
||||
commentCount?: pb<4, int_32>;
|
||||
attachInfo?: pb<5, string>;
|
||||
albumId?: pb<6, string>;
|
||||
batchId?: pb<7, string>;
|
||||
lloc?: pb<8, string>;
|
||||
}
|
||||
export interface GetQunFeedDetailRequest {
|
||||
seq?: pb<1, int_32>;
|
||||
field2?: pb_optional<2, bytes>;
|
||||
field3?: pb_optional<3, bytes>;
|
||||
data?: pb<4, GetQunFeedDetailReqData>;
|
||||
traceId?: pb<5, string>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface QunFeedCellCommon {
|
||||
type?: pb<1, uint_32>;
|
||||
time?: pb<3, uint_64>;
|
||||
feedId?: pb<4, string>;
|
||||
cellId?: pb<5, string>;
|
||||
field6?: pb<6, uint_32>;
|
||||
}
|
||||
export interface QunFeedCellUser {
|
||||
uin?: pb<13, string>;
|
||||
}
|
||||
export interface QunFeedCellUserInfo {
|
||||
user?: pb<1, QunFeedCellUser>;
|
||||
}
|
||||
export interface QunFeed {
|
||||
cellCommon?: pb<1, QunFeedCellCommon>;
|
||||
cellUserInfo?: pb<2, QunFeedCellUserInfo>;
|
||||
// FeedWorker copies this cell into DoQunComment body.4.5.
|
||||
cellMedia?: pb<5, CommentReqPhotoInfo>;
|
||||
}
|
||||
export interface QunClientFeed {
|
||||
feed?: pb<1, QunFeed>;
|
||||
}
|
||||
export interface GetQunFeedDetailRspData {
|
||||
feed?: pb<2, QunClientFeed>;
|
||||
}
|
||||
export interface GetQunFeedDetailResponse {
|
||||
seq?: pb<1, int_32>;
|
||||
result?: pb<2, int_32>;
|
||||
errorText?: pb<3, string>;
|
||||
data?: pb<4, GetQunFeedDetailRspData>;
|
||||
}
|
||||
export interface DeleteMediasReqBody {
|
||||
groupId?: pb<1, string>;
|
||||
albumId?: pb<2, string>;
|
||||
// deleteMedias 4th arg: photo lloc, or a video's cover lloc.
|
||||
mediaIds?: pb_repeated<3, string>;
|
||||
// deleteMedias 5th arg: matching batch ids. Android always sends these.
|
||||
batchIds?: pb_repeated<4, string>;
|
||||
}
|
||||
export interface DeleteMediasRequest {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, string>;
|
||||
field3?: pb<3, string>;
|
||||
body?: pb<4, DeleteMediasReqBody>;
|
||||
traceId?: pb<5, string>;
|
||||
extMap?: pb_repeated<10, ExtMapEntry>;
|
||||
}
|
||||
export interface DeleteMediasResponse {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, int_32>;
|
||||
field3?: pb<3, string>;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { pb, pb_optional, pb_repeated, uint_32 } from '@snowluma/proton';
|
||||
|
||||
/** One tag shown under a group-profile category. */
|
||||
export interface OidbGroupCategoryTag {
|
||||
id?: pb<1, uint_32>;
|
||||
name?: pb<2, string>;
|
||||
type?: pb<3, uint_32>;
|
||||
}
|
||||
|
||||
/** List the tags of one category. Category 0 is a real value and must be sent. */
|
||||
export interface OidbGetGroupCategoryTags {
|
||||
groupClass?: pb_optional<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbGetGroupCategoryTagsResp {
|
||||
tags?: pb_repeated<1, OidbGroupCategoryTag>;
|
||||
}
|
||||
|
||||
/** Add or remove one tag name in a category. */
|
||||
export interface OidbChangeGroupCategoryTag {
|
||||
groupClass?: pb_optional<1, uint_32>;
|
||||
name?: pb<2, string>;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Group ext-info modify (robot-add option).
|
||||
// OidbSvcTrpcTcp.0xf00_3 / modifyGroupExtInfoV2.
|
||||
//
|
||||
// Wire: ModifyGroupExtInfoReq{ 1:groupCode, 2:GroupExtInfo{ 1:groupCode,
|
||||
// 2:EXTInfo{ 29:inviteRobotMemberSwitch, 30:inviteRobotMemberExamine } } }
|
||||
// GroupExtFilter is client-side only: it decides which EXTInfo fields the
|
||||
// encoder emits. Presence of tag 29/30 IS the write signal, including 0.
|
||||
// Response: {1:groupCode, 2:result}.
|
||||
|
||||
import type { pb, pb_optional, pb_repeated, int_32, uint_32, uint_64 } from '@snowluma/proton';
|
||||
|
||||
export interface OidbGroupExtBody {
|
||||
inviteRobotMemberSwitch?: pb_optional<29, uint_32>;
|
||||
inviteRobotMemberExamine?: pb_optional<30, uint_32>;
|
||||
}
|
||||
export interface OidbGroupExtInfo {
|
||||
groupCode?: pb<1, uint_32>;
|
||||
ext?: pb<2, OidbGroupExtBody>;
|
||||
}
|
||||
export interface OidbModifyGroupExtReq {
|
||||
groupCode?: pb<1, uint_32>;
|
||||
info?: pb<2, OidbGroupExtInfo>;
|
||||
}
|
||||
export interface OidbModifyGroupExtResp {
|
||||
groupCode?: pb<1, uint_32>;
|
||||
result?: pb<2, int_32>;
|
||||
}
|
||||
|
||||
// OidbSvcTrpcTcp.0xef0_1 / getGroupExt0xEF0Info.
|
||||
// DoFetchGroupExtList request: {1:groupCodes, 2:GroupExtFilter}.
|
||||
// fillGroupExt0xEF0Filter writes filter tags 29/30 when those bits are set.
|
||||
// Response: repeated item{1:groupCode, 2:resultCode, 3:EXTInfo}.
|
||||
export interface OidbGroupExtFilter {
|
||||
inviteRobotMemberSwitch?: pb<29, uint_32>;
|
||||
inviteRobotMemberExamine?: pb<30, uint_32>;
|
||||
}
|
||||
export interface OidbGetGroupExtReq {
|
||||
groupCodes?: pb_repeated<1, uint_64>;
|
||||
filter?: pb<2, OidbGroupExtFilter>;
|
||||
}
|
||||
export interface OidbGetGroupExtItem {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
resultCode?: pb<2, uint_32>;
|
||||
ext?: pb<3, OidbGroupExtBody>;
|
||||
}
|
||||
export interface OidbGetGroupExtResp {
|
||||
items?: pb_repeated<1, OidbGetGroupExtItem>;
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bool, bytes } from '@snowluma/proton';
|
||||
|
||||
export interface OidbGroupFileListReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
targetDirectory?: pb<3, string>;
|
||||
fileCount?: pb<5, uint_32>;
|
||||
sortBy?: pb<9, uint_32>;
|
||||
startIndex?: pb<13, uint_32>;
|
||||
field17?: pb<17, uint_32>;
|
||||
field18?: pb<18, uint_32>;
|
||||
}
|
||||
export interface OidbGroupFileViewReq {
|
||||
list?: pb<2, OidbGroupFileListReq>;
|
||||
}
|
||||
export interface OidbGroupFileListFolderResp {
|
||||
folderId?: pb<1, string>;
|
||||
parentDirectoryId?: pb<2, string>;
|
||||
folderName?: pb<3, string>;
|
||||
createTime?: pb<4, uint_32>;
|
||||
modifiedTime?: pb<5, uint_32>;
|
||||
creatorUin?: pb<6, uint_32>;
|
||||
creatorName?: pb<7, string>;
|
||||
totalFileCount?: pb<8, uint_32>;
|
||||
modifierUin?: pb<9, uint_64>;
|
||||
modifierName?: pb<10, string>;
|
||||
}
|
||||
export interface OidbGroupFileListFileResp {
|
||||
fileId?: pb<1, string>;
|
||||
fileName?: pb<2, string>;
|
||||
fileSize?: pb<3, uint_64>;
|
||||
busId?: pb<4, uint_32>;
|
||||
uploadedTime?: pb<6, uint_32>;
|
||||
expireTime?: pb<7, uint_32>;
|
||||
modifiedTime?: pb<8, uint_32>;
|
||||
downloadedTimes?: pb<9, uint_32>;
|
||||
uploaderName?: pb<14, string>;
|
||||
uploaderUin?: pb<15, uint_32>;
|
||||
parentDirectory?: pb<16, string>;
|
||||
}
|
||||
export interface OidbGroupFileListItemResp {
|
||||
type?: pb<1, uint_32>;
|
||||
folderInfo?: pb<2, OidbGroupFileListFolderResp>;
|
||||
fileInfo?: pb<3, OidbGroupFileListFileResp>;
|
||||
}
|
||||
export interface OidbGroupFileListResp {
|
||||
retCode?: pb<1, uint_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
isEnd?: pb<4, bool>;
|
||||
items?: pb_repeated<5, OidbGroupFileListItemResp>;
|
||||
}
|
||||
export interface OidbGroupFileViewResp {
|
||||
list?: pb<2, OidbGroupFileListResp>;
|
||||
}
|
||||
export interface OidbGroupFileUploadReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
entrance?: pb<4, uint_32>;
|
||||
targetDirectory?: pb<5, string>;
|
||||
fileName?: pb<6, string>;
|
||||
localDirectory?: pb<7, string>;
|
||||
fileSize?: pb<8, uint_64>;
|
||||
fileSha1?: pb<9, bytes>;
|
||||
fileSha3?: pb<10, bytes>;
|
||||
fileMd5?: pb<11, bytes>;
|
||||
field15?: pb<15, bool>;
|
||||
}
|
||||
export interface OidbGroupFileDownloadReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
fileId?: pb<4, string>;
|
||||
}
|
||||
export interface OidbGroupFileDeleteReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
fileId?: pb<5, string>;
|
||||
}
|
||||
export interface OidbGroupFileMoveReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
fileId?: pb<4, string>;
|
||||
parentDirectory?: pb<5, string>;
|
||||
targetDirectory?: pb<6, string>;
|
||||
}
|
||||
export interface OidbGroupFileRenameReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
fileId?: pb<4, string>;
|
||||
parentFolder?: pb<5, string>;
|
||||
newFileName?: pb<6, string>;
|
||||
}
|
||||
export interface OidbGroupFileReq {
|
||||
file?: pb<1, OidbGroupFileUploadReq>;
|
||||
download?: pb<3, OidbGroupFileDownloadReq>;
|
||||
delete?: pb<4, OidbGroupFileDeleteReq>;
|
||||
rename?: pb<5, OidbGroupFileRenameReq>;
|
||||
move?: pb<6, OidbGroupFileMoveReq>;
|
||||
}
|
||||
export interface OidbGroupFileUploadResp {
|
||||
retCode?: pb<1, int_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
uploadIp?: pb<4, string>;
|
||||
serverDns?: pb<5, string>;
|
||||
busId?: pb<6, int_32>;
|
||||
fileId?: pb<7, string>;
|
||||
checkKey?: pb<8, bytes>;
|
||||
fileKey?: pb<9, bytes>;
|
||||
boolFileExist?: pb<10, bool>;
|
||||
uploadPort?: pb<14, uint_32>;
|
||||
}
|
||||
export interface OidbGroupFileDownloadResp {
|
||||
retCode?: pb<1, uint_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
downloadIp?: pb<4, string>;
|
||||
downloadDns?: pb<5, string>;
|
||||
downloadUrl?: pb<6, bytes>;
|
||||
saveFileName?: pb<11, string>;
|
||||
}
|
||||
export interface OidbGroupFileRetResp {
|
||||
retCode?: pb<1, uint_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
}
|
||||
export interface OidbGroupFileResp {
|
||||
upload?: pb<1, OidbGroupFileUploadResp>;
|
||||
download?: pb<3, OidbGroupFileDownloadResp>;
|
||||
delete?: pb<4, OidbGroupFileRetResp>;
|
||||
rename?: pb<5, OidbGroupFileRetResp>;
|
||||
move?: pb<6, OidbGroupFileRetResp>;
|
||||
}
|
||||
export interface OidbGroupTransFileReq {
|
||||
groupUin?: pb<1, uint_64>;
|
||||
appId?: pb<2, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
fileId?: pb<4, string>;
|
||||
}
|
||||
export interface OidbGroupTransFileResp {
|
||||
retCode?: pb<1, int_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
saveBusId?: pb<4, uint_32>;
|
||||
saveFilePath?: pb<5, string>;
|
||||
}
|
||||
export interface OidbGroupSendFileInfo {
|
||||
busiType?: pb<1, uint_32>;
|
||||
fileId?: pb<2, string>;
|
||||
field3?: pb<3, uint_32>;
|
||||
field4?: pb<4, string>;
|
||||
field5?: pb<5, bool>;
|
||||
}
|
||||
export interface OidbGroupSendFileBody {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
type?: pb<2, uint_32>;
|
||||
info?: pb<3, OidbGroupSendFileInfo>;
|
||||
}
|
||||
export interface OidbGroupSendFileReq {
|
||||
transFile?: pb<1, OidbGroupTransFileReq>;
|
||||
body?: pb<5, OidbGroupSendFileBody>;
|
||||
}
|
||||
export interface OidbGroupSendFileResp {
|
||||
transFile?: pb<1, OidbGroupTransFileResp>;
|
||||
}
|
||||
export interface OidbGroupFileCreateFolderReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
rootDirectory?: pb<3, string>;
|
||||
folderName?: pb<4, string>;
|
||||
}
|
||||
export interface OidbGroupFileDeleteFolderReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
folderId?: pb<3, string>;
|
||||
}
|
||||
export interface OidbGroupFileRenameFolderReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
folderId?: pb<3, string>;
|
||||
newFolderName?: pb<4, string>;
|
||||
}
|
||||
export interface OidbGroupFileFolderReq {
|
||||
create?: pb<1, OidbGroupFileCreateFolderReq>;
|
||||
delete?: pb<2, OidbGroupFileDeleteFolderReq>;
|
||||
rename?: pb<3, OidbGroupFileRenameFolderReq>;
|
||||
}
|
||||
// The create (0x6D7_0) response also carries the new folder's info at field 4
|
||||
// — the source of folderId (#195). delete/rename responses leave it empty.
|
||||
// Tags confirmed against a live create response (bot creating a folder in a
|
||||
// test group): modifyUin is field 9, NOT 7 as Lagrange's
|
||||
// OidbSvcTrpcTcp0x6D7_0ResponseFolderInfo has it.
|
||||
export interface OidbGroupFileFolderInfoResp {
|
||||
folderId?: pb<1, string>;
|
||||
folderPath?: pb<2, string>;
|
||||
folderName?: pb<3, string>;
|
||||
createTime?: pb<4, uint_32>;
|
||||
modifyTime?: pb<5, uint_32>;
|
||||
createUin?: pb<6, uint_32>;
|
||||
modifyUin?: pb<9, uint_32>;
|
||||
}
|
||||
export interface OidbGroupFileFolderRetResp {
|
||||
retcode?: pb<1, uint_32>;
|
||||
retMsg?: pb<2, string>;
|
||||
clientWording?: pb<3, string>;
|
||||
folderInfo?: pb<4, OidbGroupFileFolderInfoResp>;
|
||||
}
|
||||
export interface OidbGroupFileFolderResp {
|
||||
create?: pb<1, OidbGroupFileFolderRetResp>;
|
||||
delete?: pb<2, OidbGroupFileFolderRetResp>;
|
||||
rename?: pb<3, OidbGroupFileFolderRetResp>;
|
||||
}
|
||||
export interface OidbGroupFileCountReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
busId?: pb<3, uint_32>;
|
||||
}
|
||||
// Count response (0x6D8_2): fileCount is field 4 and maxCount (the group's file
|
||||
// ceiling, e.g. 1500) field 6 — RE'd from a live count query (#196). The old
|
||||
// pb<1>/pb<2> tags matched nothing, so file_count always decoded to 0.
|
||||
export interface OidbGroupFileCountResp {
|
||||
fileCount?: pb<4, uint_32>;
|
||||
maxCount?: pb<6, uint_32>;
|
||||
isFull?: pb<7, bool>;
|
||||
}
|
||||
// Space request/response (0x6D8_3). Both values are 64-bit — the 10 GiB ceiling
|
||||
// already exceeds uint32.
|
||||
export interface OidbGroupFileSpaceReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
appId?: pb<2, uint_32>;
|
||||
}
|
||||
export interface OidbGroupFileSpaceResp {
|
||||
totalSpace?: pb<4, uint_64>;
|
||||
usedSpace?: pb<5, uint_64>;
|
||||
}
|
||||
// count → subCommand 2, space → subCommand 3 (List is subCommand 1).
|
||||
export interface OidbGroupFileCountViewReq {
|
||||
count?: pb<3, OidbGroupFileCountReq>;
|
||||
space?: pb<4, OidbGroupFileSpaceReq>;
|
||||
}
|
||||
export interface OidbGroupFileCountViewResp {
|
||||
count?: pb<3, OidbGroupFileCountResp>;
|
||||
space?: pb<4, OidbGroupFileSpaceResp>;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { bool, pb, pb_optional, uint_64 } from '@snowluma/proton';
|
||||
|
||||
export interface GroupShareLinkRequest {
|
||||
groupCode?: pb<1, uint_64>;
|
||||
additionalParam?: pb_optional<3, string>;
|
||||
needShortUrl?: pb_optional<4, bool>;
|
||||
}
|
||||
|
||||
export interface OidbGroupShareLinkRequest {
|
||||
type?: pb<1, uint_64>;
|
||||
group?: pb<12, GroupShareLinkRequest>;
|
||||
}
|
||||
|
||||
export interface GroupShareLinkResponse {
|
||||
url?: pb<1, string>;
|
||||
}
|
||||
|
||||
export interface OidbGroupShareLinkResponse {
|
||||
group?: pb<12, GroupShareLinkResponse>;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export type * from './base';
|
||||
export type * from './group-file';
|
||||
export type * from './media';
|
||||
export type * from './group-album';
|
||||
export type * from './flash-transfer';
|
||||
@@ -0,0 +1,283 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bool, bytes } from '@snowluma/proton';
|
||||
|
||||
export interface OidbPrivateFileDownloadReqBody {
|
||||
receiverUid?: pb<10, string>;
|
||||
fileUuid?: pb<20, string>;
|
||||
type?: pb<30, uint_32>;
|
||||
fileHash?: pb<60, string>;
|
||||
t2?: pb<601, uint_32>;
|
||||
}
|
||||
export interface OidbPrivateFileDownloadReq {
|
||||
subCommand?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
body?: pb<14, OidbPrivateFileDownloadReqBody>;
|
||||
field101?: pb<101, uint_32>;
|
||||
field102?: pb<102, uint_32>;
|
||||
field200?: pb<200, uint_32>;
|
||||
field99999?: pb<99999, bytes>;
|
||||
}
|
||||
export interface OidbPrivateFileDownloadRespResult {
|
||||
server?: pb<20, string>;
|
||||
port?: pb<40, uint_32>;
|
||||
url?: pb<50, string>;
|
||||
}
|
||||
export interface OidbPrivateFileDownloadRespBody {
|
||||
state?: pb<20, string>;
|
||||
result?: pb<30, OidbPrivateFileDownloadRespResult>;
|
||||
}
|
||||
export interface OidbPrivateFileDownloadResp {
|
||||
body?: pb<14, OidbPrivateFileDownloadRespBody>;
|
||||
}
|
||||
export interface OidbPrivateFileUploadReqBody {
|
||||
senderUid?: pb<10, string>;
|
||||
receiverUid?: pb<20, string>;
|
||||
fileSize?: pb<30, uint_32>;
|
||||
fileName?: pb<40, string>;
|
||||
md510MCheckSum?: pb<50, bytes>;
|
||||
sha1CheckSum?: pb<60, bytes>;
|
||||
localPath?: pb<70, string>;
|
||||
md5CheckSum?: pb<110, bytes>;
|
||||
sha3CheckSum?: pb<120, bytes>;
|
||||
}
|
||||
export interface OidbPrivateFileUploadReq {
|
||||
command?: pb<1, uint_32>;
|
||||
seq?: pb<2, int_32>;
|
||||
upload?: pb<19, OidbPrivateFileUploadReqBody>;
|
||||
businessId?: pb<101, int_32>;
|
||||
clientType?: pb<102, int_32>;
|
||||
flagSupportMediaPlatform?: pb<200, int_32>;
|
||||
}
|
||||
export interface IPv4 {
|
||||
outIP?: pb<1, int_32>;
|
||||
outPort?: pb<2, int_32>;
|
||||
inIP?: pb<3, int_32>;
|
||||
inPort?: pb<4, int_32>;
|
||||
iPType?: pb<5, int_32>;
|
||||
}
|
||||
export interface OidbPrivateFileUploadRespBody {
|
||||
retCode?: pb<10, int_32>;
|
||||
retMsg?: pb<20, string>;
|
||||
uploadIp?: pb<60, string>;
|
||||
uploadDomain?: pb<70, string>;
|
||||
uploadPort?: pb<80, uint_32>;
|
||||
uuid?: pb<90, string>;
|
||||
uploadKey?: pb<100, bytes>;
|
||||
boolFileExist?: pb<110, bool>;
|
||||
uploadIpList?: pb_repeated<130, string>;
|
||||
uploadHttpsPort?: pb<140, int_32>;
|
||||
uploadHttpsDomain?: pb<150, string>;
|
||||
uploadDns?: pb<160, string>;
|
||||
uploadLanip?: pb<170, string>;
|
||||
fileAddon?: pb<200, string>;
|
||||
rtpMediaPlatformUploadAddress?: pb_repeated<210, IPv4>;
|
||||
mediaPlatformUploadKey?: pb<220, bytes>;
|
||||
}
|
||||
export interface OidbPrivateFileUploadResp {
|
||||
upload?: pb<19, OidbPrivateFileUploadRespBody>;
|
||||
}
|
||||
// 0xE37_800 — c2c offline-file finalize / download-credential fetch.
|
||||
// Called AFTER the Highway upload completes (NapCat runs it even when the
|
||||
// file already exists server-side). The response metadata (`field30`)
|
||||
// supplies the download-routing fields the receiver needs; those ride
|
||||
// along in `FileExtra.field6` on the PbSendMsg. Without this step the file
|
||||
// uploads + PbSendMsg returns ok but the recipient sees "文件传输失败".
|
||||
// Ported byte-for-byte from NapCat `Oidb.0XE37_800` + `Oidb.0xE37_1200`.
|
||||
export interface OidbOfflineFileFinalizeReqBody {
|
||||
senderUid?: pb<10, string>;
|
||||
receiverUid?: pb<20, string>;
|
||||
fileUuid?: pb<30, string>;
|
||||
fileHash?: pb<40, string>;
|
||||
}
|
||||
export interface OidbOfflineFileFinalizeReq {
|
||||
subCommand?: pb<1, uint_32>;
|
||||
field2?: pb<2, int_32>;
|
||||
body?: pb<10, OidbOfflineFileFinalizeReqBody>;
|
||||
field101?: pb<101, int_32>;
|
||||
field102?: pb<102, int_32>;
|
||||
field200?: pb<200, int_32>;
|
||||
}
|
||||
// Server-issued download routing for the just-uploaded c2c file. Only the
|
||||
// fields consumed by `FileExtra.field6` are modelled (NapCat names them
|
||||
// field3/field100/field101/field110/timestamp1; tags verified).
|
||||
export interface OidbOfflineFileMetadata {
|
||||
field3?: pb<3, uint_32>;
|
||||
field100?: pb<100, bytes>;
|
||||
field101?: pb<101, bytes>;
|
||||
field110?: pb<110, uint_32>;
|
||||
timestamp1?: pb<130, uint_32>;
|
||||
}
|
||||
export interface OidbOfflineFileFinalizeRespBody {
|
||||
field10?: pb<10, uint_32>;
|
||||
metadata?: pb<30, OidbOfflineFileMetadata>;
|
||||
}
|
||||
export interface OidbOfflineFileFinalizeResp {
|
||||
command?: pb<1, uint_32>;
|
||||
subCommand?: pb<2, uint_32>;
|
||||
body?: pb<10, OidbOfflineFileFinalizeRespBody>;
|
||||
field50?: pb<50, uint_32>;
|
||||
}
|
||||
export interface NTV2CommonHead {
|
||||
requestId?: pb<1, uint_32>;
|
||||
command?: pb<2, uint_32>;
|
||||
}
|
||||
export interface NTV2C2CUserInfo {
|
||||
accountType?: pb<1, uint_32>;
|
||||
targetUid?: pb<2, string>;
|
||||
}
|
||||
export interface NTV2GroupInfo {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
}
|
||||
export interface NTV2SceneInfo {
|
||||
requestType?: pb<101, uint_32>;
|
||||
businessType?: pb<102, uint_32>;
|
||||
sceneType?: pb<200, uint_32>;
|
||||
c2c?: pb<201, NTV2C2CUserInfo>;
|
||||
group?: pb<202, NTV2GroupInfo>;
|
||||
}
|
||||
export interface NTV2ClientMeta {
|
||||
agentType?: pb<1, uint_32>;
|
||||
}
|
||||
export interface NTV2ReqHead {
|
||||
common?: pb<1, NTV2CommonHead>;
|
||||
scene?: pb<2, NTV2SceneInfo>;
|
||||
client?: pb<3, NTV2ClientMeta>;
|
||||
}
|
||||
export interface NTV2DownloadRKeyReq {
|
||||
types?: pb_repeated<1, uint_32>;
|
||||
}
|
||||
export interface NTV2FileType {
|
||||
type?: pb<1, uint_32>;
|
||||
picFormat?: pb<2, uint_32>;
|
||||
videoFormat?: pb<3, uint_32>;
|
||||
voiceFormat?: pb<4, uint_32>;
|
||||
}
|
||||
export interface NTV2FileInfo {
|
||||
fileSize?: pb<1, uint_32>;
|
||||
fileHash?: pb<2, string>;
|
||||
fileSha1?: pb<3, string>;
|
||||
fileName?: pb<4, string>;
|
||||
type?: pb<5, NTV2FileType>;
|
||||
width?: pb<6, uint_32>;
|
||||
height?: pb<7, uint_32>;
|
||||
time?: pb<8, uint_32>;
|
||||
original?: pb<9, uint_32>;
|
||||
}
|
||||
export interface NTV2IndexNode {
|
||||
info?: pb<1, NTV2FileInfo>;
|
||||
fileUuid?: pb<2, string>;
|
||||
storeId?: pb<3, uint_32>;
|
||||
uploadTime?: pb<4, uint_32>;
|
||||
ttl?: pb<5, uint_32>;
|
||||
subType?: pb<6, uint_32>;
|
||||
}
|
||||
export interface NTV2VideoDownloadExt {
|
||||
busiType?: pb<1, uint_32>;
|
||||
sceneType?: pb<2, uint_32>;
|
||||
subBusiType?: pb<3, uint_32>;
|
||||
}
|
||||
export interface NTV2DownloadExt {
|
||||
video?: pb<2, NTV2VideoDownloadExt>;
|
||||
}
|
||||
export interface NTV2DownloadReq {
|
||||
node?: pb<1, NTV2IndexNode>;
|
||||
download?: pb<2, NTV2DownloadExt>;
|
||||
}
|
||||
export interface NTV2RichMediaReq {
|
||||
reqHead?: pb<1, NTV2ReqHead>;
|
||||
download?: pb<3, NTV2DownloadReq>;
|
||||
downloadRkey?: pb<4, NTV2DownloadRKeyReq>;
|
||||
}
|
||||
export interface NTV2RespHead {
|
||||
common?: pb<1, NTV2CommonHead>;
|
||||
retCode?: pb<2, uint_32>;
|
||||
message?: pb<3, string>;
|
||||
}
|
||||
export interface NTV2RKeyInfo {
|
||||
rkey?: pb<1, string>;
|
||||
rkeyTtlSec?: pb<2, uint_64>;
|
||||
storeId?: pb<3, uint_32>;
|
||||
rkeyCreateTime?: pb<4, uint_32>;
|
||||
type?: pb<5, uint_32>;
|
||||
}
|
||||
export interface NTV2DownloadRKeyResp {
|
||||
rkeys?: pb_repeated<1, NTV2RKeyInfo>;
|
||||
}
|
||||
export interface NTV2MediaDownloadInfo {
|
||||
domain?: pb<1, string>;
|
||||
urlPath?: pb<2, string>;
|
||||
httpsPort?: pb<3, uint_32>;
|
||||
}
|
||||
export interface NTV2MediaDownloadResp {
|
||||
rKeyParam?: pb<1, string>;
|
||||
rKeyTtlSecond?: pb<2, uint_32>;
|
||||
info?: pb<3, NTV2MediaDownloadInfo>;
|
||||
rKeyCreateTime?: pb<4, uint_32>;
|
||||
}
|
||||
export interface NTV2RichMediaResp {
|
||||
respHead?: pb<1, NTV2RespHead>;
|
||||
download?: pb<3, NTV2MediaDownloadResp>;
|
||||
downloadRkey?: pb<4, NTV2DownloadRKeyResp>;
|
||||
}
|
||||
export interface OidbAiVoiceListReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
chatType?: pb<2, uint_32>;
|
||||
}
|
||||
export interface OidbAiVoiceListEntry {
|
||||
voiceId?: pb<1, string>;
|
||||
voiceDisplayName?: pb<2, string>;
|
||||
voiceExampleUrl?: pb<3, string>;
|
||||
}
|
||||
export interface OidbAiVoiceListCategory {
|
||||
category?: pb<1, string>;
|
||||
voices?: pb_repeated<2, OidbAiVoiceListEntry>;
|
||||
}
|
||||
export interface OidbAiVoiceListResp {
|
||||
content?: pb_repeated<1, OidbAiVoiceListCategory>;
|
||||
}
|
||||
export interface OidbAiVoiceSession {
|
||||
sessionId?: pb<1, uint_32>;
|
||||
}
|
||||
export interface OidbAiVoiceReq {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
voiceId?: pb<2, string>;
|
||||
text?: pb<3, string>;
|
||||
chatType?: pb<4, uint_32>;
|
||||
session?: pb<5, OidbAiVoiceSession>;
|
||||
}
|
||||
export interface OidbAiVoiceFileType {
|
||||
type?: pb<1, uint_32>;
|
||||
picFormat?: pb<2, uint_32>;
|
||||
videoFormat?: pb<3, uint_32>;
|
||||
voiceFormat?: pb<4, uint_32>;
|
||||
}
|
||||
export interface OidbAiVoiceFileInfo {
|
||||
fileSize?: pb<1, uint_32>;
|
||||
fileHash?: pb<2, string>;
|
||||
fileSha1?: pb<3, string>;
|
||||
fileName?: pb<4, string>;
|
||||
type?: pb<5, OidbAiVoiceFileType>;
|
||||
width?: pb<6, uint_32>;
|
||||
height?: pb<7, uint_32>;
|
||||
time?: pb<8, uint_32>;
|
||||
original?: pb<9, uint_32>;
|
||||
}
|
||||
export interface OidbAiVoiceIndexNode {
|
||||
info?: pb<1, OidbAiVoiceFileInfo>;
|
||||
fileUuid?: pb<2, string>;
|
||||
storeId?: pb<3, uint_32>;
|
||||
uploadTime?: pb<4, uint_32>;
|
||||
ttl?: pb<5, uint_32>;
|
||||
subType?: pb<6, uint_32>;
|
||||
}
|
||||
export interface OidbAiVoiceMsgInfoBody {
|
||||
index?: pb<1, OidbAiVoiceIndexNode>;
|
||||
}
|
||||
export interface OidbAiVoiceMsgInfo {
|
||||
msgInfoBody?: pb_repeated<1, OidbAiVoiceMsgInfoBody>;
|
||||
}
|
||||
export interface OidbAiVoiceResp {
|
||||
statusCode?: pb<1, uint_32>;
|
||||
field2?: pb<2, uint_32>;
|
||||
field3?: pb<3, uint_32>;
|
||||
msgInfo?: pb<4, OidbAiVoiceMsgInfo>;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// OIDB 0xE07_0 — server-side image OCR. Field tags verified against
|
||||
// NapCat's Oidb.0xE07 proto AND Lagrange.Core's OidbSvcTrpcTcp.0xE07_0
|
||||
// (the two agree; NapCat's transformer builds with cmd 0xEB7, which is a
|
||||
// typo — the proto name + Lagrange + the `OidbSvcTrpcTcp.0xe07_0` wire
|
||||
// name are authoritative). Request takes an image URL (server fetches it).
|
||||
|
||||
import type { pb, pb_repeated, int_32, uint_32, bool } from '@snowluma/proton';
|
||||
|
||||
export interface OcrReqBody {
|
||||
imageUrl?: pb<1, string>;
|
||||
languageType?: pb<2, uint_32>;
|
||||
scene?: pb<3, uint_32>;
|
||||
originMd5?: pb<10, string>;
|
||||
afterCompressMd5?: pb<11, string>;
|
||||
afterCompressFileSize?: pb<12, string>;
|
||||
afterCompressWeight?: pb<13, string>;
|
||||
afterCompressHeight?: pb<14, string>;
|
||||
isCut?: pb<15, bool>;
|
||||
}
|
||||
export interface ImageOcrReq {
|
||||
version?: pb<1, uint_32>;
|
||||
client?: pb<2, uint_32>;
|
||||
entrance?: pb<3, uint_32>;
|
||||
ocrReqBody?: pb<10, OcrReqBody>;
|
||||
}
|
||||
|
||||
export interface OcrCoordinate {
|
||||
x?: pb<1, int_32>;
|
||||
y?: pb<2, int_32>;
|
||||
}
|
||||
export interface OcrPolygon {
|
||||
coordinates?: pb_repeated<1, OcrCoordinate>;
|
||||
}
|
||||
export interface OcrTextDetection {
|
||||
detectedText?: pb<1, string>;
|
||||
confidence?: pb<2, uint_32>;
|
||||
polygon?: pb<3, OcrPolygon>;
|
||||
advancedInfo?: pb<4, string>;
|
||||
}
|
||||
export interface OcrRspBody {
|
||||
textDetections?: pb_repeated<1, OcrTextDetection>;
|
||||
language?: pb<2, string>;
|
||||
requestId?: pb<3, string>;
|
||||
}
|
||||
export interface ImageOcrResp {
|
||||
retCode?: pb<1, int_32>;
|
||||
errMsg?: pb<2, string>;
|
||||
wording?: pb<3, string>;
|
||||
ocrRspBody?: pb<10, OcrRspBody>;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// 0x9154_1 — QQ system face / emoji catalog protobuf shapes.
|
||||
|
||||
import type { pb, pb_repeated, int_32, bool } from '@snowluma/proton';
|
||||
|
||||
export interface OidbFaceResourceUrl {
|
||||
baseUrl?: pb<1, string>;
|
||||
advUrl?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface OidbFaceEmoji {
|
||||
qSid?: pb<1, string>;
|
||||
qDes?: pb<2, string>;
|
||||
emCode?: pb<3, string>;
|
||||
qCid?: pb<4, int_32>;
|
||||
aniStickerType?: pb<5, int_32>;
|
||||
aniStickerPackId?: pb<6, int_32>;
|
||||
aniStickerId?: pb<7, int_32>;
|
||||
url?: pb<8, OidbFaceResourceUrl>;
|
||||
emojiNameAlias?: pb_repeated<9, string>;
|
||||
unknown10?: pb<10, int_32>;
|
||||
aniStickerWidth?: pb<13, int_32>;
|
||||
aniStickerHeight?: pb<14, int_32>;
|
||||
}
|
||||
|
||||
export interface OidbFaceEmojiList {
|
||||
emojiPackName?: pb<1, string>;
|
||||
emojiDetail?: pb_repeated<2, OidbFaceEmoji>;
|
||||
}
|
||||
|
||||
export interface OidbFaceContent {
|
||||
emojiList?: pb_repeated<1, OidbFaceEmojiList>;
|
||||
resourceUrl?: pb<2, OidbFaceResourceUrl>;
|
||||
}
|
||||
|
||||
export interface OidbFetchSysFacesExpInfo {
|
||||
field1?: pb<1, string>;
|
||||
}
|
||||
|
||||
export interface OidbFetchSysFacesReq {
|
||||
field1?: pb<1, int_32>;
|
||||
field2?: pb<2, int_32>;
|
||||
field3?: pb<3, int_32>;
|
||||
field4?: pb<4, OidbFetchSysFacesExpInfo>;
|
||||
}
|
||||
|
||||
export interface OidbFetchSysFacesResp {
|
||||
field1?: pb<1, int_32>;
|
||||
commonFace?: pb<2, OidbFaceContent>;
|
||||
specialBigFace?: pb<3, OidbFaceContent>;
|
||||
specialMagicFace?: pb<4, OidbFaceContent>;
|
||||
}
|
||||
|
||||
export interface OidbFetchSysFaceReq {
|
||||
qSid?: pb<1, string>;
|
||||
}
|
||||
|
||||
export interface OidbFetchSysFaceResp {
|
||||
emoji?: pb<1, OidbFaceEmoji>;
|
||||
field2?: pb<2, bool>;
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
import type { pb, pb_repeated, int_32, uint_32, uint_64, bytes, bool } from '@snowluma/proton';
|
||||
|
||||
export interface OidbProperty {
|
||||
key?: pb<1, string>;
|
||||
value?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface OidbBase<TBody> {
|
||||
command?: pb<1, uint_32>;
|
||||
subCommand?: pb<2, uint_32>;
|
||||
errorCode?: pb<3, uint_32>;
|
||||
body?: pb<4, TBody>;
|
||||
errorMsg?: pb<5, string>;
|
||||
properties?: pb_repeated<11, OidbProperty>;
|
||||
reserved?: pb<12, int_32>;
|
||||
}
|
||||
|
||||
export interface OidbBaseMeta {
|
||||
command?: pb<1, uint_32>;
|
||||
subCommand?: pb<2, uint_32>;
|
||||
errorCode?: pb<3, uint_32>;
|
||||
errorMsg?: pb<5, string>;
|
||||
reserved?: pb<12, int_32>;
|
||||
}
|
||||
|
||||
/** Placeholder body for OIDB cmds whose successful response carries no
|
||||
* payload (only the envelope's errorCode matters). Used as the
|
||||
* TResp parameter in OidbCallSpec for fire-and-forget cmds — proton
|
||||
* needs a real message interface here, not `void` or `never`. */
|
||||
export interface OidbEmpty {}
|
||||
|
||||
// Oidb.0xFD4_1 Friend list
|
||||
export interface OidbFriendProperty {
|
||||
code?: pb<1, uint_32>;
|
||||
value?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface OidbFriendNumberProperty {
|
||||
key?: pb<1, uint_32>;
|
||||
value?: pb<2, int_32>;
|
||||
}
|
||||
|
||||
export interface OidbFriendLayer1 {
|
||||
numberProperties?: pb_repeated<1, OidbFriendNumberProperty>;
|
||||
properties?: pb_repeated<2, OidbFriendProperty>;
|
||||
}
|
||||
|
||||
export interface OidbFriendAdditional {
|
||||
type?: pb<1, uint_32>;
|
||||
layer1?: pb<2, OidbFriendLayer1>;
|
||||
}
|
||||
|
||||
export interface OidbFriend {
|
||||
uid?: pb<1, string>;
|
||||
customGroup?: pb<2, uint_32>;
|
||||
uin?: pb<3, uint_32>;
|
||||
additional?: pb_repeated<10001, OidbFriendAdditional>;
|
||||
}
|
||||
|
||||
export interface OidbFriendCategory {
|
||||
categoryId?: pb<1, uint_32>;
|
||||
categoryName?: pb<2, string>;
|
||||
memberCount?: pb<3, uint_32>;
|
||||
sortId?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFD4_1Response {
|
||||
cookie?: pb<2, bytes>;
|
||||
isEnd?: pb<3, bool>;
|
||||
timestamp?: pb<6, uint_64>;
|
||||
selfUin?: pb<7, uint_64>;
|
||||
smallSeq?: pb<8, uint_32>;
|
||||
friends?: pb_repeated<101, OidbFriend>;
|
||||
categories?: pb_repeated<102, OidbFriendCategory>;
|
||||
}
|
||||
|
||||
// Oidb.0xFE5_2 Group list
|
||||
export interface OidbSvcTrpcTcp0xFE5_2Member {
|
||||
uid?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE5_2GroupInfo {
|
||||
groupOwner?: pb<1, OidbSvcTrpcTcp0xFE5_2Member>;
|
||||
createdTime?: pb<2, uint_32>;
|
||||
memberMax?: pb<3, uint_32>;
|
||||
memberCount?: pb<4, uint_32>;
|
||||
groupName?: pb<5, string>;
|
||||
description?: pb<18, string>;
|
||||
question?: pb<19, string>;
|
||||
announcement?: pb<30, string>;
|
||||
// wrapper.node 3.2.32 group_codec.cc DecodeGroupInfo: tag 10 → internal
|
||||
// 60027 (JS groupShutupExpireTime). Tag 31 is 60259, not the mute expire.
|
||||
// 0 = off, 0xFFFFFFFF = permanent, otherwise unix-seconds expire.
|
||||
shutUpAllTimestamp?: pb<10, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE5_2CustomInfo {
|
||||
remark?: pb<3, string>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE5_2Group {
|
||||
groupUin?: pb<3, uint_32>;
|
||||
info?: pb<4, OidbSvcTrpcTcp0xFE5_2GroupInfo>;
|
||||
customInfo?: pb<5, OidbSvcTrpcTcp0xFE5_2CustomInfo>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE5_2Response {
|
||||
groups?: pb_repeated<2, OidbSvcTrpcTcp0xFE5_2Group>;
|
||||
}
|
||||
|
||||
// Oidb.0x88D_0 — single group detail by uin. `results` tags mirror the request
|
||||
// flags. Cross-checked against
|
||||
// dev/Lagrange.Core/.../Response/OidbSvcTrpcTcp0x88D_0Response.cs.
|
||||
export interface OidbSvcTrpcTcp0x88D_0Results {
|
||||
ownerUid?: pb<1, string>;
|
||||
createTime?: pb<2, uint_64>;
|
||||
maxMemberCount?: pb<5, uint_64>;
|
||||
memberCount?: pb<6, uint_64>;
|
||||
// DecodeSingleGroupDetailInfoByBaseFilter: tag 7 → 60205 addOption.
|
||||
// SET uses a different message domain (0x89A settings tag 16).
|
||||
addType?: pb<7, uint_32>;
|
||||
level?: pb<10, uint_64>;
|
||||
name?: pb<15, string>;
|
||||
noticePreview?: pb<16, string>;
|
||||
uin?: pb<21, uint_64>;
|
||||
lastSequence?: pb<22, uint_64>;
|
||||
lastMessageTime?: pb<23, uint_64>;
|
||||
question?: pb<24, string>;
|
||||
answer?: pb<25, string>;
|
||||
maxAdminCount?: pb<29, uint_64>;
|
||||
// wrapper.node 3.2.32 group_info_fetch_codec.cc
|
||||
// DecodeSingleGroupDetailInfoByBaseFilter: tag 45 → internal 60027.
|
||||
// Tag 59 is 60259, not the mute expire. Request mask tag is also 45.
|
||||
shutUpAllTimestamp?: pb<45, uint_32>;
|
||||
/** Complete app privilege bitfield (requested with detail flag tag 56). */
|
||||
privilegeFlag?: pb<56, uint_32>;
|
||||
/** New-member history-visible switch (0/1; omitted means hidden). */
|
||||
groupFlagExt4?: pb<101, uint_32>;
|
||||
// DecodeSingleGroupDetailInfoByBaseFilter: tag 82 → 60282, tag 83 → 60283.
|
||||
// SET counterparts are 0x89A settings 35/36. 0 = that search mode is open.
|
||||
noFingerOpen?: pb<82, uint_32>;
|
||||
noCodeFingerOpen?: pb<83, uint_32>;
|
||||
}
|
||||
export interface OidbSvcTrpcTcp0x88D_0ResponseGroupInfo {
|
||||
uin?: pb<1, uint_64>;
|
||||
results?: pb<3, OidbSvcTrpcTcp0x88D_0Results>;
|
||||
}
|
||||
export interface OidbSvcTrpcTcp0x88D_0Response {
|
||||
groupInfo?: pb<1, OidbSvcTrpcTcp0x88D_0ResponseGroupInfo>;
|
||||
}
|
||||
|
||||
// Oidb.0xFE7_3 Group member list
|
||||
export interface OidbSvcTrpcTcp0xFE7_3Uin {
|
||||
uid?: pb<2, string>;
|
||||
uin?: pb<4, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE7_3Card {
|
||||
/** Plain UTF-8 or a serialized RichGroupCard. */
|
||||
memberCard?: pb<2, bytes>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE7_3Level {
|
||||
infos?: pb_repeated<1, uint_32>;
|
||||
level?: pb<2, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE7_3Member {
|
||||
uin?: pb<1, OidbSvcTrpcTcp0xFE7_3Uin>;
|
||||
memberName?: pb<10, string>;
|
||||
specialTitle?: pb<17, string>;
|
||||
memberCard?: pb<11, OidbSvcTrpcTcp0xFE7_3Card>;
|
||||
level?: pb<12, OidbSvcTrpcTcp0xFE7_3Level>;
|
||||
joinTimestamp?: pb<100, uint_32>;
|
||||
lastMsgTimestamp?: pb<101, uint_32>;
|
||||
shutUpTimestamp?: pb<102, uint_32>;
|
||||
permission?: pb<107, uint_32>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0xFE7_3Response {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
members?: pb_repeated<2, OidbSvcTrpcTcp0xFE7_3Member>;
|
||||
field3?: pb<3, uint_32>;
|
||||
memberChangeSeq?: pb<5, uint_32>;
|
||||
memberCardChangeSeq?: pb<6, uint_32>;
|
||||
token?: pb<15, string>;
|
||||
}
|
||||
|
||||
// OIDB 0x496_0 — dynamic robot UIN ranges. QQ's native
|
||||
// NodeIKernelRobotService uses this config when deciding whether a group
|
||||
// member is a robot; the ranges are server-versioned and must not be
|
||||
// hard-coded client-side.
|
||||
export interface OidbRobotUinRange {
|
||||
minUin?: pb<1, uint_64>;
|
||||
maxUin?: pb<2, uint_64>;
|
||||
}
|
||||
|
||||
export interface OidbRobotUinRangeConfig {
|
||||
version?: pb<1, uint_32>;
|
||||
ranges?: pb_repeated<2, OidbRobotUinRange>;
|
||||
}
|
||||
|
||||
export interface OidbRobotUinRangeResponse {
|
||||
robotConfig?: pb<5, OidbRobotUinRangeConfig>;
|
||||
}
|
||||
|
||||
// OIDB.0x10C0 Group Request — UID-form response (envelope reserved=0).
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseUser {
|
||||
uid?: pb<1, string>;
|
||||
name?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseGroup {
|
||||
groupUin?: pb<1, uint_32>;
|
||||
groupName?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseRequest {
|
||||
sequence?: pb<1, uint_64>;
|
||||
eventType?: pb<2, uint_32>;
|
||||
state?: pb<3, uint_32>;
|
||||
group?: pb<4, OidbSvcTrpcTcp0x10C0ResponseGroup>;
|
||||
target?: pb<5, OidbSvcTrpcTcp0x10C0ResponseUser>;
|
||||
invitor?: pb<6, OidbSvcTrpcTcp0x10C0ResponseUser>;
|
||||
operatorUser?: pb<7, OidbSvcTrpcTcp0x10C0ResponseUser>;
|
||||
field9?: pb<9, string>;
|
||||
comment?: pb<10, string>;
|
||||
operateTransInfo?: pb<14, bytes>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0x10C0Response {
|
||||
requests?: pb_repeated<1, OidbSvcTrpcTcp0x10C0ResponseRequest>;
|
||||
field2?: pb<2, uint_64>;
|
||||
newLatestSeq?: pb<3, uint_64>;
|
||||
field4?: pb<4, uint_32>;
|
||||
field5?: pb<5, uint_64>;
|
||||
field6?: pb<6, uint_32>;
|
||||
}
|
||||
|
||||
// The native UIN-form request (envelope reserved=1) uses the same response
|
||||
// tags, but user field 1 changes wire type from string to uint32. Keep a
|
||||
// separate schema: decoding both forms through one interface would silently
|
||||
// discard every numeric account identifier as a mismatched wire type.
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseUserByUin {
|
||||
uin?: pb<1, uint_32>;
|
||||
name?: pb<2, string>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseRequestByUin {
|
||||
sequence?: pb<1, uint_64>;
|
||||
eventType?: pb<2, uint_32>;
|
||||
state?: pb<3, uint_32>;
|
||||
group?: pb<4, OidbSvcTrpcTcp0x10C0ResponseGroup>;
|
||||
target?: pb<5, OidbSvcTrpcTcp0x10C0ResponseUserByUin>;
|
||||
invitor?: pb<6, OidbSvcTrpcTcp0x10C0ResponseUserByUin>;
|
||||
operatorUser?: pb<7, OidbSvcTrpcTcp0x10C0ResponseUserByUin>;
|
||||
field9?: pb<9, string>;
|
||||
comment?: pb<10, string>;
|
||||
operateTransInfo?: pb<14, bytes>;
|
||||
}
|
||||
|
||||
export interface OidbSvcTrpcTcp0x10C0ResponseByUin {
|
||||
requests?: pb_repeated<1, OidbSvcTrpcTcp0x10C0ResponseRequestByUin>;
|
||||
field2?: pb<2, uint_64>;
|
||||
newLatestSeq?: pb<3, uint_64>;
|
||||
field4?: pb<4, uint_32>;
|
||||
field5?: pb<5, uint_64>;
|
||||
field6?: pb<6, uint_32>;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import type { pb, uint_32, uint_64 } from '@snowluma/proton';
|
||||
|
||||
/**
|
||||
* Voice-to-text (语音转文字) request/response protobufs for the
|
||||
* `pttTrans.TransC2CPttReq` / `pttTrans.TransGroupPttReq` SSO commands.
|
||||
*
|
||||
* Reverse-engineered from QQ-NT `wrapper.node` (macOS 9.9.x) —
|
||||
* `im_core/msg/ptt/ptt_trans_worker.cc` (`EncodeC2CPtt` / `EncodeTroopPtt`
|
||||
* build the request, `OnTranslateResp` decodes the response). The wire shape
|
||||
* here is RE-derived and NOT yet verified against a live server: the numeric
|
||||
* field tags are read straight from the encoder, but the length-delimited
|
||||
* fields (uuid / md5) and the response `text` tag should be confirmed with a
|
||||
* single live capture before relying on them.
|
||||
*
|
||||
* Flow: the response can carry completed text inline. Otherwise, the caller
|
||||
* waits for an asynchronous result correlated with the original message ID.
|
||||
*/
|
||||
|
||||
/** Source ptt-element field (NT internal tag) noted in the comment after each. */
|
||||
export interface C2CPttTransItem {
|
||||
msgId?: pb<1, uint_64>;
|
||||
senderUin?: pb<2, uint_64>;
|
||||
receiverUin?: pb<3, uint_64>;
|
||||
uuid?: pb<4, string>; // element 45503 (c2c ptt uuid)
|
||||
duration?: pb<5, uint_32>; // element 45906 (seconds)
|
||||
size?: pb<6, uint_32>; // element 45405 (bytes)
|
||||
format?: pb<7, uint_32>; // element 45907 (voice codec)
|
||||
eventType?: pb<8, uint_32>; // element 45921
|
||||
// QQ NT (EncodeC2CPtt) hex-encodes the md5 to a 32-char lowercase string
|
||||
// before sending it (verified in wrapper.linux.node: field 9 = sub_7A02D80
|
||||
// = bytes→hex). Sending the raw 16 bytes makes the server reject with
|
||||
// errCode -1079. So this is a hex STRING, not bytes.
|
||||
md5?: pb<9, string>; // element 45406 (32-char lowercase hex)
|
||||
}
|
||||
|
||||
export interface GroupPttTransItem {
|
||||
msgId?: pb<1, uint_64>;
|
||||
senderUin?: pb<2, uint_64>;
|
||||
groupUin?: pb<3, uint_64>;
|
||||
fileId?: pb<4, uint_32>; // element 45903 (group ptt numeric file id)
|
||||
md5?: pb<5, string>; // element 45406 (32-char lowercase hex, see C2C note)
|
||||
duration?: pb<6, uint_32>; // element 45906
|
||||
size?: pb<7, uint_32>; // element 45405
|
||||
format?: pb<8, uint_32>; // element 45907
|
||||
uuid?: pb<9, string>; // element 45503
|
||||
eventType?: pb<10, uint_32>; // element 45921
|
||||
ext?: pb<11, uint_32>; // element 49202 (optional)
|
||||
}
|
||||
|
||||
/**
|
||||
* Outer request. `type` selects the scene (1 = group, 2 = c2c) and only the
|
||||
* matching item is populated — group at field 2, c2c at field 3.
|
||||
*/
|
||||
export interface PttTransReq {
|
||||
type?: pb<1, uint_32>;
|
||||
groupItem?: pb<2, GroupPttTransItem>;
|
||||
c2cItem?: pb<3, C2CPttTransItem>;
|
||||
}
|
||||
|
||||
/** Per-scene result. `errCode` 0 = ok; `text` carries the recognised speech. */
|
||||
export interface C2CPttTransResult {
|
||||
errCode?: pb<2, uint_32>;
|
||||
text?: pb<8, string>; // VERIFY LIVE: text tag from OnTranslateResp
|
||||
}
|
||||
|
||||
export interface GroupPttTransResult {
|
||||
errCode?: pb<2, uint_32>;
|
||||
text?: pb<9, string>; // VERIFY LIVE: text tag from OnTranslateResp
|
||||
}
|
||||
|
||||
/**
|
||||
* Outer response. `type` echoes the scene; result is at field 2 (group) /
|
||||
* field 3 (c2c). An empty `text` with `errCode == 0` means "transcribing,
|
||||
* await the result push".
|
||||
*/
|
||||
export interface PttTransResp {
|
||||
type?: pb<1, uint_32>;
|
||||
groupResult?: pb<2, GroupPttTransResult>;
|
||||
c2cResult?: pb<3, C2CPttTransResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Async result push (Event 0x210 subType 61), sent after the request once the
|
||||
* server finishes transcribing. **Live-verified** against a real push: the
|
||||
* outer carries a single result item at field 2; the item echoes the request
|
||||
* `msgId` at field 1 (the correlation key) and the recognised text at field 8.
|
||||
*/
|
||||
export interface PttTransPushItem {
|
||||
msgId?: pb<1, uint_64>; // echoes the request msgId — correlation key
|
||||
text?: pb<8, string>; // recognised text
|
||||
senderUin?: pb<9, uint_64>;
|
||||
receiverUin?: pb<10, uint_64>;
|
||||
uuid?: pb<13, string>;
|
||||
}
|
||||
|
||||
export interface PttTransPush {
|
||||
field1?: pb<1, uint_32>;
|
||||
item?: pb<2, PttTransPushItem>;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { pb, uint_32 } from '@snowluma/proton';
|
||||
|
||||
// trpc.basic.corp.Datacard.SsoCorpInfo — 企点企业资料卡信息。
|
||||
// 请求:field1 = 目标账号 UIN(varint)。
|
||||
// 响应字段为企点企业资料卡:名称 / 简介 / 官网 / 企业签名 / 地址 / 电话 / 邮箱。
|
||||
export interface QidianCorpInfoRequest {
|
||||
uin?: pb<1, uint_32>;
|
||||
}
|
||||
|
||||
export interface QidianCorpInfoResponse {
|
||||
corpName?: pb<2, string>;
|
||||
intro?: pb<3, string>;
|
||||
website?: pb<4, string>;
|
||||
slogan?: pb<5, string>;
|
||||
address?: pb<6, string>;
|
||||
phone?: pb<7, string>;
|
||||
email?: pb<8, string>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { int_64, pb, pb_optional } from '@snowluma/proton';
|
||||
|
||||
/** Personal-space emotion identity carried in GetFeedDetail's base64 ugc_id. */
|
||||
export interface QzoneEmotionUgcId {
|
||||
appId: pb<1, int_64>;
|
||||
uin: pb<2, int_64>;
|
||||
publishTime: pb<3, int_64>;
|
||||
// These empty fields have explicit presence in the upstream identifier.
|
||||
field4: pb_optional<4, string>;
|
||||
field5: pb_optional<5, string>;
|
||||
field6: pb<6, string>;
|
||||
tid: pb<8, string>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user