修复interface初始化问题

This commit is contained in:
GaLicn 2025-09-23 12:17:13 +08:00
parent 7f704e2a9c
commit b2b2740864
5 changed files with 245 additions and 17 deletions

View File

@ -19,4 +19,32 @@ public interface InterfaceWirelessLinkBridge {
default void eap$setClientWirelessState(boolean connected) {
// 默认实现为空
}
/**
* 检查是否已经进行过tick初始化
*/
default boolean eap$hasTickInitialized() {
return true; // 默认认为已初始化
}
/**
* 设置tick初始化状态
*/
default void eap$setTickInitialized(boolean initialized) {
// 默认实现为空
}
/**
* 执行频道链接初始化
*/
default void eap$initializeChannelLink() {
// 默认实现为空
}
/**
* 检查并处理延迟初始化
*/
default void eap$handleDelayedInit() {
// 默认实现为空
}
}

View File

@ -6,6 +6,7 @@ import appeng.helpers.InterfaceLogicHost;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.wireless.IWirelessEndpoint;
import com.extendedae_plus.wireless.WirelessSlaveLink;
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
@ -26,19 +27,63 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
@Shadow(remap = false) public abstract appeng.api.networking.IGridNode getActionableNode();
@Shadow(remap = false) protected InterfaceLogicHost host;
@Shadow(remap = false) protected appeng.api.networking.IManagedGridNode mainNode;
@Unique
private WirelessSlaveLink eap$link;
@Unique
private long eap$lastChannel = -1;
@Unique
private boolean eap$clientConnected = false;
@Unique
private boolean eap$hasInitialized = false;
@Unique
private int eap$delayedInitTicks = 0;
static {
ExtendedAELogger.LOGGER.info("[服务端] InterfaceLogicChannelCardMixin 已加载");
}
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
private void eap$onUpgradesChangedTail(CallbackInfo ci) {
handleChannelCardChange();
// 升级变更时重置标志并尝试初始化
eap$lastChannel = -1;
eap$hasInitialized = false;
eap$initializeChannelLink();
}
@Inject(method = "gridChanged", at = @At("TAIL"), remap = false)
private void eap$afterGridChanged(CallbackInfo ci) {
// 网格状态变化时重置标志并设置延迟初始化
ExtendedAELogger.LOGGER.debug("[服务端] Interface gridChanged 触发,设置延迟初始化");
eap$lastChannel = -1;
eap$hasInitialized = false;
eap$delayedInitTicks = 10; // 适当增加延迟tick等待网格完成引导
// 尝试唤醒设备确保后续还能继续tick
if (mainNode != null) {
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
// 防御性日志避免因这里的异常影响主流程
ExtendedAELogger.LOGGER.debug("[服务端] Interface 唤醒设备失败: {}", t.toString());
}
});
}
}
@Inject(method = "readFromNBT", at = @At("TAIL"), remap = false)
private void eap$afterReadNBT(net.minecraft.nbt.CompoundTag tag, CallbackInfo ci) {
// 重载后根据卡状态恢复连接
handleChannelCardChange();
// NBT加载时重置标志
eap$lastChannel = -1;
eap$hasInitialized = false;
// 直接尝试初始化
eap$initializeChannelLink();
}
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
@ -49,20 +94,95 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
}
@Unique
private void handleChannelCardChange() {
var inv = getUpgrades();
long channel = 0L;
for (ItemStack stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
break;
public void eap$initializeChannelLink() {
ExtendedAELogger.LOGGER.debug("[服务端] Interface eap$initializeChannelLink 被调用");
// 防止在客户端执行
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 在客户端,跳过初始化");
return;
}
// 检查是否已经初始化过
if (eap$hasInitialized) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 已经初始化过,跳过");
return;
}
// 优先等待网格完成引导比仅检查 isActive 更可靠
if (!mainNode.hasGridBooted()) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 网格未完成引导(boot),等待后再初始化: ready={}, active={}, online={}",
mainNode.isReady(), mainNode.isActive(), mainNode.isOnline());
return;
}
try {
var inv = getUpgrades();
long channel = 0L;
boolean found = false;
for (ItemStack stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
}
ExtendedAELogger.LOGGER.debug("[服务端] Interface 初始化频道链接: found={}, channel={}", found, channel);
if (!found) {
// 无频道卡则断开
if (eap$link != null) {
eap$link.setFrequency(0L);
eap$link.updateStatus();
ExtendedAELogger.LOGGER.debug("[服务端] Interface 断开频道链接");
}
eap$hasInitialized = true; // 无频道卡也算初始化完成
return;
}
if (eap$link == null) {
// 使用mainNode而不是getActionableNode因为后者可能返回null
IWirelessEndpoint endpoint = new InterfaceNodeEndpointImpl(host, () -> mainNode.getNode());
eap$link = new WirelessSlaveLink(endpoint);
ExtendedAELogger.LOGGER.debug("[服务端] Interface 创建新的无线链接");
}
eap$link.setFrequency(channel);
eap$link.updateStatus();
// 调试信息检查网格节点状态
var gridNode = mainNode.getNode();
var isActive = mainNode.isActive();
ExtendedAELogger.LOGGER.debug("[服务端] Interface 设置频道: {}, 连接状态: {}, 网格节点: {}, 激活: {}, 在线: {}",
channel, eap$link.isConnected(),
gridNode != null ? "exists" : "null",
isActive,
gridNode != null ? gridNode.isOnline() : "N/A");
if (eap$link.isConnected()) {
eap$hasInitialized = true; // 设置初始化完成标志
ExtendedAELogger.LOGGER.debug("[服务端] Interface 无线链接建立成功");
} else {
ExtendedAELogger.LOGGER.warn("[服务端] Interface 无线链接建立失败,将继续重试");
// 不标记为完成允许后续tick重试
eap$hasInitialized = false;
// 设置一个短延迟窗口避免每tick刷屏
eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5);
try {
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 初始化失败后唤醒设备失败: {}", t.toString());
}
});
} catch (Throwable ignored) {
}
}
} catch (Exception e) {
ExtendedAELogger.LOGGER.error("[服务端] Interface 初始化频道链接失败", e);
}
if (eap$link == null) {
IWirelessEndpoint endpoint = new InterfaceNodeEndpointImpl(host, this::getActionableNode);
eap$link = new WirelessSlaveLink(endpoint);
}
eap$link.setFrequency(channel);
}
@Override
@ -71,4 +191,69 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
eap$link.updateStatus();
}
}
@Override
public boolean eap$isWirelessConnected() {
// InterfaceLogic没有isClientSide方法需要通过host判断
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
return eap$clientConnected;
} else {
return eap$link != null && eap$link.isConnected();
}
}
@Override
public void eap$setClientWirelessState(boolean connected) {
eap$clientConnected = connected;
}
@Override
public boolean eap$hasTickInitialized() {
return eap$hasInitialized;
}
@Override
public void eap$setTickInitialized(boolean initialized) {
eap$hasInitialized = initialized;
}
@Override
public void eap$handleDelayedInit() {
// 仅在服务端执行延迟初始化避免在渲染线程/客户端触发任何初始化路径
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
return;
}
// 若尚未初始化则持续尝试直到网格完成引导
if (!eap$hasInitialized) {
if (!mainNode.hasGridBooted()) {
// 仍在引导消耗计时器
if (eap$delayedInitTicks > 0) {
eap$delayedInitTicks--;
}
if (eap$delayedInitTicks == 0) {
// 重新设定一个短延迟窗口并唤醒设备以保证后续还能继续 tick
eap$delayedInitTicks = 5;
try {
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 延迟等待期间唤醒设备失败: {}", t.toString());
}
});
} catch (Throwable ignored) {
}
ExtendedAELogger.LOGGER.debug("[服务端] Interface 网格仍在引导,继续等待: ready={}, active={}, online={}",
mainNode.isReady(), mainNode.isActive(), mainNode.isOnline());
}
} else {
// 网格已引导完成执行初始化
ExtendedAELogger.LOGGER.debug("[服务端] Interface 延迟初始化触发(网格已完成引导)");
eap$initializeChannelLink();
}
}
}
// eap$initializeChannelLink方法已在上面实现
}

View File

@ -2,6 +2,7 @@ package com.extendedae_plus.mixin.ae2.helpers;
import appeng.helpers.InterfaceLogic;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.util.ExtendedAELogger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -20,6 +21,20 @@ public abstract class InterfaceLogicTickerMixin {
@Final
private InterfaceLogic this$0;
@Inject(method = "tickingRequest", at = @At("HEAD"), remap = false)
private void eap$tickHead(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
// 仅在服务端处理延迟初始化避免客户端干扰
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
return;
}
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
// 处理延迟初始化
bridge.eap$handleDelayedInit();
}
}
@Inject(method = "tickingRequest", at = @At("TAIL"), remap = false)
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {

View File

@ -64,7 +64,7 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
}
@Unique
private void eap$initializeChannelLink() {
public void eap$initializeChannelLink() {
// 防止重复调用
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return;

View File

@ -61,7 +61,7 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
}
@Unique
private void eap$initializeChannelLink() {
public void eap$initializeChannelLink() {
// 防止重复调用
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return;