勘探者日志(Prospector’s Log)

本 mod 唯一注册的游戏物品。它不是容器也不是工具,而是一张「数据收据」:右键写入把自己的勘探数据打包上传给服务器,右键读取别人的数据下载到本地。最大堆叠 1,无耐久,无附魔。

基本信息

属性 值
注册名 visualprospecting:visualprospecting.prospectorslog(HooksShared.java:101,getUnlocalizedName() 直接取自 ProspectorsLog.java:31)
内部类 com.sinthoras.visualprospecting.item.ProspectorsLog
本地化名 item.visualprospecting.prospectorslog.name = Prospector’s Log
物品组 GregTech 主物品栏(setCreativeTab(GregTechAPI.TAB_GREGTECH),ProspectorsLog.java:32)
最大堆叠 1(构造时直接 maxStackSize = 1,非 setMaxStackSize)
贴图 visualprospecting:prospectorslog
子类型 否
耐久度 无
合成配方 无

⚠️ 注册名含两个点号(visualprospecting.visualprospecting.prospectorslog),因为 setUnlocalizedName 传入的是 "visualprospecting.prospectorslog",而 Forge 会在其后拼 ".name" 查语言文件。写命令 / KubeJS 脚本时要注意这个双段结构。

两种状态

状态不靠 damage 值区分,而是靠 NBT。isFilledLog()(ProspectorsLog.java:101-105)判定 NBT 是否同时含 log_author 与 log_author_id 两个键:

状态 NBT tooltip
空白 无 NBT item.visualprospecting.prospectorslog.empty = “Use item to fill it.”
已填写 log_author(显示名)+ log_author_id(UUID 字符串) item.visualprospecting.prospectorslog.author = “Author: %s”

右键行为

onItemRightClick(ProspectorsLog.java:37-86)永不消耗物品,恒 return item。

空白日志 → 写入自己的数据

客户端 world.isRemote 分支只发一个 SnapshotUploadTask;真正的判定在服务端:

VP.randomGeneration.nextInt(1000) < 5   → 失败:发灰色斜体消息 + destroyCurrentEquippedItem()(物品消失)
否则                                    → 成功:发 "creation.begin" 消息

写入失败率 0.5%(5/1000)。失败时消息取 item.visualprospecting.prospectorslog.creation.fail<random>,其中 <random> 是那个随机数本身。

已填写日志 → 读取对方数据

先比对 NBT 里的 log_author_id 与当前玩家 UUID。只有不是自己写的日志才继续(读自己的日志无任何反应)。且判定上限取决于对方数据是否已在本地:

TransferCache.instance.isClientDataAvailable(authorUuid) ? 1000 : 5
  • 对方数据已在本地 → 5/1000 失败率,走 SnapshotDownloadTask;
  • 对方数据不在本地 → 必定失败(5/5),发 reading.fail<random> 消息并销毁物品。

成功时发 reading.begin,服务端 TaskManager.SERVER_INSTANCE 排入 SnapshotDownloadTask(authorUuid, player);完成后客户端发 reading.end = “I finished the Prospector’s Log of %s”。

已知缺陷

  • 失败消息键名带随机数,但语言文件只提供 fail0–fail4。en_US.lang 里 creation.fail0–fail4 与 reading.fail0–fail4 各 5 条(内容是 “Damn! I spilled coffee over it…” 之类的趣味文案),而代码把 nextInt(1000) 的返回值(0–999)直接拼进键名。所以 995/1000 的失败会显示原始键名字符串(形如 item.visualprospecting.prospectorslog.creation.fail713)而不是可读文案。同一缺陷存在于写入与读取两条路径。

  • 读取不存在的数据会销毁物品。当对方数据不在本地时 nextInt(5) 恒小于 5,必然走进失败分支,而失败分支调 player.destroyCurrentEquippedItem()。玩家在队伍数据未同步时右键队友的日志,日志直接消失且看不到任何有效原因(看到的是随机数键名)。

  • VP.randomGeneration 命名误导(VP.java:13)。这个 Random 实例在本 mod 里只被当作「判失败」的随机源,与「随机生成」无关;且它是全局共享且非线程安全的单一 Random,服务端多玩家同时右键会争用同一实例。

  • 物品无任何获取途径。grep -rn "addRecipe" src/main/java 无输出,本 mod 不注册任何配方。唯一来源是创造模式物品栏——GT 地震勘探器产出的是数据棒(Data Stick),不是本物品。

相关条目

  • 数据库与缓存 - 本物品上传/下载的数据存在哪里
  • 指令 - /vp team info 可直接查队伍数据,不一定需要本物品
  • 配置 - uploadBandwidth 超限会踢玩家,直接影响本物品的上传