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文件存在(会 embedorg.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 输出。
条目索引
核心与运行时机制
- MCLib 核心与任务队列 -
MCLib.init()契约、TaskQueue、模块持有者 - 共享状态与版本仲裁 -
Launch.blackboard共享 + cglib 方法重定向 + 最新副本选举 - Forge 事件钩子 - 订阅的六个事件、所用总线、取消性分析
- 反射访问点 - 全部
ReflectionHelper/getDeclaredField目标与 SRG 名
三个共享模块
- AssetDirector -
ADConfig资源声明与AssetDirectorAPI.register - AssetFetcher - Mojang 接口交互、索引缓存、SHA-1 校验下载
- 多版本原版资源包 -
minecraft_<版本>资源域注入、1.7.10/1.13 路径换算 - SSL 信任库替换 -
SSLHacker的老 Java 补丁与MCUtil抽象层 - SloppyDepLoader - 可选依赖声明、版本合并、异步下载、重启提示
- UpdateCheck - update JSON 求解、分类语义、
updates.html渲染
配置、GUI 与工具
- 配置文件 - 两个 cfg 的全部 9 个选项与加载时机
- GUI 注入 - 主菜单更新按钮、重启对话框、自绘 tooltip
- ItemConfigHelper - 通配符物品黑名单解析
- 零散工具类 -
JsonUtil与InventoryUtils2