﻿危险指示灯（显示附近敌人数）- 盒子插件发布说明
===================================================
生成日期：2026-10-28
适用客户端：2.4.1.1（WOT 国服）
作者：C.C.Nemo（原作 protanki / tv.protanki.enemyannouncer）

一、文件清单
---------------------------------------------------
危险指示灯_2.4.1.1.wbp      611,613 B
SHA256  4AEBBFC36E8E12BEFC177A658F9B763A7473284D44E739CC22F7D706FCED6B7F
包内 8 个条目：wbpinfo + wbpimg.jpg + 6 个 Files/

二、包内三段内容
---------------------------------------------------
EscapePath（卸载即删，2 条）
  mods/2.4.1.1/tv.protanki.enemyannouncer_3.4.08.wotmod
  mods/configs/protanki/enemyAnnouncer.json

KeepPath（卸载不删，4 条）
  mods/2.4.1.1/poliroid.modslistapi_1.8.0.wotmod
  mods/2.4.1.1/izeberg.modssettingsapi_1.7.1.wotmod
  mods/2.4.1.1/net.openwg.gameface_1.2.2.wotmod
  mods/2.4.1.1/zzz.ccnemo.scaleform.compat_1.1.0.wotmod

FileList：空

三、KeepPath 的正确语义
---------------------------------------------------
EscapePath = 安装到磁盘，卸载时删除。      → 插件独有文件
KeepPath   = 安装到磁盘，卸载时不删除。    → 多插件共享的依赖
FileList   = 安装 + 在 res_wbp\<版本>\ 留 "<包ID>.原文件名" 备份，卸载时还原

证据：盒子线上包 pId=346（最小+实时落弹环）把 modslistapi、modssettingsapi、
gameface 三库只写在 KeepPath；pId=298（伤害统计）把 mod_mods_gui、
gambiter.guiflash 写在 KeepPath，其余 20 条写在 EscapePath。
res_wbp\list.xml 是盒子安装登记表，res_wbp\filemap.xml 记录
"SourceFile → <包ID>.文件名" 的映射。

把 KeepPath 条目全搬进 EscapePath 是错的——用户卸载本插件时会把 modslistapi、
modssettingsapi、gameface 一起删掉，连累伤害统计、落弹环、点亮提醒等插件。

四、依赖取舍：为什么不用 net.openwg.common
---------------------------------------------------
历史包 [2.4.1.0] 带了 net.openwg.common_2.8.4.0000.wotmod（8 MB，内含 17 个
原生库 openwg_gpu.pyd / sl.*.dll 等）。我们实测本插件完全不需要它：

  移走 net.openwg.common 后启动 → 无弹窗、无 ImportError、无 OpenWG 报错、
  车库插件设置正常、进战斗三色灯与倒计时全部正常。

而 [2.3.1.3] 那个最老的包本身就只带四个文件（本体 + modslistapi 1.7.9 +
modssettingsapi 1.7.0 + gameface 1.1.6），从来没有 openwg.common。

去掉它的收益：
  1. 包体从 3.66 MB 降到 0.61 MB；
  2. 17 个原生库不再被解包到 mods\temp —— 这正是其他玩家看到
     "temp 一堆文件" 的来源（openwg_loader 的 PATH_TEMP = "mods/temp"，
     openwg_native 把 wotmod 里的 .pyd/.dll 解包过去再加载）；
  3. 不必给干净客户端多塞 6 MB 用不上的 GPU/音频组件。

五、zzz.ccnemo.scaleform.compat_1.1.0.wotmod 是什么
---------------------------------------------------
50,117 B，内部 6 个条目（全部 STORED）：

  meta.xml
  res/scripts/client/gui/Scaleform/framework/g_entitiesFactories.pyc   1,415 B
  res/scripts/client/openwg_loader/__init__.pyc                       15,600 B
  res/scripts/client/openwg_loader/dag.pyc                            11,023 B
  res/scripts/client/openwg_loader/ordered_dict.pyc                    7,898 B
  res/scripts/client/openwg_vfs/__init__.pyc                          11,340 B
  res/scripts/client/openwg_scaleform/__init__.pyc                     1,457 B

为什么必须这么装：
1. g_entitiesFactories 是 2.4.1.0 起官方删除的 Scaleform 模块，mods_gui、
   guiflash、modssettingsapi、quests、DModButton、危险指示灯 6 个老插件都靠它，
   只能自己补（modssettingsapi 1.7.1 的 pyc 里能直接搜到 g_entitiesFactories，
   缺了它车库设置面板就打不开）。
2. openwg_loader / openwg_vfs / openwg_scaleform 是 OpenWG 的引导模块。
   net.openwg.gameface 走 OpenWG，如果 mod_openwg 找不到 openwg_loader，
   每次事件都会报 "ImportError: No module named openwg_loader"，OpenWG 等于没启动。
3. 这些文件不能作为散装 res_mods 文件投递（见第六节第 2 条），
   所以打包成 wotmod，通过 VFS 提供。

风险提示：这个包以 KeepPath 投递，卸载后仍留在 mods\2.4.1.1 下。
若将来客户端官方恢复了 g_entitiesFactories 模块，它会遮蔽官方实现，需要手工删除。

六、盒子打包的硬规则（实测，血泪教训）
---------------------------------------------------
1. wbpinfo 里的声明路径必须用【正斜杠】，且以 mods/ 开头。
   反斜杠写法（mods\configs\protanki\xxx.json）盒子会静默跳过，不报错。
   官方包全部是 mods/2.3.1.3/xxx.wotmod、mods/configs/DMod/xxx.json 这种形式。

2. res_mods 下的文件不能写进 EscapePath / KeepPath。
   这两个段只认 mods/ 开头的路径。res_mods 内容只能走 FileList，
   而 FileList 的声明路径是【相对 res_mods\<版本>\ 的】，例如 gui/flash/debugPanel.swf。

3. FileList 只能覆盖客户端 res 里【已经存在】的文件，不能新建文件。
   实测：声明 gui/flash/zz4a.txt 时，盒子只把内容备份到
   res_wbp\2.4.1.1\<包ID>.zz4a.txt，真名路径不写。
   所以 g_entitiesFactories.pyc 这种"客户端里已不存在"的文件，FileList 装不进去，
   只能走 wotmod。

4. （wotmod 自身）内部条目必须是【不压缩/STORED】。
   .NET 的 CompressionLevel::NoCompression 只是把数据以未压缩块塞进 DEFLATE 流，
   压缩方法字段仍是 8，客户端会报 "load error: compression not supported"。
   必须用真正的 STORED（zip method 0），例如 Python 的 zipfile.ZIP_STORED。
   官方所有 wotmod 的条目都是 STORED。

七、路径映射规则（声明 → 包内 payload）
---------------------------------------------------
  mods/<版本>/x.wotmod                →  Files/x.wotmod
  mods/configs/a/b.json               →  Files/configs/a/b.json
  gui/flash/x.swf（FileList，相对）   →  Files/gui/flash/x.swf

打包脚本里已按此规则逐条反推校验：6 条声明全部对上 payload。

八、绿灯不亮的原因（历史问题，已解决）
---------------------------------------------------
配置里 "logicSightedDisplay" 与 "logicSightedSound" 被关成 false 时，
插件不再跟踪"被点亮"的目标，而绿灯判定条件正是"敌人在视线外但已被点亮"，
于是绿灯永远不亮；黄灯（视野外但能造成伤害）、红灯（50 米内）走距离判定不受影响。

本包内置配置与 [2.3.1.3]/[2.4.0.2] 那两版逐字节相同（只调整了 offset 位置）：
    "logicSightedDisplay": true
    "logicSightedSound": true

插件本体 tv.protanki.enemyannouncer_3.4.08.wotmod 在 2.3.1.3 / 2.4.0.0 /
2.4.0.1 / 2.4.0.2 / 2.4.1.0 五个历史包中哈希完全相同（AD055A8EC1EB46BE…，
345,972 B），本包用的就是同一份二进制，外观与行为与老包完全一致。
唯一区别是默认位置 offset（老包 -74,109 / -74,151 / -74,151，
本包 -74,53 / -46,249 / -46,229，1920×1080 实测），玩家拖动一次即按自己的存盘。

3.4.08 不认 viewMode / dockIdleLight / dockSize / dockSkin / freeFlow /
freeIdleLight / dockMapPath / dockPosition 这些键（启动重写配置时直接丢弃）。

九、关于 mods\temp 与 mods\configs\net.openwg.common
---------------------------------------------------
这两个目录是 OpenWG 运行时产生的，不是盒子安装器建的
（WBPInstaller.exe 里没有 mods\temp / configs 字面量）：
  mods\temp                       → openwg_loader 的 PATH_TEMP，
                                     openwg_native 把 wotmod 内的原生库(.pyd/.dll)
                                     解包到这里再加载
  mods\configs\net.openwg.common  → 运行时写入的配置目录

本包现在不含 net.openwg.common（没有原生库），实测安装运行后这两个目录都不出现。
如果玩家看到它们，来源是别的带原生组件的 OpenWG 包；无害，删掉不影响，
下次启动会按需重建。

十、其他常见现象（非本包问题）
---------------------------------------------------
"NO HTML FILE"：来自 mod_mods_gui（Mod Browser）。它按模板加载
  <插件>/i18n/module_settings.html，找不到就显示这个占位页。
  本插件走 modsSettingsApi，与 mod_mods_gui 无关；该占位属于其他注册给
  mod_mods_gui 的插件（群里说的"俄文排序设置"就是那个插件自己的页面）。

设置窗口里的选项是俄文：modsSettingsAPI 官方只提供 be/de/en/hu/pl/ru/uk 七种
  语言，没有中文，中文客户端会回退到俄语。本包已把它的语言包改成中文
  （把 ru.yml 换成中文 + 新增 zh_cn.yml），所以窗口标题与按钮是中文；
  但窗口内的"选项文字"由危险指示灯插件本体提供，其 pyc 字节码被作者加密
  （字节码段熵 7.95，普通 pyc 约 4.8，srcsize 仅 99），无法反编译修改，
  因此选项仍为俄文。功能不受影响，默认值已按常用配置预置好。

十一、发布前自测（已在 2.4.1.1 全部通过）
---------------------------------------------------
环境：清空所有散装运行时（openwg_packages / openwg_loader / g_entitiesFactories.pyc
全部移走），只用盒子安装本包。
  1) 安装后 6 个文件全部落地                    ✅ 6/6
  2) compat wotmod 内部 6 条目均为 STORED        ✅
  3) 启动日志 "zzz.ccnemo.scaleform.compat ... loaded"  ✅
  4) 无 "No module named openwg_loader"          ✅
  5) 无 "compression not supported"              ✅
  6) 绿灯 / 黄灯 / 红灯 / 倒计时                  ✅ 全部正常（含去掉 common 后）
  7) 车库内各插件设置面板均可打开                 ✅
  8) 设置窗口标题与按钮为中文                     ✅（窗口内选项沿用插件原文，俄文）
  9) 不产生 mods\temp / mods\configs\net.openwg.common  ✅

十二、兼容性备注
---------------------------------------------------
1. 版本号与路径写死为 2.4.1.1；客户端升级后需重新打包
   （重跑 build_危险指示灯_wbp.ps1，脚本自动读 version.xml）。
2. 默认配置：skinSize=horizontal、skinVariant=new。
3. 玩家若在插件设置里关闭"点亮提示"相关选项，绿灯会失效——插件设计，非包问题。
4. 其他依赖 OpenWG 的插件（伤害统计、落弹环等）各自会带自己的 openwg 组件，
   与本包互不影响。