EnderStorage API
提供给其他 mod 集成的核心入口:
EnderStorageManager、EnderStoragePlugin、EnderStorageDyeTool、AbstractEnderStorage与频率↔颜色换算工具。
基本信息
| 组件 | 类 | 路径 |
|---|---|---|
| Manager | EnderStorageManager |
codechicken.enderstorage.api.EnderStorageManager |
| 抽象存储 | AbstractEnderStorage |
codechicken.enderstorage.api.AbstractEnderStorage |
| Plugin 接口 | EnderStoragePlugin |
codechicken.enderstorage.api.EnderStoragePlugin |
| 染料工具 | EnderStorageDyeTool |
codechicken.enderstorage.api.EnderStorageDyeTool |
| 存储事件 | EnderStorageStoredEvent |
codechicken.enderstorage.event.EnderStorageStoredEvent |
EnderStorageManager(核心管理器)
- 双实例:服务端
serverManager与客户端clientManager,通过instance(boolean client)区分。 - 内部维护三张表:
storageMap: Map<String, AbstractEnderStorage>(key = freq + "|" + owner + "|" + type)storageList: Map<String, List<AbstractEnderStorage>>(按 type 分类的列表,用于客户端广播)dirtyStorage: LinkedList<AbstractEnderStorage>(待持久化对象)
- 通过
EnderStorageSaveHandler在WorldEvent.Load/Save上自动加载/保存;保存使用DimensionManager.getCurrentSaveRootDirectory()/EnderStorage/data{1,2}.dat+lock.dat三个文件的双缓冲模式(lock.dat记录上一次写入的文件编号)。 getStorage(owner, freq, type)懒加载:owner == null强制写为"global";首次访问创建EnderStoragePlugin.createEnderStorage实例,并尝试从saveTag中loadFromTag。setStorage(owner, freq, type, nbt)用 NBT 覆盖已有实例或创建新实例。cleanStorage(owner, type)把 owner 在指定 type 下的所有存储清空(item 清空 ItemStack 数组;liquid 把tank.Amount设为 0)。requestSave(storage)把脏存储加入dirtyStorage,下一次save(false)触发时由EnderStorageSaveHandler.onWorldSave写入磁盘。
频率↔颜色换算
// 颜色 → 频率(freq = (c1<<8) + (c2<<4) + c3)
public static int getFreqFromColours(int colour1, int colour2, int colour3)
public static int getFreqFromColours(int[] colours)
// 频率 → 颜色(0 = 高 4-bit / 1 = 中 4-bit / 2 = 低 4-bit)
public static int getColourFromFreq(int freq, int colour)
public static int[] getColoursFromFreq(int freq)
colour1/2/3 与 colour=0/1/2 顺序一致(高位先)。染色 blockEnderStorage.onBlockActivated 中读取并写入 freq 的对应分量。
插件注册
public static void registerPlugin(EnderStoragePlugin plugin)
public static void loadConfig(ConfigFile config2)
init 时机依次:registerPlugin(new EnderItemStoragePlugin()) → registerPlugin(new EnderLiquidStoragePlugin())。新插件必须实现 EnderStoragePlugin 接口才能挂入。
EnderStoragePlugin 接口
public AbstractEnderStorage createEnderStorage(EnderStorageManager manager, String owner, int freq);
public String identifer(); // "item" / "liquid"
public void sendClientInfo(EntityPlayer player, List<AbstractEnderStorage> list);
public void loadConfig(ConfigTag tag);
identifer()返回字符串用于storageMap/storageList的 key。sendClientInfo在玩家登录/切换维度时调用;item 插件实现为"对所有打开中的 EnderItemStorage 广播openCount",liquid 插件为空实现(液体走TankSynchroniser)。loadConfig读取ConfigFile中<identifier>子分组。
AbstractEnderStorage(抽象存储)
public final EnderStorageManager manager;
public final int freq;
public final String owner;
public void setDirty(); // 标记 + manager.requestSave + changeCount++
public void setClean();
public int getChangeCount(); // 客户端每 tick 用 changeCount 判断是否需要同步
public abstract String type();
public abstract NBTTagCompound saveToTag();
public abstract void loadFromTag(NBTTagCompound tag);
- 脏标记 + 变更计数:服务端的
setDirty会调用manager.requestSave;客户端setDirty直接 return。 changeCount在客户端用来判断"是否要把 TileEntity 标记为需要 update(worldObj.func_147453_f)",由TileFrequencyOwner.updateEntity每 tick 轮询。
EnderStorageDyeTool(染料工具接口)
public interface EnderStorageDyeTool {
int getDye(ItemStack itemStack); // 返回 0–15 的染料颜色;-1 表示此物品不提供染料
default void expendToolUse(ItemStack itemStack) {} // 默认无操作;mod 可在此消耗耐久/EU/etc
}
集成流程(BlockEnderStorage.onBlockActivated subHit 1–3):
EnderStorageRecipe.getDyeType(item)先尝试Items.dye、dyeBlack/…/od 列表;- 然后尝试
item instanceof EnderStorageDyeTool,调getDye(item); - 命中后修改 freq 对应分量;创造模式不消耗,否则调用
((EnderStorageDyeTool) item.getItem()).expendToolUse(item)。
接口 Javadoc 明确说明:仅对已放置的 Ender Chest / Tank 有效——合成配方中的"染色"路径不走
EnderStorageDyeTool。
EnderStorageStoredEvent(事件)
public static final int TYPE_ITEM = 1;
public static final int TYPE_LIQUID = 2;
public final boolean global; // true=global, false=player-owned
public final int type; // TYPE_ITEM / TYPE_LIQUID
由 EnderStorageCPH.handlePacket 在收到服务器 type=7 包后通过 MinecraftForge.EVENT_BUS.post(new EnderStorageStoredEvent(global, type)) 触发,第三方 mod 可监听以在"玩家完整库存清单下发"后做缓存/UI 更新。
网络包(channel = "ES")
| type | 方向 | 含义 |
|---|---|---|
| 1 | S→C | TileEntity description(handleTilePacket) |
| 1 | C→S | TankSynchroniser.handleVisiblityPacket |
| 2 | S→C | 打开 GUI(EnderItemStorage.openClientGui) |
| 2 | C→S | 请求完整库存清单(sendStorageStored) |
| 3 | S→C | 箱子开/关状态(setClientOpen) |
| 4 | S→C | 液体同步(TankSynchroniser.syncClient) |
| 5/6 | S↔C | Ender Tank 液体/压力状态(TileEnderTank.sync) |
| 7 | S→C | 完整 (freqs, owner, type) 清单(updateStorage + 触发 EnderStorageStoredEvent) |
第三方 mod 集成示例
// 自定义 EnderStorage 插件(不通过 EnderStorageManager.registerPlugin 在 init 时机注册,
// 可在 mod 自己的 FMLInitializationEvent 中注册):
public class MyStoragePlugin implements EnderStoragePlugin {
@Override public AbstractEnderStorage createEnderStorage(EnderStorageManager m, String o, int f) {
return new MyEnderStorage(m, o, f);
}
@Override public String identifer() { return "mytype"; }
@Override public void sendClientInfo(EntityPlayer p, List<AbstractEnderStorage> list) {}
@Override public void loadConfig(ConfigTag tag) {}
}
EnderStorageManager.registerPlugin(new MyStoragePlugin());
// 自定义染料工具:
public class MyDyeTool extends Item implements EnderStorageDyeTool {
@Override public int getDye(ItemStack s) { return s.getItemDamage() & 0xF; }
@Override public void expendToolUse(ItemStack s) { s.setItemDamage(s.getItemDamage() + 1); }
}
相关条目
- Ender Chest - 调用 API 完成
(freq, owner)切换 - Ender Tank - 调用
TankSynchroniser做液体同步 - 配置项 -
loadConfig的来源 - /enderstorage 命令 - 触发
sendStorageStored - EnderStorageRecipe -
getDyeColour反查表