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 面。