修复样板供应器初始化问题

This commit is contained in:
GaLicn 2025-09-23 12:48:50 +08:00
parent b2b2740864
commit 773d1bb263
3 changed files with 186 additions and 69 deletions

View File

@ -6,8 +6,6 @@ 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;
import net.minecraft.server.level.ServerLevel;
@ -46,7 +44,7 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
private int eap$delayedInitTicks = 0;
static {
ExtendedAELogger.LOGGER.info("[服务端] InterfaceLogicChannelCardMixin 已加载");
// InterfaceLogicChannelCardMixin 已加载
}
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
@ -60,7 +58,6 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
@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等待网格完成引导
@ -69,9 +66,7 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
// 防御性日志避免因这里的异常影响主流程
ExtendedAELogger.LOGGER.debug("[服务端] Interface 唤醒设备失败: {}", t.toString());
} catch (Throwable ignored) {
}
});
}
@ -95,76 +90,53 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
@Unique
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) {
for (ItemStack stack : getUpgrades()) {
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; // 无频道卡也算初始化完成
eap$hasInitialized = true;
return;
}
if (eap$link == null) {
// 使用mainNode而不是getActionableNode因为后者可能返回null
IWirelessEndpoint endpoint = new InterfaceNodeEndpointImpl(host, () -> mainNode.getNode());
var endpoint = new InterfaceNodeEndpointImpl(host, () -> this.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刷屏
@ -173,15 +145,13 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 初始化失败后唤醒设备失败: {}", t.toString());
} catch (Throwable ignored) {
}
});
} catch (Throwable ignored) {
}
}
} catch (Exception e) {
ExtendedAELogger.LOGGER.error("[服务端] Interface 初始化频道链接失败", e);
} catch (Exception ignored) {
}
}
@ -238,18 +208,14 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
mainNode.ifPresent((grid, node) -> {
try {
grid.getTickManager().wakeDevice(node);
} catch (Throwable t) {
ExtendedAELogger.LOGGER.debug("[服务端] Interface 延迟等待期间唤醒设备失败: {}", t.toString());
} catch (Throwable ignored) {
}
});
} catch (Throwable ignored) {
}
ExtendedAELogger.LOGGER.debug("[服务端] Interface 网格仍在引导,继续等待: ready={}, active={}, online={}",
mainNode.isReady(), mainNode.isActive(), mainNode.isOnline());
}
} else {
// 网格已引导完成执行初始化
ExtendedAELogger.LOGGER.debug("[服务端] Interface 延迟初始化触发(网格已完成引导)");
eap$initializeChannelLink();
}
}

View File

@ -20,6 +20,18 @@ public abstract class PatternProviderLogicTickerMixin {
@Final
private PatternProviderLogic this$0;
@Inject(method = "tickingRequest", at = @At("HEAD"))
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"))
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {

View File

@ -37,6 +37,18 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
@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;
@Final
@Shadow
private PatternProviderLogicHost host;
@ -52,26 +64,13 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
@Unique
private void eap$onUpgradesChanged() {
this.host.saveChanges();
// 读取频道卡更新无线链接频率
long channel = 0L;
for (var stack : this.eap$upgrades) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
break;
}
}
if (eap$link == null) {
var endpoint = new GenericNodeEndpointImpl(() -> host.getBlockEntity(), () -> this.mainNode.getNode());
eap$link = new WirelessSlaveLink(endpoint);
}
eap$link.setFrequency(channel);
eap$link.updateStatus();
// 升级变更重置并尝试初始化
eap$lastChannel = -1;
eap$hasInitialized = false;
eap$initializeChannelLink();
}
@Override
public IUpgradeInventory getUpgrades() {
return this.eap$upgrades;
}
@Inject(method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
at = @At("TAIL"))
@ -87,6 +86,10 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void eap$loadUpgrades(CompoundTag tag, CallbackInfo ci) {
this.eap$upgrades.readFromNBT(tag, "upgrades");
// NBT 加载后重置并尝试初始化可能刚进入世界
eap$lastChannel = -1;
eap$hasInitialized = false;
eap$initializeChannelLink();
}
@Inject(method = "addDrops", at = @At("TAIL"))
@ -109,4 +112,140 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
eap$link.updateStatus();
}
}
@Override
public IUpgradeInventory getUpgrades() {
return this.eap$upgrades;
}
// ===== 频道卡初始化与延迟重试服务端 =====
@Unique
public void eap$initializeChannelLink() {
// 客户端早退
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
return;
}
// 避免重复初始化
if (eap$hasInitialized) {
return;
}
// 等待网格完成引导
if (!mainNode.hasGridBooted()) {
// 安排短延迟等待后续 tick 再试
eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5);
try {
mainNode.ifPresent((grid, node) -> {
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
});
} catch (Throwable ignored) {}
return;
}
try {
long channel = 0L;
boolean found = false;
for (ItemStack stack : this.eap$upgrades) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
}
if (!found) {
// 无频道卡断开并视为初始化完成
if (eap$link != null) {
eap$link.setFrequency(0L);
eap$link.updateStatus();
}
eap$hasInitialized = true;
return;
}
if (eap$link == null) {
var endpoint = new GenericNodeEndpointImpl(() -> host.getBlockEntity(), () -> this.mainNode.getNode());
eap$link = new WirelessSlaveLink(endpoint);
}
eap$link.setFrequency(channel);
eap$link.updateStatus();
if (eap$link.isConnected()) {
eap$hasInitialized = true;
} else {
eap$hasInitialized = false;
eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5);
try {
mainNode.ifPresent((grid, node) -> {
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
});
} catch (Throwable ignored) {}
}
} catch (Exception ignored) {
}
}
@Override
public void eap$setClientWirelessState(boolean connected) {
eap$clientConnected = connected;
}
@Override
public boolean eap$isWirelessConnected() {
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 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) {
eap$delayedInitTicks = 5;
try {
mainNode.ifPresent((grid, node) -> {
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
});
} catch (Throwable ignored) {}
}
} else {
eap$initializeChannelLink();
}
}
}
// 当主节点状态变化例如 GRID_BOOT 完成安排一次延迟初始化并唤醒设备
@Inject(method = "onMainNodeStateChanged", at = @At("TAIL"))
private void eap$onMainNodeStateChangedTail(CallbackInfo ci) {
eap$lastChannel = -1;
eap$hasInitialized = false;
eap$delayedInitTicks = 10;
try {
mainNode.ifPresent((grid, node) -> {
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
});
} catch (Throwable ignored) {}
}
}