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。
相关
- CommonProxy - 父类
- ServerProxy - 对侧
- TagRegistry - postInit 的调用方
- PluginLoader - 集成的两阶段加载