ClientProxy

客户端全部注册

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.proxy.ClientProxy
行数 75
父类 CommonProxy

客户端的全部初始化都在这里(75 行是三个 proxy 里最长的)。

preInit(:30-47)—— 8 步

super.preInit(event);                                             // 1. logger = event.getModLog()
ClientConfigurationHandler.init(event.getSuggestedConfigurationFile());  // 2. 读 cfg
ValueRegistry.INSTANCE.init();                                    // 3. 注册 31 个 value 函数
PluginLoader.getInstance().preInit(event);                        // 4. 探测 5 个集成
core.moveConfig(getModConfigurationDirectory(), configName);       // 5. 旧配置搬进子目录
core.setConfigDirectory(...resolve("InGameInfoXML"));              // 6. 设配置目录
core.setConfigFileWithLocale(configName);                         // 7. 定位配置文件
core.reloadConfig();                                              // 8. 解析
ClientConfigurationHandler.propFileInterval.setConfigEntryClass(NumberSliderEntry.class);
ClientConfigurationHandler.propscale.setConfigEntryClass(NumberSliderEntry.class);

顺序不可调换的原因

约束 原因
3 必须在 8 之前 reloadConfig 解析配置时要用 Value.fromString → forName → 查 ValueRegistry
7 必须在 8 之前 reloadConfig 依赖 parser 已由 setConfigFile 选定
4 必须在 8 之前 集成 tag 要在解析前注册,否则配置文件里的集成 tag 全变 <ERROR>

⚠️ 第 4 步只 preInit 不 postInit —— PluginLoader 的 preInit 只做「反射加载并筛选 canLoad()」, 真正 plugin.load()(注册集成 tag)在它的 postInit(:60-69)。

而集成 tag 的注册发生在 ClientProxy.postInit(:61-64), 晚于本方法第 8 步的 reloadConfig()。

所以首次启动时配置文件里的集成 tag 会解析失败(得到 <ERROR>), 需要 /igi reload 或重进世界才正常 —— 因为解析产出的 Value 树在 reloadConfig 时就已固化。

init(:49-58)—— 4 处注册

super.init(event);                                                   // PacketHandler.init()
FMLCommonHandler.instance().bus().register(new TickerManager());      // 1
FMLCommonHandler.instance().bus().register(ClientConfigurationHandler.INSTANCE);  // 2
FMLCommonHandler.instance().bus().register(new KeyInputHandler());    // 3
ClientCommandHandler.instance.registerCommand(new InGameInfoCommand());  // 4
((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager())
        .registerReloadListener(ClientConfigurationHandler.INSTANCE);  // 5
# 对象 事件总线 作用
1 TickerManager FML 按连接状态注册 Ticker
2 ClientConfigurationHandler.INSTANCE FML 收 ConfigChangedEvent
3 KeyInputHandler FML 收 KeyInputEvent
4 InGameInfoCommand — 注册 /igi
5 ClientConfigurationHandler.INSTANCE 资源管理器 收资源重载

⚠️ TickerManager 只订阅连接/断开事件, Ticker 本身在 onClientConnect 时才被注册 (见 TickerManager)。 所以主菜单阶段没有任何 tick/render 处理。

⚠️ 第 5 步的 registerReloadListener 传的是 ClientConfigurationHandler.INSTANCE(不是 new), 与第 2 步同一个实例被注册到两个不同总线 —— 该类同时实现 IResourceManagerReloadListener(见其条目)。

postInit(:60-64)

PluginLoader.getInstance().postInit(event);   // 真正 load 5 个集成(注册集成 tag)
TagRegistry.INSTANCE.init();                  // 注册 151 个内置 tag

⚠️ 顺序与 preInit 的需求冲突: PluginLoader.postInit 先执行(注册集成 tag), TagRegistry.init() 后执行(注册内置 tag)。 两者注册到同一张 stringTagMap,互不覆盖(名字不同), 所以顺序本身无害。

但如 preInit 所述,此刻配置早已解析完毕(第 8 步), 集成 tag 的注册对已解析的配置无效。

⚠️ TagRegistry.init() 打的日志 "Registered {} tags" 只统计内置 tag, 不含 5 个集成贡献的 tag。

serverStarting / serverStopping(:66-74)

Tag.setServer(event.getServer());    // 存进 Tag 的 static server 字段
Tag.setServer(null);

⚠️ 这是客户端 proxy 里的服务端事件 —— FMLServerStartingEvent 在客户端也会触发(单机)或被 FML 转发, 用于把 MinecraftServer 引用交给 Tag 的静态字段。 反注册时置 null,避免主菜单期访问已销毁的 server。

相关