scan_sourid.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env python3
  2. """scan_sourid.py — 从存量抓包 jsonl 提取每张图的 SC51/SC634 sourid。
  3. SC51/SC634 body 是 encode6 编码 JSON(含 MapName/MapId/sourid/Minimap)。
  4. body_hex 字段是编码后字节 → decode6 → JSON → 提取。
  5. 用法: uv run python scripts/scan_sourid.py (protocol_bot/ 下执行)
  6. """
  7. from __future__ import annotations
  8. import glob
  9. import json
  10. import sys
  11. sys.path.insert(0, "src")
  12. from pbot.codec.bitbuf import decode6 # noqa: E402
  13. def try_decode_body(hexstr: str) -> dict | None:
  14. try:
  15. raw = decode6(bytes.fromhex(hexstr))
  16. text = raw.decode("utf-8", errors="replace")
  17. start = text.find("{")
  18. if start < 0:
  19. return None
  20. return json.loads(text[start:text.rfind("}") + 1])
  21. except Exception:
  22. return None
  23. def main() -> None:
  24. results: dict[str, dict] = {}
  25. for path in sorted(glob.glob("/tmp/cap_*.jsonl")):
  26. try:
  27. with open(path, encoding="utf-8", errors="replace") as f:
  28. for line in f:
  29. if '"msg": 51,' not in line and '"msg": 634,' not in line:
  30. continue
  31. try:
  32. rec = json.loads(line)
  33. except ValueError:
  34. continue
  35. if rec.get("msg") not in (51, 634):
  36. continue
  37. body = rec.get("body_hex")
  38. if not body:
  39. continue
  40. j = try_decode_body(body)
  41. if not j:
  42. continue
  43. name = j.get("MapName") or j.get("MapId")
  44. if not name:
  45. continue
  46. key = f"{name}"
  47. if key in results and results[key].get("_src") == "SC51":
  48. continue
  49. j["_src"] = f"SC{rec['msg']}"
  50. j["_file"] = path.split("/")[-1]
  51. results[key] = j
  52. except OSError:
  53. continue
  54. print(f"{'显示名':<12} {'MapId':<12} {'sourid':<8} {'Minimap':<8} 来源")
  55. print("-" * 70)
  56. for name in sorted(results):
  57. j = results[name]
  58. print(f"{name:<12} {str(j.get('MapId','')):<12} "
  59. f"{str(j.get('sourid','')):<8} {str(j.get('Minimap','')):<8} "
  60. f"{j['_src']} @{j['_file']}")
  61. if __name__ == "__main__":
  62. main()