修复interface初始化问题
This commit is contained in:
parent
7f704e2a9c
commit
b2b2740864
|
|
@ -19,4 +19,32 @@ public interface InterfaceWirelessLinkBridge {
|
||||||
default void eap$setClientWirelessState(boolean connected) {
|
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() {
|
||||||
|
// 默认实现为空
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import appeng.helpers.InterfaceLogicHost;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.items.ChannelCardItem;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import com.extendedae_plus.wireless.IWirelessEndpoint;
|
import com.extendedae_plus.wireless.IWirelessEndpoint;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
|
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
|
||||||
|
|
@ -27,18 +28,62 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
|
|
||||||
@Shadow(remap = false) protected InterfaceLogicHost host;
|
@Shadow(remap = false) protected InterfaceLogicHost host;
|
||||||
|
|
||||||
|
@Shadow(remap = false) protected appeng.api.networking.IManagedGridNode mainNode;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private WirelessSlaveLink eap$link;
|
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)
|
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
|
||||||
private void eap$onUpgradesChangedTail(CallbackInfo ci) {
|
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)
|
@Inject(method = "readFromNBT", at = @At("TAIL"), remap = false)
|
||||||
private void eap$afterReadNBT(net.minecraft.nbt.CompoundTag tag, CallbackInfo ci) {
|
private void eap$afterReadNBT(net.minecraft.nbt.CompoundTag tag, CallbackInfo ci) {
|
||||||
// 重载后根据卡状态恢复连接
|
// 从 NBT加载时重置标志
|
||||||
handleChannelCardChange();
|
eap$lastChannel = -1;
|
||||||
|
eap$hasInitialized = false;
|
||||||
|
// 直接尝试初始化
|
||||||
|
eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
|
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
|
||||||
|
|
@ -49,20 +94,95 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void handleChannelCardChange() {
|
public void eap$initializeChannelLink() {
|
||||||
var inv = getUpgrades();
|
ExtendedAELogger.LOGGER.debug("[服务端] Interface eap$initializeChannelLink 被调用");
|
||||||
long channel = 0L;
|
|
||||||
for (ItemStack stack : inv) {
|
// 防止在客户端执行
|
||||||
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
||||||
channel = ChannelCardItem.getChannel(stack);
|
ExtendedAELogger.LOGGER.debug("[服务端] Interface 在客户端,跳过初始化");
|
||||||
break;
|
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
|
@Override
|
||||||
|
|
@ -71,4 +191,69 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
eap$link.updateStatus();
|
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方法已在上面实现
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.extendedae_plus.mixin.ae2.helpers;
|
||||||
|
|
||||||
import appeng.helpers.InterfaceLogic;
|
import appeng.helpers.InterfaceLogic;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
||||||
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
@ -20,6 +21,20 @@ public abstract class InterfaceLogicTickerMixin {
|
||||||
@Final
|
@Final
|
||||||
private InterfaceLogic this$0;
|
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)
|
@Inject(method = "tickingRequest", at = @At("TAIL"), remap = false)
|
||||||
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
|
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
|
||||||
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$initializeChannelLink() {
|
public void eap$initializeChannelLink() {
|
||||||
// 防止重复调用
|
// 防止重复调用
|
||||||
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$initializeChannelLink() {
|
public void eap$initializeChannelLink() {
|
||||||
// 防止重复调用
|
// 防止重复调用
|
||||||
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user