Skip to content

通用 URI 解析

这一页只回答 3 个问题:

  1. mqqapi://markdown/node 在运行时分成哪几条支路
  2. 每类 query 参数当前到底在哪一层被消费
  3. 哪些字段仍未闭环

1. 入口形态

当前常见形态:

markdown
[](mqqapi://markdown/node?nodeType=richui&json=...)
[](mqqapi://markdown/node?nodeType=quoteArea&nodeID=quoteArea&state=start&text=...)
[](mqqapi://markdown/node?nodeType=replace&nodeID=quoteArea)
[](mqqapi://markdown/node-data?nodeID=aidrawPic&index=0&picUrl=...)

这里要注意两点:

  • 当前实现里同时能看到 nodeIdnodeID 两种命名痕迹
  • 运行时真正按 query map 读值时,至少已实锤 nodeTypenodeIDstate

2. 运行时主分支

a2.e.a(...) 已恢复出可读方法体。当前最重要的结论如下。[1]

2.1 nodeType=replace

运行时动作:

  • 创建 h2.e
  • 只写 nodeID -> h2.e.f4603a
  • 包进 h2.b
  • h2.b.f4598a = 0

当前已实锤消费字段:

字段当前消费点结论
nodeIDa2.el1.gu1.e已实锤
text未找到 replace 专属读点未闭环
state未找到 replace 专属读点未闭环
index未找到 replace 专属读点未闭环

下游当前只会这样用它:

  • 先从 replace 占位节点取 nodeID
  • 再回查 a2.c.b[nodeID]
  • 取真实 start 节点的 nodeType

也就是说,replace 当前最严格的实锤语义是:

  • 它是一个“按 nodeID 回指真实节点类型”的占位节点

2.2 普通 mqqapi://markdown/node?...

运行时动作:

  • 创建 h2.f
  • h2.f.b = nodeID
  • h2.f.f4605c = nodeType
  • h2.f.d = 整个 query attrMap
  • state=start -> h2.f.f4604a = 1
  • state=end -> h2.f.f4604a = 2

随后:

  • start 节点写入 a2.c.b[nodeID]
  • end 节点写入 a2.c.f14c[nodeID]

这条分支当前直接支撑了:

  • quoteArea(start/end)
  • thinkArea
  • multiPic
  • 其他 custom syntax 节点类型识别

2.3 mqqapi://markdown/node-data?...

运行时动作:

  • 创建 h2.d
  • h2.d.f4602a = nodeID
  • h2.d.b = 整个 query attrMap
  • 包进 h2.b
  • h2.b.f4598a = 2
  • 聚合到 a2.c.f13a[nodeID]

这条分支当前最明确的真实消费链是 multiPic[2]

3. 参数分层

3.1 分发参数

参数所在分支当前状态说明
nodeTypenode / replace已实锤分支选择与真实节点类型
nodeIDreplace / node / node-data已实锤关联键
state普通 node已实锤start/end

3.2 载荷参数

参数当前真实消费层当前结论
jsonrichui已实锤
text普通 nodeattrMap / 预处理器已实锤有读点,但语义未全闭环
indexnode-data -> multiPic已实锤
itemsPerRowmultiPic已实锤
itemsNummultiPic已实锤

3.3 当前不能再混写的结论

  • index 不能再默认写成 replace 参数
  • itemsPerRow/itemsNum 不能再默认写成 quoteArea 参数
  • text 当前只能说“进入过普通 nodeattrMap 并被部分预处理器读取”,不能直接写死成标题

4. quoteArea 当前能确认到哪一层

4.1 AST / custom node 层

  • l1.e 明确把 quoteArea 识别为一种 custom syntax[3]
  • a2.e 的普通 node 分支会把 nodeType=quoteArea 写入 h2.f
  • NetSearchMDPreprocessorMarkerCustomProcessor 都会直接读取 extra.F["text"][4]

4.2 展示态层

  • MarkdownCustomQuoteAreaKt 渲染时直接从 extra.G.dj2.b[5]
  • j2.b 字段当前已明确:
    • f4993a: title
    • b: status
    • f4994c: items
    • d: msgId

4.3 半浮层层

  • MarkdownHandlerImpl.b(j2.b) 点击后只消费 j2.b.f4994c
  • 它会把 List<j2.c> 序列化为 quoteAreaItems
  • QuoteHalfFloatingPage 再从 quoteAreaItems 反序列化出 j2.c 列表

5. replace 当前能确认到哪一层

5.1 已实锤

  • replace 运行时确实有专门分支
  • 它当前只写 nodeID
  • 下游当前也只按 nodeID 回查真实 start 节点类型

5.2 未闭环

  • replace.text
  • replace.state
  • replace.index
  • replace -> j2.b 的任何直接装配

6. 当前最重要的缺口

目前最关键的未闭环点不是入口,而是中间装配:

  • 谁给 a2.e.d 赋值
  • 谁构造 j2.b
  • quoteArea.text -> j2.b.f4993a 是否成立

7. 关键源码


  1. a2.e.a(...) 已恢复出可读方法体,见 ../../jadx_retry_a2_e_simple.java:339-400../../jadx_single_a2_e.java:503-612↩︎

  2. node-data.indexmultiPic 链的真实消费见 ../../classes14_src/f2/c.java:78-154itemsPerRow/itemsNum 解析见 ../../classes18_src/com/tencent/qqnt/markdown/data/multipic/f.java↩︎

  3. quoteArea custom syntax 识别见 ../../classes14_src/l1/e.java:582-606↩︎

  4. extra.F["text"] 读点见 ../../classes14_src/net_search/markdown/NetSearchMDPreprocessor.java:153-192../../classes14_src/base/markdown/processor/parser/MarkerCustomProcessor.java:121-159↩︎

  5. MarkdownCustomQuoteAreaKt 读取 extra.G.d../../classes14_src/base/markdown/renderer/compose/elements/custom_syntax/MarkdownCustomQuoteAreaKt.java:106-120j2.b 结构见 ../../classes14_src/j2/b.java:8-20,31-52↩︎