feat(protocol): 采集客户端枚举读取打点并加分析脚本
This commit is contained in:
1 parent
ce8eeec8d6
commit
1c5dc3afb9
2 files changed
+105
No files matched your search
@@ -0,0 +1,71 @@
|
||||
# analyze_enum_trace.py - 分析客户端「枚举读取」打点:确认读 enum 时字节游标是否推进
|
||||
#
|
||||
# 数据来源:镜像站 module_24635.js 的 Kt.t7h 补丁(枚举读器)。它记录
|
||||
# {enum: 枚举 kClass 名, pos0/pos1: 读前/读后的字节游标, bit: nullmap 位游标}
|
||||
# 节流 POST 到 serve.js 的 /__dump__/enum_trace.json。
|
||||
#
|
||||
# 判读:
|
||||
# pos1 - pos0 == 0 → 该枚举不占字节(与源码 EnumCodecInfo/Kt 空实现一致);
|
||||
# pos1 - pos0 != 0 → 客户端确实为这个枚举读了字节,说明宽度不是常量。
|
||||
#
|
||||
# 用法: python tools/analyze_enum_trace.py [--names names]
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
Root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def Arg(Name, Def):
|
||||
if '--' + Name in sys.argv:
|
||||
I = sys.argv.index('--' + Name)
|
||||
if I + 1 < len(sys.argv):
|
||||
return sys.argv[I + 1]
|
||||
return Def
|
||||
|
||||
|
||||
NamesDir = os.path.abspath(Arg('names', os.path.join(Root, 'names')))
|
||||
TracePath = os.path.join(NamesDir, 'enum_trace.json')
|
||||
FieldsPath = os.path.join(NamesDir, 'codec_fields.json')
|
||||
|
||||
|
||||
def Main():
|
||||
if not os.path.exists(TracePath):
|
||||
print('缺少 ' + TracePath)
|
||||
print('请先用镜像站进一局战斗(Kt.t7h 已打枚举打点,会自动 POST)。')
|
||||
return 1
|
||||
with open(TracePath, 'r', encoding='utf-8') as F:
|
||||
Data = json.load(F)
|
||||
Rows = Data.get('trace') or []
|
||||
print('枚举打点:%d 条(采集于 %s)' % (len(Rows), Data.get('at', '?')))
|
||||
|
||||
with open(FieldsPath, 'r', encoding='utf-8') as F:
|
||||
Codecs = json.load(F).get('Codecs') or {}
|
||||
# 枚举类型名 → 用到它的 (codec, 字段)
|
||||
Users = defaultdict(list)
|
||||
for Key, C in Codecs.items():
|
||||
for F in C.get('Fields') or []:
|
||||
T = str(F.get('Type') or '')
|
||||
if T.startswith('enum<') and T.endswith('>'):
|
||||
Users[T[5:-1]].append((Key, F.get('Name')))
|
||||
|
||||
Delta = Counter()
|
||||
ByEnum = defaultdict(Counter)
|
||||
for R in Rows:
|
||||
D = (R.get('pos1', -1) - R.get('pos0', -1)) if R.get('pos0', -1) >= 0 else -1
|
||||
Delta[D] += 1
|
||||
ByEnum[R.get('enum') or '?'][D] += 1
|
||||
|
||||
print(' 字节推进量分布(pos1-pos0):%s' % dict(Delta))
|
||||
print(' 按枚举类型:')
|
||||
for Name, Cnt in sorted(ByEnum.items(), key=lambda X: -sum(X[1].values()))[:25]:
|
||||
Where = Users.get(Name) or []
|
||||
Sample = ('%s.%s' % Where[0]) if Where else '?'
|
||||
print(' %-4s 次数=%-5d 推进=%s 使用处=%s%s'
|
||||
% (Name or '?', sum(Cnt.values()), dict(Cnt), Sample, (' 等 %d 处' % len(Where)) if len(Where) > 1 else ''))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
@@ -510,6 +510,40 @@
|
||||
(z(Vt).u7h = function (t) {}),
|
||||
(z(Kt).u7h = function (t) {}),
|
||||
(z(Kt).t7h = function (t) {
|
||||
// [Hornet 调试] 枚举读取打点:记录「枚举类型名 + 读前/读后的字节游标」。
|
||||
// 枚举本身按源码不占字节(这里恒返回 null),打点只为确认客户端在真实数据里
|
||||
// 读 enum 时字节游标到底动没动,以及是哪个枚举类型(y7h_1 = kClass)。
|
||||
try {
|
||||
if (typeof window !== "undefined") {
|
||||
var S = t.e7h_1;
|
||||
var P0 = S && typeof S.g2t === "function" ? S.g2t() : -1;
|
||||
var E = (window.__HornetEnumTrace__ = window.__HornetEnumTrace__ || {
|
||||
rows: [], timer: 0,
|
||||
push: function (Row) {
|
||||
if (this.rows.length >= 3000) return;
|
||||
this.rows.push(Row);
|
||||
if (!this.timer) {
|
||||
var Me = this;
|
||||
this.timer = setTimeout(function () {
|
||||
Me.timer = 0;
|
||||
try {
|
||||
fetch("/__dump__/enum_trace.json", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ at: new Date().toISOString(), count: Me.rows.length, trace: Me.rows }),
|
||||
});
|
||||
} catch (E2) {}
|
||||
}, 1500);
|
||||
}
|
||||
},
|
||||
});
|
||||
E.push({
|
||||
enum: (this.y7h_1 && this.y7h_1.name) || "",
|
||||
pos0: P0,
|
||||
pos1: S && typeof S.g2t === "function" ? S.g2t() : -1,
|
||||
bit: (t.f7h_1 && typeof t.f7h_1.y7g_1 === "number") ? t.f7h_1.y7g_1 : -1,
|
||||
});
|
||||
}
|
||||
} catch (E4) {}
|
||||
return null;
|
||||
}),
|
||||
(z(Kt).s7h = function (t, n) {}),
|
||||
|
||||
Reference in new issue
Block a user