优化
This commit is contained in:
parent
8fec6fff87
commit
146cce9de1
|
|
@ -1,5 +1,6 @@
|
|||
package com.extendedae_plus.mixin.ae2.accessor;
|
||||
|
||||
import appeng.api.networking.IManagedGridNode;
|
||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -9,4 +10,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
|
|||
public interface PatternProviderLogicAccessor {
|
||||
@Accessor("host")
|
||||
PatternProviderLogicHost eap$host();
|
||||
|
||||
@Accessor("mainNode")
|
||||
IManagedGridNode eap$mainNode();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,31 +85,8 @@ public class CraftingMonitorOpenProviderC2SPacket {
|
|||
var pbe = host.getBlockEntity();
|
||||
if (pbe == null) continue;
|
||||
|
||||
// 跳过未连接到网格或不活跃的 provider(例如缺少频道/通道)
|
||||
try {
|
||||
var providerGrid = ppl.getGrid();
|
||||
if (providerGrid == null || !providerGrid.equals(grid)) {
|
||||
continue;
|
||||
}
|
||||
// 如果 provider 自身对外提供的通道/频道信息不可用或不活跃,跳过
|
||||
try {
|
||||
// 尝试通过 provider 的主节点判断是否有 channel
|
||||
var mainNodeField = ppl.getClass().getDeclaredField("mainNode");
|
||||
mainNodeField.setAccessible(true);
|
||||
var mainNode = mainNodeField.get(ppl);
|
||||
if (mainNode == null) continue;
|
||||
var getChannelsMethod = mainNode.getClass().getMethod("getChannels");
|
||||
Object channels = null;
|
||||
channels = getChannelsMethod.invoke(mainNode);
|
||||
if (channels instanceof java.util.Collection) {
|
||||
if (((java.util.Collection<?>) channels).isEmpty()) continue;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 无法判断 channel 时继续:不因反射失败而阻止正常 provider
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
// 跳过未连接到网格或不活跃的 provider(使用 util 判断并传入当前 grid)
|
||||
if (!PatternProviderDataUtil.isProviderAvailable(ppl, grid)) continue;
|
||||
|
||||
// 直接打开供应器自身的 UI(调用 Host 默认方法)
|
||||
try {
|
||||
|
|
@ -121,7 +98,7 @@ public class CraftingMonitorOpenProviderC2SPacket {
|
|||
}
|
||||
|
||||
// 先在该 provider 中定位 pattern 的槽位索引,以便计算页码(尽量早退出,按槽位逐个解码)
|
||||
int foundSlot = findSlotIndexInProvider(ppl, pattern);
|
||||
int foundSlot = PatternProviderDataUtil.findSlotForPattern(ppl, pattern.getDefinition());
|
||||
if (foundSlot >= 0) {
|
||||
int pageId = foundSlot / 36;
|
||||
if (pageId > 0) {
|
||||
|
|
@ -145,20 +122,4 @@ public class CraftingMonitorOpenProviderC2SPacket {
|
|||
});
|
||||
context.setPacketHandled(true);
|
||||
}
|
||||
|
||||
private static int findSlotIndexInProvider(PatternProviderLogic ppl, IPatternDetails pattern) {
|
||||
try {
|
||||
// 通过逐槽位解码并在找到匹配定义时立即返回索引,避免分配大量对象
|
||||
var list = PatternProviderDataUtil.getAllPatternData(ppl);
|
||||
for (var pd : list) {
|
||||
if (pd != null && pd.getPatternDetails() != null && pd.getPatternDetails().getDefinition().equals(pattern.getDefinition())) {
|
||||
return pd.getSlotIndex();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ package com.extendedae_plus.util;
|
|||
import appeng.api.crafting.IPatternDetails;
|
||||
import appeng.api.crafting.PatternDetailsHelper;
|
||||
import appeng.api.inventories.InternalInventory;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.stacks.AEKey;
|
||||
import appeng.api.stacks.GenericStack;
|
||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -242,12 +243,15 @@ public class PatternProviderDataUtil {
|
|||
// 遍历所有样板槽位
|
||||
for (int i = 0; i < patternInventory.size(); i++) {
|
||||
ItemStack patternStack = patternInventory.getStackInSlot(i);
|
||||
if (!patternStack.isEmpty()) {
|
||||
if (patternStack.isEmpty()) continue;
|
||||
try {
|
||||
// 解码样板
|
||||
IPatternDetails patternDetails = PatternDetailsHelper.decodePattern(patternStack, level);
|
||||
if (patternDetails != null) {
|
||||
patternDataList.add(new PatternData(patternDetails, patternStack, i));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) LogUtils.getLogger().debug("Pattern decode failed at slot {}: {}", i, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,6 +401,59 @@ public class PatternProviderDataUtil {
|
|||
return patternProvider.getGrid() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 provider 是否可用并属于指定网格(在线且有频道/处于活跃状态)
|
||||
*/
|
||||
public static boolean isProviderAvailable(PatternProviderLogic provider, IGrid expectedGrid) {
|
||||
if (provider == null || expectedGrid == null) return false;
|
||||
try {
|
||||
var grid = provider.getGrid();
|
||||
if (grid == null || !grid.equals(expectedGrid)) return false;
|
||||
|
||||
// 使用 accessor 获取 mainNode,再调用 isActive
|
||||
if (provider instanceof PatternProviderLogicAccessor accessor) {
|
||||
var mainNode = accessor.eap$mainNode();
|
||||
if (mainNode == null) return false;
|
||||
try {
|
||||
var isActiveMethod = mainNode.getClass().getMethod("isActive");
|
||||
Object active = isActiveMethod.invoke(mainNode);
|
||||
if (active instanceof Boolean && !((Boolean) active)) return false;
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
// 没有 isActive 方法时,退回到检查 channels
|
||||
try {
|
||||
var getChannels = mainNode.getClass().getMethod("getChannels");
|
||||
Object channels = getChannels.invoke(mainNode);
|
||||
if (channels instanceof java.util.Collection) {
|
||||
if (((java.util.Collection<?>) channels).isEmpty()) return false;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 无法判断 channels 时,认为不可用
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有 accessor 的情况,尽量通过反射判断 mainNode.channels
|
||||
try {
|
||||
var mainNodeField = provider.getClass().getDeclaredField("mainNode");
|
||||
mainNodeField.setAccessible(true);
|
||||
var mainNode = mainNodeField.get(provider);
|
||||
if (mainNode == null) return false;
|
||||
var getChannelsMethod = mainNode.getClass().getMethod("getChannels");
|
||||
Object channels = getChannelsMethod.invoke(mainNode);
|
||||
if (channels instanceof java.util.Collection) {
|
||||
return !((java.util.Collection<?>) channels).isEmpty();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查样板供应器是否处于活跃状态
|
||||
*
|
||||
|
|
@ -411,18 +468,21 @@ public class PatternProviderDataUtil {
|
|||
if (grid == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查网格节点是否活跃
|
||||
// 检查网格节点是否活跃(使用 accessor 代替反射)
|
||||
try {
|
||||
// 使用反射安全地访问mainNode字段
|
||||
var mainNodeField = patternProvider.getClass().getDeclaredField("mainNode");
|
||||
mainNodeField.setAccessible(true);
|
||||
var mainNode = mainNodeField.get(patternProvider);
|
||||
if (mainNode != null) {
|
||||
var isActiveMethod = mainNode.getClass().getMethod("isActive");
|
||||
return (Boolean) isActiveMethod.invoke(mainNode);
|
||||
if (patternProvider instanceof PatternProviderLogicAccessor accessor) {
|
||||
var mainNode = accessor.eap$mainNode();
|
||||
if (mainNode != null) {
|
||||
try {
|
||||
var isActiveMethod = mainNode.getClass().getMethod("isActive");
|
||||
return (Boolean) isActiveMethod.invoke(mainNode);
|
||||
} catch (Exception e) {
|
||||
// 无法调用 isActive 时,认为活跃
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 如果反射失败,假设是活跃的
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -490,6 +550,34 @@ public class PatternProviderDataUtil {
|
|||
return scalePatternAmountsExtendedAEStyle(patternProvider, multiplier, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找 provider 中匹配给定定义的样板槽位(轻量、按需解码并早退出)
|
||||
* @param patternProvider 要搜索的 provider
|
||||
* @param targetDefinition pattern.getDefinition() 返回的对象(用于 equals 比较)
|
||||
* @return 找到的槽位索引,未找到返回 -1
|
||||
*/
|
||||
public static int findSlotForPattern(PatternProviderLogic patternProvider, Object targetDefinition) {
|
||||
if (patternProvider == null || targetDefinition == null) return -1;
|
||||
InternalInventory inv = patternProvider.getPatternInv();
|
||||
if (inv == null) return -1;
|
||||
Level level = getPatternProviderLevel(patternProvider);
|
||||
if (level == null) return -1;
|
||||
|
||||
for (int i = 0; i < inv.size(); i++) {
|
||||
ItemStack s = inv.getStackInSlot(i);
|
||||
if (s.isEmpty()) continue;
|
||||
try {
|
||||
IPatternDetails d = PatternDetailsHelper.decodePattern(s, level);
|
||||
if (d != null && d.getDefinition().equals(targetDefinition)) {
|
||||
return i;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) LogUtils.getLogger().debug("findSlotForPattern decode failed at {}: {}", i, e.toString());
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格的样板复制倍增
|
||||
* 支持更精确的样板处理和错误恢复
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user