数据库与缓存

VisualProspecting 的核心不是「可视化的东西」,而是一套存在内存里的矿脉 / 地下流体数据库,以及把数据在玩家之间搬运的传输层。全部内容都在 database/ 与 task/ 包下,共 11 + 5 个类。

数据不落地在方块里

本 mod 不注册任何方块或 TileEntity。 勘探数据存在 ServerCache / ClientCache 的 Java 数据结构里,靠 SnapshotUploadTask / SnapshotDownloadTask 在玩家登录 / 右键日志时传输。

数据库层(database/)

类 作用
ServerCache 服务端权威数据库,持有全服所有维度的矿脉与流体记录
ClientCache 客户端本地副本,显示用
TransferCache 记录「哪些玩家的数据我已经有了」,决定勘探者日志读取时走 5/1000 还是 5/5 失败率
WorldCache 单个世界的记录集合
DimensionCache 单个维度的记录集合
WorldIdHandler 分配 / 解析 worldId(NBT 键 wId)
DimensionNameResolver 维度 id ↔ 可读名
LegacyDimensionCacheLoader 兼容旧版存档格式
OreVeinPosition 一条矿脉的坐标与元数据
UndergroundFluidPosition 一个地下流体样本的坐标、产量区间与流体类型
VeinSource 记录矿脉的来源(供 commit 268e673 的「不可信 oregen 模式」校验用)

缓存构建(database/cachebuilder/)

类 作用
WorldAnalysis 全世界扫描任务的顶层
DimensionAnalysis 单维度扫描
ChunkAnalysis 单区块分析
DetailedChunkAnalysis 带细节的区块分析
PartiallyLoadedChunk 区块未完全加载时的中间态
RegionReader 直接读 r.X.Z.mca region 文件,绕过 Minecraft 区块系统
AnalysisProgressTracker 进度追踪,配合 cacheGenerationLogUpdateMinTime 刷日志

⚠️ 缓存重建直接读存档文件。RegionReader 打开的 region 文件总大小受 maxRegionRowFileMBForInMemoryScan(默认 10,000 MB)限制,配置项描述明确写着「出现 OutOfMemoryException 就调低」——这是全 mod 唯一的内存爆炸风险点。

任务层(task/)

类 作用
ITask 任务接口
TaskManager 客户端 / 服务端各一个实例(CLIENT_INSTANCE / SERVER_INSTANCE),串行执行任务队列
SnapshotUploadTask 把本地勘探数据打包上传
SnapshotDownloadTask 从服务器下载指定玩家的数据

网络消息(network/)

7 个消息类,其中 ProspectingRequest / ProspectionSharing / RequestTeamUploadMessage 走 GTNHLib 的队伍通道,VeinDepletionMessage / TeamCatchupNotification / WorldIdNotification / ProspectingNotification 为主通道。

上传分包上限 30,000 B/封包(VP.uploadSizePerPacketInBytes),源码注释警告「Larger than 32kB will kick the player!」。实际每秒封包数由 uploadBandwidthBytes / 30,000 算出,默认 2,000,000 B/s ≈ 66 封包/s。

矿脉类型(database/veintypes/)

VeinType 与 VeinTypeCaching 定义 GT 矿脉的分类与缓存键。NBT 哨兵值 ore.mix.none(Tags.ORE_MIX_NONE_NAME)表示「无 ore 混合」。

已知缺陷

  • 无持久化格式版本号。LegacyDimensionCacheLoader 说明存在旧格式,但没有版本迁移的版本字段;跨 GTNH 大版本升级时数据可能失效。
  • TransferCache 是读取路径的硬依赖。它决定勘探者日志的失败率,一旦缓存状态不同步(客户端有 / 服务端无),玩家会看到「读取必定失败 + 物品被销毁」。

相关条目