MCLib

[!INFO] Git Commit: aa4acec | Updated: 2024-11-05

MCLib 是 makamys 编写的一个 Java 库(非 Forge mod),供 Minecraft 1.7.10 的其他 mod 通过 shading 引入。GTNH fork 适配了 ForgeGradle 1.2.11 / Java 8 环境。

它自身不注册任何方块、物品、实体、配方、附魔或维度。全部内容是给宿主 mod 用的 API:更新检查、资源下载、可选依赖下载,以及一套"多个 shade 副本只跑最新那份"的共享状态机制。

基本信息

属性 值
源码目录 /Users/evlos/a/mirror/MCLib/
包根 makamys.mclib
Gradle modid makamys.mclib(仅供 archivesBaseName 与 srgExtra 用,不是 Forge 注册的 modid)
Minecraft 1.7.10
Forge 10.13.4.1614-1.7.10
发布版本 0.3.7.7
Java 源文件 38 个(其中 3 个在 test/ 包,默认从 jar 排除,实际发布 35 个)
打包依赖 cglib:cglib-nodep:3.1(打包进去)、codechicken:CodeChickenLib:1.7.10-1.1.3.140:dev(仅编译,不打包)
构建插件 net.ltgt.apt 0.10 + Lombok 1.18.4
日志名 mclib、mclib(<宿主modid>)、updatechecklib、AssetDirector、SloppyDepLoader

架构总览

MCLib.init()  ← 宿主 mod 在 FMLConstructionEvent 调用
  │
  ├── 共享状态层  Launch.blackboard + cglib 代理 → 全场只跑最新副本
  │     ├── TaskQueue          按 LoaderState 延迟执行,版本高者胜
  │     └── SharedLibHelper    版本仲裁 + 静态字段代理化
  │
  ├── 三个共享模块(都是 public static API)
  │     ├── UpdateCheck        update JSON 检查 → updates.html → 主菜单按钮
  │     ├── AssetDirector      从 Mojang 下载 1.13+ 资源 → 挂成 minecraft_<ver> 资源域
  │     └── SloppyDepLoader    可选依赖自动下载(失败不退出游戏)
  │
  └── 纯工具类
        ├── ItemConfigHelper / BackpackConfigHelper   通配符物品黑名单
        ├── InventoryUtils2                           CCL 库存单趟插入
        └── JsonUtil                                  Gson 取或建

API 表面

宿主 mod 实际会 import 的类,按功能分组。所有类均在上述包路径下。

引导与共享状态

类 关键成员
core.MCLib init()、init(boolean subscribe)、VERSION、RESOURCES_VERSION、LOGGER、GLOGGER、FML_MASTER
core.MCLibModules public static UpdateCheckAPI updateCheckAPI(唯一的共享模块入口)
core.TaskQueue enqueueTask(LoaderState, String, Runnable[, ComparableVersion])
core.sharedstate.SharedReference<T> get(namespace, name, Class) / get(namespace, name, Supplier)
core.sharedstate.SharedLibHelper register、isNewestLib、getNewestLibPackage、shareifyClass、findNewestLibClass
core.sharedstate.SharedModuleMethodRedirector cglib MethodInterceptor 实现
core.sharedstate.SharedField 运行时保留的空标记注解(当前逻辑中已被注释停用)

三个共享模块

类 关键成员
updatecheck.UpdateCheckAPI submitModTask(modid[, version], url)、submitTask(name, version, categoryID, url)、registerCategory(id, version, displayName, backwardsCompatible)、MODS_CATEGORY_ID、RESOURCE_PACKS_CATEGORY_ID
sloppydeploader.SloppyDepLoaderAPI addDependenciesForMod(String modid, SloppyDependency...)
sloppydeploader.SloppyDependency 五参构造 (repo, filename, testClass, dev, pattern)、serializeToString()
ext.assetdirector.AssetDirectorAPI register(ADConfig)
ext.assetdirector.ADConfig addObject(version, path)、addSoundEvent(version, name[, category])、addJar(version)

工具类

类 关键成员
config.item.ItemConfigHelper resolveItem、resolveItemList、ensureNamespaced
config.item.BackpackConfigHelper NON_NESTABLE_BACKPACK_BLACKLIST、CONFIG_DESCRIPTION_SUFFIX、isAllowed(ItemStack)
ccl.inventory.InventoryUtils2 insertItem(InventoryRange, ItemStack, boolean simulate, int pass)
json.JsonUtil getOrCreateObject、getOrCreateArray、getOrCreateElement

内部实现(宿主 mod 一般不直接用,但会影响行为)

类 用途
updatecheck.UpdateCheckLib 静态块自注册两条总线;持有预置分类、线程池、UPDATES_BUTTON_ID
updatecheck.UpdateCheckTask 版本求解算法;Result、Hyperlink
updatecheck.ResultHTMLRenderer 写 updates.html
updatecheck.MockHelper mock:// 假网络,仅测试用
updatecheck.gui.GuiButtonGeneric / GuiButtonUpdates 主菜单更新按钮
updatecheck.Util openURLInBrowser、drawSimpleTooltip
sloppydeploader.SloppyDepLoader NS 常量、IDownloadDisplay、VersionedFile、Dependency、DepLoadInst
sloppydeploader.SloppyDepDownloadManager 单线程池异步下载
sloppydeploader.GuiRestartNotification 重启提示对话框
ext.assetdirector.AssetDirector SOUNDS_JSON_REQUESTED、preInit 流程
ext.assetdirector.AssetFetcher 端点常量、索引结构、哈希校验
ext.assetdirector.mc.MultiVersionDefaultResourcePack 资源域注入与 1.7.10/1.13 路径换算
ext.assetdirector.ResourcePackUtil 取原版资源包列表、isBuiltIn
ext.assetdirector.SSLHacker 老 Java 的 SSL 信任库补丁
ext.assetdirector.mc.MCUtil getMCAssetsDir、getInstanceDir、ProgressBar、Version

事件

本 mod 不声明任何自定义事件,也不向任何总线 post 事件。 它订阅以下 FML / Forge 生命周期事件:

事件 注解 处理者 总线 触发时机与行为
FMLPreInitializationEvent @Subscribe MCLib.onPreInit FML 母总线 pre-init;本副本最新时跑 SloppyDepLoader.preInit,随后消费任务队列(触发 AssetDirector)
FMLInitializationEvent @Subscribe DepLoadInst.onInit FML 母总线 init;仅用于把自身挂上 Forge 总线
FMLPreInitializationEvent @Subscribe UpdateCheckLib.preInit FML 母总线 方法体为空
FMLPostInitializationEvent @Subscribe UpdateCheckLib.postInit FML 母总线 post-init;等所有检查完成后写 HTML、更新按钮数字
GuiOpenEvent @SubscribeEvent + @SideOnly(CLIENT) DepLoadInst.onGui MinecraftForge.EVENT_BUS 打开主菜单时若有新下载的依赖,替换为重启动提示,然后注销自身
GuiScreenEvent.InitGuiEvent.Post @SubscribeEvent + @SideOnly(CLIENT) UpdateCheckLib.onGui MinecraftForge.EVENT_BUS 主菜单初始化后注入 20x20 更新按钮

这些事件里只有 GuiOpenEvent 可取消,MCLib 通过替换 event.gui 而非 setCanceled 来实现提示;其余五个 FML 生命周期事件不可取消。

网络

没有任何 Forge 网络消息。 无 SimpleNetworkWrapper、无 IMessage、无 NetworkRegistry、无 registerMessage、无 FMLEmbeddedChannel,因此也没有注册 id 或载荷字段。

它做的是普通的出站 HTTP / 文件拉取:

发起方 目标 协议细节
AssetDirector launchermeta.mojang.com 版本清单、各版本 JSON、resources.download.minecraft.net 资源对象 HTTPS GET,按 SHA-1 校验;端点可用系统属性覆盖
SloppyDepLoader 任意 repo URL 下的 jar 普通 URL.openConnection,User-Agent "Sloppy DepLoader Downloader",超时 5000 ms
UpdateCheck 宿主 mod 提供的 update JSON HTTPS GET,线程池最多 4 并发;测试时可用 mock:// 假 URL
SloppyDepLoader 客户端 getClassBytes("net.minecraft.world.World") 本地类加载器探测,不是网络

配置文件

共 2 个,均为 Forge Configuration 格式,写在 Launch.minecraftHome/config/ 下。详见 配置文件。

文件 维护类 选项数
sloppydeploader.cfg ConfigSDL 2
UpdateCheckLib.cfg ConfigUCL 7

AssetDirector 不写配置,只读系统属性 assetDirector.manifestEndpoint、assetDirector.resourcesEndpoint、assetDirector.downloadTimeout、assetDirector.downloadAttempts、assetDirector.dumpSoundsJson、minecraft.sharedDataDir(回退环境变量 MINECRAFT_SHARED_DATA_DIR)。UpdateCheck 另有测试属性 updateCheckLib.test。

所有选项的完整表格见 配置文件 条目。

指令与热键

指令:没有。 grep -rn -E "ICommand|CommandBase|addChatCommand|getRequiredPermissionLevel" src/ 无结果,因此也没有权限等级。

热键:没有。 grep -rn "new KeyBinding" src/ 无结果,没有默认按键。

唯一涉及键盘的是 GUI 注入 中更新按钮的 Shift+左键:点击瞬间用 Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) 轮询,把 URL 复制到剪贴板。它不注册进 Forge 的按键设置界面,不占用任何 KeyBinding。

Access Transformer / coremod / mixin

一个都没有。 见 反射访问点 的完整清单。构建配置的证据:

  • gradle.properties 无 coreModClass、无 accessTransformersFile,只有 enable_mixin=false
  • 仓库内无 META-INF/ 目录,因此没有 META-INF/*_at.cfg
  • 无 mixins*.json / *.mixins.json、无 mixinPlugin
  • buildscript/forge-1.7-mixin.gradle 文件存在(会 embed org.spongepowered:mixin:0.7.11-SNAPSHOT),但本项目未启用

所有私有字段访问改用运行期 ReflectionHelper.getPrivateValue(声明类, 实例, 字段名, SRG名),SRG 名与 Access Transformer 等价。涉及的 Minecraft 字段有四个:

声明类 字段 SRG 名
Minecraft fileAssets field_110446_Y
Minecraft defaultResourcePacks field_110449_ao
SimpleReloadableResourceManager domainResourceManagers field_110548_a
FallbackResourceManager resourcePacks field_110540_a

另有 Loader.modController、LoadController.masterChannel 两个 FML 字段(无 SRG 名),以及 URLClassLoader.ucp、URLClassPath.loaders、URLClassPath.lmap 三个 JDK 字段。

本 mod 没有的内容(grep 证据)

以下每一项都已在源码中核对过,不是遗漏,而是本 mod 确实不包含。

1. 方块、物品、实体、TileEntity

$ grep -rn -E "registerBlock|registerItem|registerTileEntity|registerEntity|registerDimension|registerWorldProvider|registerKeyBinding|registerCommand|registerEventHandler|registerEnchantment|registerAchievement|registerBiome|GameRegistry" src/
(no match)

$ grep -rn -E "extends (Block|Item|TileEntity|Entity)\b" src/
(no match)

因此 block/、item/、entity/、multiblock/ 四个维度在本 wiki 中不存在条目。

2. 一个可发布的 @Mod 主类

这是本 mod 最大的事实:MCLib 不是 mod,是库。 仓库里连 mcmod.info 都没有。

$ find . -name "mcmod.info" -not -path "./.git/*"
(无输出)

$ grep -rn "@Mod(modid" src/
src/main/java/makamys/mclib/ext/assetdirector/test/ADTest.java:24:@Mod(modid = "ADTest", version = "0.0")
src/main/java/makamys/mclib/sloppydeploader/test/SDLTest.java:9:@Mod(modid = SDLTest.MODID, version = "0.0")
src/main/java/makamys/mclib/updatecheck/test/UCLTest.java:21:@Mod(modid = UCLTest.MODID, version = "0.0")

三处 @Mod 全在 test/ 包里,而 project.gradle 默认把这三个包从 jar 排除(除非加 -Ptest_sdl / -Ptest_uc / -Ptest_ad)。它们是示例 mod,不是库自身。

gradle.properties 里的 modid=makamys.mclib 只影响 archivesBaseName 和 README 里给使用者的 srgExtra 规则,不代表 Forge 会加载一个叫 MCLib 的 mod。

3. 自定义事件

$ grep -rn -E "extends Event\b|@Cancelable|EVENT_BUS.post|bus.post" src/
(no match)

它只订阅 FML/Forge 既有事件,从不定义或派发自己的事件。完整订阅表见上文"事件"章节。

4. Forge 网络消息

$ grep -rn -E "SimpleNetworkWrapper|IMessage|NetworkRegistry|registerMessage|FMLEmbeddedChannel" src/
(no match)

无消息类、无注册 id、无载荷字段、无频道名。

5. 指令

$ grep -rn -E "ICommand|CommandBase|addChatCommand|getRequiredPermissionLevel" src/
(no match)

6. 热键

$ grep -rn "new KeyBinding" src/
(no match)

7. NBT 读写

$ grep -rn "NBTTagCompound|writeToNBT|readFromNBT|getCompoundTagAt|setTagInfo" src/
(no match)

没有 TileEntity 就没有 NBT 序列化需求。唯一的序列化手段是 Gson(JsonUtil)和 SloppyDependency.serializeToString() 的逗号分隔字符串。

8. 配方、世界生成、附魔、成就、群系、药水效果

$ grep -rn "IRecipe|CraftingManager|WorldGen|populate|BiomeGen|Enchantment|Achievement|Potion|PotionEffect|OreDictionary" src/
(no match)

$ grep -rn -E "extends Entity|registerPotion" src/
(no match)

9. Access Transformer / coremod / mixin

见上文"Access Transformer / coremod / mixin"章节的全部 grep 输出。

条目索引

核心与运行时机制

三个共享模块

配置、GUI 与工具