[Bug]: onPistonTryPush 活塞推不动的方块数量越多时导致服务器tps越低
Describe the bug
- onPistonTryPush 活塞推不动的方块数量越多时导致服务器tps越低
- onPistonPush 在未推动任何方块时无法触发(这个修不修都行,主要时第一条)
To Reproduce
// 墓碑防推
mc.listen("onPistonTryPush", (pistonPos, block) => {
let obj = JSON.parse(playerTombstoneData.read());
if (block != null && block.type === "minecraft:chest" && block.hasContainer() && block.hasBlockEntity()) {
const x = block.pos.x;
const y = block.pos.y;
const z = block.pos.z;
const dimid = block.pos.dimid;
// 遍历对象中的每一个key
for (let key of Object.keys(obj)) {
// 获取当前key对应的tombstonePos数组
let tombstoneArray = obj[key];
// 遍历tombstonePos数组
for (let tombstone of tombstoneArray) {
// 获取当前tombstonePos的位置信息
let tombstonePos = tombstone.tombstonePos;
// 检查位置信息是否匹配
if (tombstonePos.X === x && tombstonePos.Y - 1 === y && tombstonePos.Z === z && tombstonePos.Dimid === dimid) {
// 如果找到匹配的位置,返回false阻止活塞推动
//return false; // 直接拦截会卡服:https://github.com/LiteLDev/LegacyScriptEngine/issues/313
//block.destroy(true);
}
}
}
}
});
在代码中,在满足条件时无论是仅 return false 还是 仅 block.destroy(true) 还是 什么都不做,都会导致卡服 已知 let obj = JSON.parse(playerTombstoneData.read()); 获取的是一份墓碑箱json数据,其内容量有点庞大(145kb,52份玩家墓碑箱数据)
Expected behavior
onPistonTryPush 拦截时不会卡服(不会降低服务器tps)
Screenshots
1
Platform
win10
BDS Version
1.21.93
LeviLamina Version
1.4.1
LegacyScriptEngine Version
0.13.1
Additional context
No response
这个事件实际上应该是方块被活塞推动(或拉动?)事件,包括间接推动,所以推到空气时不会触发
这个事件实际上应该是方块被活塞推动(或拉动?)事件,包括间接推动,所以推到空气时不会触发
发现新的问题:onPistonPush 这个事件 在拦截 return false 的时候,如果活塞被卡住(活塞推动的方块太多或被黑曜石等方块阻挡)并且推不动的方块的数量越多(从22个方块开始)卡顿较为明显,tps一开始降低到15,推不动的方块的数量非常多时,tps甚至降低到个位数甚至不到1(0.几)
我的墓碑箱插件就是加了墓碑箱防推所以使用到了这个事件,并且这个事件我记得在之前的LSE版本中是不会卡服的,但是在当前版本中确实存在卡服,经过了一整天的排查+四处询问C++大佬,已确定是该事件所导致
BDS版本:1.21.93 LL版本:1.4.1 LSE版本:0.13.1
最简单的卡服阵列:一键卡服机,拉动拉杆即可让服务器tps瞬间降低
onHopperSearchItem 监听事件似乎也会卡服,导致服务器tps降低,删除 onHopperSearchItem 监听事件修改代码后tps恢复正常
// 防止墓碑被漏斗/漏斗矿车吸取物品
mc.listen("onHopperSearchItem",
(
/** @type {FloatPos} 漏斗(漏斗矿车)所在的位置*/pos,
/** @type {bool} 是否为漏斗矿车*/isMinecart,
/** @type {Item} 检测到的物品对象*/_item
) => {
const upX = Math.floor(pos.x);
const upY = Math.floor(pos.y) + 1;
const upZ = Math.floor(pos.z);
const upPos = new IntPos(upX, upY, upZ, pos.dimid);
const upChestBlock = mc.getBlock(upPos);
const upChestIsTombstone = IsPosIsTombstone(upX, upY, upZ, pos.dimid);
if (upChestBlock && upChestIsTombstone) {
//logger.warn(`onHopperSearchItem : 已拦截 ${isMinecart ? "漏斗矿车" : "漏斗"} 吸取墓碑箱子内物品:${upPos}!`);
return false;
}
}
)
对监听事件做一个计数可以看出来,开一些生电机器的时候,"onPistonTryPush"的事件触发次数非常多,漏斗也有类似情况。