ExtendedAE_Plus/src/main/java/com/extendedae_plus/util/PatternProviderDataUtil.java
2025-10-26 17:29:36 +08:00

116 lines
5.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.helpers.patternprovider.PatternProviderLogic;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
/**
* 样板供应器数据工具类
* 用于获取样板供应器中的所有样板数据,包括输入输出物品的数量信息
*/
public class PatternProviderDataUtil {
/**
* 判断 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;
}
}
/**
* 查找 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 ignored) {}
}
return -1;
}
/**
* ExtendedAE风格安全获取样板供应器的Level对象
*/
private static Level getPatternProviderLevel(PatternProviderLogic patternProvider) {
if (patternProvider == null) return null;
try {
if (patternProvider instanceof PatternProviderLogicAccessor accessor) {
var host = accessor.eap$host();
if (host != null) {
BlockEntity be = host.getBlockEntity();
if (be != null) {
return be.getLevel();
}
}
}
} catch (Exception ignored) {
}
return null;
}
}