RegionLib(区域存档库)
[!INFO] Git Commit:
7dd1c24| Updated: 2025-11-28
RegionLib(modid RegionLib,根包 cubicchunks.regionlib)是 Minecraft Forge 1.7.10 的纯 Java 存档区域文件库,为 GTNH 生态提供一套"把任意 key 对应的一堆 ByteBuffer 存进分区域打包文件"的底层实现。全 mod 42 个 Java 文件、0 个方块 / 0 个物品 / 0 个实体 / 0 个配置项 / 0 条指令。
⚠️ 重要更正:本 mod 不是世界生成 / 矿脉配置后端。仓库里没有 region 配置、没有矿脉(vein)定义、没有
IGenerator接口、没有任何 JSON / YAML 数据文件(grep -rni "vein|oredistribut|smallore|mining|regionconfig|IGenerator" src/零命中)。“region” 在这里指的是存档区域文件(region file),即 Anvil 存档格式里那个把世界切成 32×32 区块的.mca文件抽象,与世界生成里的"区域配置"毫无关系。
README 原文一句话概括:General region-based save format library, made for the Cubic Chunks mod。
基本信息
| 项目 | 值 | 来源 |
|---|---|---|
| modid | RegionLib(首字母大写) |
RegionLib.java:18 public static final String MODID = "RegionLib" |
@Mod 类 |
cubicchunks.regionlib.RegionLib |
RegionLib.java:15 |
@Mod name |
RegionLib |
RegionLib.java:15 |
| 接受的 MC 版本 | [1.7.10] |
RegionLib.java:15 acceptedMinecraftVersions |
version |
Tags.VERSION(构建期生成) |
gradle.properties generateGradleTokenClass = cubicchunks.regionlib.Tags |
modGroup(根包) |
cubicchunks.regionlib |
gradle.properties |
| Minecraft | 1.7.10 | gradle.properties minecraftVersion |
| Forge | 10.13.4.1614 | gradle.properties forgeVersion |
| 上游 | https://github.com/GTNewHorizons/RegionLib.git |
git remote -v |
| 作者 | Cubic Chunks 团队(2016 起),GTNH fork | LICENSE.txt / 各文件头 Copyright (c) 2016 contributors |
| 许可 | MIT | LICENSE.txt |
| Java 文件数 | 42 | find src -name "*.java" | wc -l |
| 源码包 | api(对外 API)/ lib(通用实现)/ impl(具体格式实现)/ util |
— |
⚠️
gradle.properties写的是modId = regionlib(小写),但真正注册进 FML 的是@Mod(modid = RegionLib.MODID)里的RegionLib。任何依赖它的 mod 写@Mod(modid = ..., dependencies = "required-after:RegionLib")时必须用大写R。
与 Minecraft 的耦合程度
全仓库没有一处 import net.minecraft.*。 与 FML 的接触面只有 11 行:
| 文件 | 接触点 |
|---|---|
RegionLib.java |
@Mod、@SidedProxy、@Mod.EventHandler × 4 |
CommonProxy.java |
FMLPreInitializationEvent / FMLInitializationEvent / FMLPostInitializationEvent / FMLServerStartingEvent 的 4 个空方法 |
@SidedProxy(clientSide = "cubicchunks.regionlib.CommonProxy", serverSide = "cubicchunks.regionlib.CommonProxy")
public static CommonProxy proxy;
clientSide 与 serverSide 指向同一个类,且 CommonProxy 的 4 个生命周期方法全部空实现。也就是说 RegionLib 在游戏里不做任何事——它纯粹是一个"被打包成 mod 以便被其它 mod 依赖"的库,运行时行为全部由调用方触发。
RegionLib.java导入了org.apache.logging.log4j.LogManager/Logger但从未使用(无Logger字段、无日志调用)。
外部依赖仅 3 个(grep -rho "^import ..." | sort -u):Guava(ImmutableMap / ImmutableList / ListMultimap / MultimapBuilder / Multimaps)、Netty(io.netty.buffer.ByteBuf——仅 SaveSection import 了它,文件里没有任何一处使用)、log4j2(同上,未使用)。dependencies.gradle 里只声明了 runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.7.4-GTNH:dev") 和 testCompile("junit:junit:4.11")——Guava / Netty 靠 Forge 环境自带。
API 接口与实现总表
这是本 mod 唯一值得成体系记录的部分:其它 mod 用到的就是下面这 9 个接口。区域数据的三层结构是 SaveSection(高层数据库)→ IRegionProvider(带缓存的访问)→ IRegion(单个区域文件)。
全部接口一览
| 接口 | 所在文件 | 方法 | 实现者 |
|---|---|---|---|
IRegion<K extends IKey<K>> |
api/region/IRegion.java |
writeValue / writeValues / writeSpecial / readValue / readValues / hasValue / forEachKey + flush / close |
Region<K>、ExtRegion<K> |
IRegionFactory<K> |
api/region/IRegionFactory.java |
getKeyProvider / getRegion / getExistingRegion / allRegions |
SimpleRegionFactory<K> |
IRegionProvider<K> |
api/region/IRegionProvider.java |
forRegion / fromRegion / forExistingRegion / fromExistingRegion / allRegions / allKeys / allEntries + flush / close |
SharedCachedRegionProvider<K> |
IKey<K extends IKey<K>> |
api/region/key/IKey.java |
getId / getRegionKey |
EntryLocation2D、EntryLocation3D、MinecraftChunkLocation |
IKeyProvider<K> |
api/region/key/IKeyProvider.java |
fromRegionAndId / getKeyCount / isValid |
EntryLocation2D.Provider、EntryLocation3D.Provider、MinecraftChunkLocation.Provider(均为静态内部类) |
IHeaderDataEntry |
api/region/header/IHeaderDataEntry.java |
write(ByteBuffer) |
IntHeaderEntry |
IHeaderDataEntryProvider<H, K> |
api/region/header/IHeaderDataEntryProvider.java |
apply(K)(继承 Function<K, H>)/ getEntryByteCount() |
EntryLocationHeaderEntryProvider<K>、TimestampHeaderEntryProvider<L> |
IKeyIdToSectorMap<H, P, K> |
lib/header/IKeyIdToSectorMap.java |
getEntryLocation(K)(default)/ getEntryLocation(int) / setOffsetAndSize / setSpecial / trySpecialValue / isSpecial / headerEntryProvider + Iterable<RegionEntryLocation> |
IntPackedSectorMap<K> |
SaveSection<S, K> |
api/storage/SaveSection.java(抽象类) |
save ×2 / load ×2 / allKeys / allEntries / forAllKeys(已废弃) / hasEntry + flush / close |
MinecraftSaveSection、SaveSection2D、SaveSection3D |
实现类全表
| 实现类 | 实现接口 | 底层存储 | 条目大小上限 | 关闭语义 |
|---|---|---|---|---|
Region<K> |
IRegion<K> |
单个 FileChannel 文件,头表 + 扇区 |
255 扇区(512 B → 130556 B;4096 B → 1044476 B) | close() 真正 flush + 关文件 |
ExtRegion<K> |
IRegion<K> |
每 key 一个文件的 .ext 目录 |
无(仅 Integer.MAX_VALUE 保护) |
close() 是 no-op |
SimpleRegionFactory<K> |
IRegionFactory<K> |
— | — | — |
SharedCachedRegionProvider<K> |
IRegionProvider<K> |
委托给 SharedCache |
— | 二次调用抛 IllegalStateException |
EntryLocation2D |
IKey<EntryLocation2D> |
— | — | 1024 条目 / 区域 |
EntryLocation3D |
IKey<EntryLocation3D> |
— | — | 4096 条目 / 区域 |
MinecraftChunkLocation |
IKey<MinecraftChunkLocation> |
— | — | 1024 条目 / 区域 |
IntHeaderEntry |
IHeaderDataEntry |
— | — | 单个 int |
EntryLocationHeaderEntryProvider<K> |
IHeaderDataEntryProvider<IntHeaderEntry, K> |
写扇区位图 | — | 4 B |
TimestampHeaderEntryProvider<L> |
IHeaderDataEntryProvider<IntHeaderEntry, L> |
写时间戳 | — | 4 B |
IntPackedSectorMap<K> |
IKeyIdToSectorMap<…> |
— | — | offset ≤ 16777215、size ≤ 255 |
MinecraftSaveSection |
SaveSection<…> |
Region 4096 扇区 + 时间戳 |
1044476 B | 单 provider,无回退 |
SaveSection2D |
SaveSection<…> |
Region 512 扇区 → ExtRegion |
130556 B,回退后无限 | 两层回退 |
SaveSection3D |
SaveSection<…> |
Region 512 扇区 → ExtRegion |
130556 B,回退后无限 | 两层回退 |
SaveCubeColumns |
—(Flushable + Closeable 组合体) |
持有一个 SaveSection2D + 一个 SaveSection3D |
— | 依次转发 2D、3D |
非接口的支撑类
| 类 | 作用 |
|---|---|
RegionKey |
区域名包装,只有 getName();equals / hashCode 只基于 name |
RegionSectorTracker<K> |
BitSet 扇区占用表 + 就地扩 / 找空段的分配算法 |
RegionEntryLocation |
(offset, size) 不可变对,带 withSize(int) |
Region.Builder<K> |
Region 的构造器,javadoc 自称"very unsafe" |
SimpleRegionFactory.RegionFactory<K> |
函数式接口 (IKeyProvider<K>, RegionKey) → IRegion<K> |
SimpleRegionFactory.RegionExistsPredicate<K> |
函数式接口 (IKeyProvider<K>, RegionKey) → boolean |
SharedCache |
硬/软限流的共享区域缓存(见 区域缓存上限) |
SharedCache.SharedCacheKey<K> / WrappedRegion<K> |
缓存键 = (RegionKey, 工厂引用身份);值 = (region, openedTime) |
Utils |
createDirectories(逐级建目录,刻意不用 Files.createDirectories 因为它不处理符号链接)/ readFully / writeFully ×2 / concat(流列表对半切分成平衡二叉树) |
BatchReadResult<K> |
批量结果:ImmutableMap read + ImmutableMap errored |
SaveCubeColumns |
2D + 3D 的组合入口 |
异常层级
java.io.IOException
├── UnsupportedDataException (RegionLib 包根)
│ └── UnsupportedDataException.WithKey 额外携带一个 Object key,getKey() 泛型转型取出
├── MultiUnsupportedDataException 多个 WithKey 作为 suppressed 挂在自身,getChildren() 转成 Map
├── util.CorruptedDataException 读到的长度 > 该条目占据的扇区字节数
├── util.SaveSectionException 批量原因用 addSuppressed 挂载
└── util/… 无
ExtRegion.writeSpecial 抛的是 UnsupportedOperationException(非上述体系),消息 "ExtRegion doesn't support special values"。IntPackedSectorMap.packed() 抛 IllegalArgumentException(unchecked),而 setOffsetAndSize 对同一约束抛 UnsupportedDataException(checked)——两条路径不一致。
游戏设定列表
本 mod 没有指令、没有开关式游戏规则;下列条目记录的是它唯一的配置面与存档后端的可调参数。
- 区域缓存上限 - 全 mod 唯一的可调参数:JVM system property
cubicchunks.regionlib.maxRegionCacheSize(默认256),SharedCache的硬/软限流、信号量票据与 LRU 近似淘汰全表 - 区域文件格式 -
Region打包扇区格式:4 字节长度前缀、size | (offset << 8)头表打包(size ≤ 255 / offset ≤ 16777215)、RegionSectorTracker扇区分配、列存式自定义头表、特殊值扩展点 .ext回退格式 -ExtRegion:<regionName>.ext/目录、每 key 一个整数名文件、.tmp+ATOMIC_MOVE+DSYNC的崩溃原子写、无大小上限、不支持特殊值- 多提供者回退链 -
SaveSection的有序 provider 列表:写入时"第一个接受者胜出、其余全擦除",读取时第一个应答者说了算,ensureUnique去重语义与批量路径 - 存档目录与文件命名 - 三种 key 类型的区域名正则与 id 打包(含 X/Z 顺序反转陷阱)、
region2d/region3d/目录树、allRegions()枚举行为的两个坑
维度列表
⚠️ 本 mod 没有任何 Minecraft 维度(
WorldProvider/DimensionType/registerDimension全部零命中)。下列三个条目是存档数据空间的坐标维度变体——同一套SaveSection机制下的三套分区/格式方案,与下界、末地无关。归入dimension/是因为它们是本 mod 仅有的"多套空间变体"。
- SaveSection2D - 二维存档区:32×32 = 1024 条目 / 区域,区域名
<X>.<Z>.2dr,目录region2d/,512 字节扇区 - SaveSection3D - 三维存档区:16×16×16 = 4096 条目 / 区域,区域名
<X>.<Y>.<Z>.3dr,目录region3d/,512 字节扇区,头表开销是 2D 版四倍 - Minecraft 原版存档区 - 对齐 Anvil 格式:
MinecraftRegionType的MCR/MCA两值、区域名r.<X>.<Z>.<ext>、4096 字节扇区、秒级时间戳头表、无.ext回退
随包发布的数据文件
一个都没有。
$ ls -d src/main/resources
ls: src/main/resources: No such file or directory
$ git ls-files | grep -v '\.java$'
.gitattributes
.github/workflows/build-and-test.yml
.github/workflows/release-tags.yml
.gitignore
HEADER.txt
LICENSE.txt
README.md
build.gradle.kts
dependencies.gradle
gradle.properties
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties
gradlew
gradlew.bat
jitpack.yml
repositories.gradle
settings.gradle.kts
- 无
mcmod.info(虽然gradle.properties注释提到 “available for mcmod.info population”,但文件本身不存在) - 无语言文件(
assets/<modid>/lang/*.lang不存在,因此本 wiki 条目中没有任何原版物品名可引) - 无任何 JSON / YAML / cfg:所有布局常量(
.2dr/.3dr/.ext/mcr/mca/LOC_BITS/512/4096)都硬编码在 Java 源码里,玩家无法改写 - 无
mcmod.info、无mixins.<modid>.json(usesMixins = false、coreModClass为空、accessTransformersFile为空)
本 mod 没有的内容(源码 grep 证据)
以下维度在本 mod 中没有任何内容,因此没有为它们建目录,也没有在条目里留下占位符。
| 维度 | 状态 | 依据 |
|---|---|---|
| 方块 / TileEntity | 无 | grep -rn "registerBlock|registerTileEntity|extends Block\b" src/ → 0 命中 |
| 物品 | 无 | grep -rn "registerItem" src/ → 0 命中;find src -name "Item*.java" 无结果 |
| 实体(含投掷物) | 无 | grep -rn "registerEntity|registerModEntity|extends Entity" src/ → 0 命中 |
| 多方块结构 | 无 | grep -rn "Multiblock|IMultiblock|Controller" src/ → 0 命中 |
| 游戏指令 | 无 | grep -rn "ICommand|CommandBase|addChatCommand|CommandEvent" src/ → 0 命中。serverStarting 转给 CommonProxy 的空方法 |
| 热键绑定 | 无 | grep -rn "KeyBinding|registerKeyBinding|ClientRegistry" src/ → 0 命中 |
| 附魔 | 无 | grep -rn "Enchantment" src/ → 0 命中 |
| Buff / Debuff | 无 | grep -rn "Potion|MobEffect" src/ → 0 命中 |
| 群系 | 无 | grep -rn "Biome|BiomeGen" src/ → 0 命中 |
| 结构生成 | 无 | grep -rn "MapGen|IWorldGenerator|StructureStart|MinableWorldgen" src/ → 0 命中。grep -rni "vein|oreminer|oredistribut|smallore|largeore|mining" src/ → 0 命中 |
| 成就 | 无 | grep -rn "Achievement" src/ → 0 命中 |
| Minecraft 维度 / 世界生成 | 无 | grep -rn "WorldProvider|registerDimension|DimensionType|DimensionManager" src/ → 0 命中;grep -rn "registerWorldGenerator|addMapGenEntry" src/ → 0 命中 |
FML 配置项(@Config / Configuration) |
无 | grep -rn "@Config|ForgeConfiguration|getConfiguration" src/ → 0 命中。唯一可调项是 SharedCache 里的 JVM system property cubicchunks.regionlib.maxRegionCacheSize |
| JSON / YAML 数据文件 | 无 | grep -rn "Gson|JsonObject|ObjectMapper|yaml|SnakeYAML" src/ → 0 命中;ls src/main/resources 不存在 |
| 创造模式标签 / GUI | 无 | 无 CreativeTabs、无 IGuiHandler、无 IGuiHandler 实现 |
| NEI / REI / JEI 集成 | 无 | grep -rn "nei/|rei/|jei/|SimpleServiceLocator" src/ → 0 命中。dependencies.gradle 里的 NotEnoughItems 是 runtimeOnlyNonPublishable 开发期依赖,不构成 API 集成 |
| 网络包 / 实体同步 | 无 | 无 SimpleNetworkWrapper、无 IMessage、无 FMLEmbeddedChannel |
| Mixin / Core Mod | 无 | gradle.properties:usesMixins = false、coreModClass =(空)、accessTransformersFile =(空);find src -path "*mixin*" 无结果 |
唯一的 FML 耦合点
整个 mod 与 Forge 的交集就是 RegionLib.java(15 行有效代码)和 CommonProxy.java(4 个空方法):
| 事件 | RegionLib 的处理 |
实际行为 |
|---|---|---|
FMLPreInitializationEvent |
proxy.preInit(event) |
空 |
FMLInitializationEvent |
proxy.init(event) |
空 |
FMLPostInitializationEvent |
proxy.postInit(event) |
空 |
FMLServerStartingEvent |
proxy.serverStarting(event) |
空(不注册任何指令) |
@SidedProxy(clientSide = "cubicchunks.regionlib.CommonProxy", serverSide = "cubicchunks.regionlib.CommonProxy") 两侧同一个类,没有 ClientProxy / CommonProxy 的分离。
综上:RegionLib 在游戏运行时注册 0 个游戏内容、读写 0 个配置文件、响应 0 条指令。它是一块被 RegionLib 依赖方(如 Cubic Chunks 系模组)在代码里调用的库。
附:源码文件清单(42 个)
| 包 | 文件 |
|---|---|
cubicchunks.regionlib |
RegionLib.java、CommonProxy.java、UnsupportedDataException.java、MultiUnsupportedDataException.java |
api |
package-info.java |
api.region |
IRegion.java、IRegionFactory.java、IRegionProvider.java、BatchReadResult.java |
api.region.key |
IKey.java、IKeyProvider.java、RegionKey.java |
api.region.header |
IHeaderDataEntry.java、IHeaderDataEntryProvider.java |
api.storage |
SaveSection.java |
impl |
EntryLocation2D.java、EntryLocation3D.java、MinecraftChunkLocation.java、SaveCubeColumns.java、package-info.java |
impl.header |
TimestampHeaderEntryProvider.java |
impl.save |
MinecraftSaveSection.java、SaveSection2D.java、SaveSection3D.java |
lib |
Region.java、ExtRegion.java、RegionSectorTracker.java、RegionEntryLocation.java、package-info.java |
lib.factory |
SimpleRegionFactory.java |
lib.header |
IKeyIdToSectorMap.java、IntPackedSectorMap.java、EntryLocationHeaderEntryProvider.java、IntHeaderEntry.java |
lib.provider |
SharedCache.java、SharedCachedRegionProvider.java |
util |
Utils.java、CheckedConsumer.java、CheckedFunction.java、CheckedBiConsumer.java、CorruptedDataException.java、SaveSectionException.java |
CheckedBiConsumer 在全仓库没有任何调用方(grep -rn "CheckedBiConsumer" src/ 只命中定义本身),BatchReadResult 之外 IKeyIdToSectorMap 也只在 lib 内部流转——这些是留给外部实现的 API 面。