容器与背包 · LSE¶
虚拟容器与背包虚容器;动态刷新只发给 UI 开着的玩家。
快速开始¶
最小可跑的例子:给玩家开一个 27 格的「任务列表」,在定时器里取点击。
const containerOpen = ll.import("HologramLib", "containerOpen");
const containerSetItem = ll.import("HologramLib", "containerSetItem");
const containerPollClicks = ll.import("HologramLib", "containerPollClicks");
const id = containerOpen("Steve", "§8任务列表", 3); // 27 格;rows = 6 → 54 格
containerSetItem(id, 0, "minecraft:diamond_sword", 1, 0, "§b试炼", "§7点击领取|§8第二行");
setInterval(() => { // 也可以挂在 mc.listen 的 tick 上
for (const line of containerPollClicks()) { // 每条 "player=X menuId=N slot=S closed=0|1"
const m = line.match(/player=(\S+) menuId=(-?\d+) slot=(-?\d+) closed=(\d)/);
if (!m) continue;
const [, player, menuId, slot, closed] = m;
if (closed === "1") continue; // 界面关闭(此时 slot = -1)
logger.info(`${player} 在菜单 ${menuId} 点了第 ${slot} 格`);
}
}, 200);
打开容器有固有延迟(默认 7 tick ≈ 350ms):客户端要先把这个箱子方块与它的方块实体应用上去, 打开界面的那条包才绑得住那个位置。延迟期间填格不会丢(逐格刷新走的是另一条包),但界面会稍晚出现。
虚拟容器(container*)¶
在客户端摆一个箱子方块 + 方块实体,再开箱子界面:服务端根本没有这个容器,条目只是「摆在那里」。
它的点击 = 一次物品拾取,任何输入设备都会发包(触屏也能点),所以它最适合当「点了有回调的列表界面」。
点击/关闭同样走轮询队列 containerPollClicks。
打开一个空容器界面¶
containerOpen(playerName, title, rows)
- 参数:
playerName:String
目标玩家名,必须在线title:String
界面标题(支持§颜色码);空串 = 用默认标题rows:Integer
容器行数,3= 小容器 27 格,6= 大容器 54 格- 返回值:菜单 id(之后用
containerSetItem逐格填);-1= 打开失败(玩家不在线、容器 id 用尽) - 返回值类型:
Integer -
示例:
就地刷新一个格子¶
containerSetItem(id, slot, type, count, damage, name, loreCsv)
- 参数:
id:Integer
菜单 idslot:Integer
格子下标(0 起),也就是点击回传里的slottype:String
物品 id,如"minecraft:diamond_sword";空串 = 清空该格count:Integer
数量,小于 1 按 1 处理damage:Integer
物品的附加数据值,一般填0name:String
自定义名(支持§颜色码),空串 = 无loreCsv:String
描述行,用\n或|分行,空串 = 没有描述行- 返回值:
true= 已刷新(发一条单格更新,客户端就地换掉那一格,无延迟、无闪烁);false= 菜单已不在、槽位越界或玩家离线 - 返回值类型:
Boolean -
示例:
就地换掉界面标题¶
containerSetTitle(id, title)
- 参数:
id:Integer
菜单 idtitle:String
新标题(支持§颜色码)- 返回值:
true= 已换(重发方块实体 + 界面包,不重摆方块、不重开界面);false= 菜单已不在或玩家离线 - 返回值类型:
Boolean -
示例:
打开或关闭可交互模式¶
containerSetInteractive(id, on)
- 参数:
id:Integer
菜单 idon:Booleantrue= 可交互(物品真的留在新格子,只接整条请求都落在本容器里的动作);false(默认)= 只回传点击,物品被服务端打回原位- 返回值:
true= 已切换;false= 菜单已不在 - 返回值类型:
Boolean -
示例:
取走并清空容器点击事件¶
containerPollClicks()
- 返回值:每条形如
player=X menuId=N slot=S closed=0|1;slot= 被点击的格子下标,closed=1表示界面被关闭(此时slot=-1);队列空时返回空数组 - 返回值类型:
Array<String> -
示例:
丢弃容器队列里的点击¶
containerClearClicks()
- 返回值:没有返回值
- 返回值类型:
Null -
示例:
查询容器菜单是否还在¶
containerIsOpen(id)
- 参数:
id:Integer
菜单 id- 返回值:
true= 菜单存在;false= 已关闭或不存在 - 返回值类型:
Boolean -
示例:
列出所有打开的容器菜单¶
containerGetIds()
- 返回值:菜单 id 数组;没有打开的菜单时是空数组
- 返回值类型:
Array<Integer> -
示例:
关掉一个容器界面¶
containerClose(id)
- 参数:
id:Integer
菜单 id- 返回值:
true= 已关闭(客户端那一格方块会被改回真实方块);false= 该 id 不存在 - 返回值类型:
Boolean -
示例:
关掉所有容器界面¶
containerCloseAll()
- 返回值:没有返回值
- 返回值类型:
Null -
示例:
背包虚容器(fakeInv*)¶
伪造内容覆盖玩家背包的 36 格:0..8 是快捷栏,9..35 是主背包。
点击走轮询队列 fakeInvPollClicks,只有「伪造且非空」的格子被点击才会有回传。
下发伪造背包并周期重发¶
fakeInvApply(playerName, itemsSpec, refreshIntervalTicks)
- 参数:
playerName:String
目标玩家名,必须在线itemsSpec:String
整份伪造内容。每条槽位|物品id|数量|名字|描述行~描述行,条目之间用;或换行分隔;槽位0..35(越界的条目会被跳过),数量留空按 1,描述行用~分隔refreshIntervalTicks:Integer
周期重发间隔(tick);0= 关掉周期重发,小于 5 的值按 5 执行(最快 5 tick)- 返回值:
true= 已下发;false= 玩家不在线 - 返回值类型:
Boolean -
示例:
改伪造背包里的一个格子¶
fakeInvSetSlot(playerName, slot, type, count, damage, name, loreCsv)
- 参数:
playerName:String
目标玩家名slot:Integer
槽位0..35(0..8快捷栏,9..35主背包)type:String
物品 id;空串 = 清空该格count:Integer
数量,小于 1 按 1 处理damage:Integer
物品的附加数据值,一般填0name:String
自定义名(支持§颜色码),空串 = 无loreCsv:String
描述行,用~分隔,空串 = 没有描述行- 返回值:
true= 已改(单格更新,无延迟);false= 该玩家还没apply过、玩家不在线或槽位越界 - 返回值类型:
Boolean -
示例:
立刻重发一遍伪造背包¶
fakeInvRefresh(playerName)
- 参数:
playerName:String
目标玩家名- 返回值:
true= 已重发(打开界面后发现被盖掉时用);false= 该玩家没有生效中的伪造,或玩家不在线 - 返回值类型:
Boolean -
示例:
查询玩家有没有伪造背包¶
fakeInvIsActive(playerName)
- 参数:
playerName:String
目标玩家名- 返回值:
true= 伪造生效中;false= 没有 - 返回值类型:
Boolean -
示例:
列出伪造生效中的玩家¶
fakeInvGetPlayers()
- 返回值:玩家名数组;一个都没有时是空数组
- 返回值类型:
Array<String> -
示例:
取走并清空伪造格点击¶
fakeInvPollClicks()
- 返回值:每条形如
player=X slot=S;slot= 被点击的伪造槽位;队列空时返回空数组 - 返回值类型:
Array<String> -
示例:
丢弃队列里全部点击¶
fakeInvClearClicks()
- 返回值:没有返回值
- 返回值类型:
Null -
示例:
撤销伪造并重发真实背包¶
fakeInvClear(playerName)
- 参数:
playerName:String
目标玩家名- 返回值:
true= 已撤销;false= 该玩家本来就没有伪造 - 返回值类型:
Boolean -
示例:
撤销所有玩家的伪造¶
fakeInvClearAll()
- 返回值:没有返回值
- 返回值类型:
Null -
示例: