修复iobus初始化

This commit is contained in:
GaLicn 2025-09-23 10:40:02 +08:00
parent 4745be1063
commit fd075c76f4
6 changed files with 335 additions and 70 deletions

View File

@ -5,4 +5,18 @@ package com.extendedae_plus.bridge;
*/
public interface InterfaceWirelessLinkBridge {
void extendedae_plus$updateWirelessLink();
/**
* 获取无线连接状态服务端返回真实状态客户端返回同步状态
*/
default boolean extendedae_plus$isWirelessConnected() {
return false;
}
/**
* 设置客户端的无线连接状态仅在客户端使用
*/
default void extendedae_plus$setClientWirelessState(boolean connected) {
// 默认实现为空
}
}

View File

@ -1,36 +1,48 @@
package com.extendedae_plus.mixin.ae2;
import appeng.blockentity.crafting.CraftingBlockEntity;
import appeng.blockentity.crafting.CraftingMonitorBlockEntity;
import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.me.helpers.MachineSource;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.List;
@Mixin(value = CraftingCPUCluster.class, remap = false, priority = 2000)
public abstract class CraftingCPUClusterMixin {
// 1) 提升单方块线程上限的常量避免抛出 IAE IllegalArgumentException
@ModifyConstant(
method = "addBlockEntity(Lappeng/blockentity/crafting/CraftingBlockEntity;)V",
constant = @Constant(intValue = 16)
)
private int extendedae_plus$raisePerUnitLimit(int original) {
// 放宽到极大值完全取消单方块 16 线程的硬限制
return Integer.MAX_VALUE;
}
@Shadow private List<CraftingBlockEntity> blockEntities;
@Shadow private List<CraftingMonitorBlockEntity> status;
@Shadow private MachineSource machineSrc;
@Shadow private long storage;
@Shadow private int accelerator;
/**
* 完全重写addBlockEntity方法移除16线程的硬限制
* @author ExtendedAE_Plus
* @reason 移除单方块16线程的硬限制允许更高的线程数
*/
@Overwrite
void addBlockEntity(CraftingBlockEntity te) {
if (this.machineSrc == null || te.isCoreBlock()) {
this.machineSrc = new MachineSource(te);
}
// 2) 保持统计使用原始线程值若存在多处调用不再返回固定 16
@Redirect(
method = "addBlockEntity(Lappeng/blockentity/crafting/CraftingBlockEntity;)V",
at = @At(
value = "INVOKE",
target = "Lappeng/blockentity/crafting/CraftingBlockEntity;getAcceleratorThreads()I",
ordinal = 1
)
)
private int extendedae_plus$onGetThreadsForLimitCheck(CraftingBlockEntity te) {
// 返回原始线程数确保总并行单元不被错误下限
return te.getAcceleratorThreads();
te.setCoreBlock(false);
te.saveChanges();
this.blockEntities.add(0, te);
if (te instanceof CraftingMonitorBlockEntity) {
this.status.add((CraftingMonitorBlockEntity) te);
}
if (te.getStorageBytes() > 0) {
this.storage += te.getStorageBytes();
}
if (te.getAcceleratorThreads() > 0) {
// 移除原来的16线程限制直接添加线程数
this.accelerator += te.getAcceleratorThreads();
}
}
}

View File

@ -0,0 +1,68 @@
package com.extendedae_plus.mixin.ae2.parts;
import appeng.parts.AEBasePart;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import net.minecraft.network.FriendlyByteBuf;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* 为所有AE2 Part添加无线连接状态的客户端同步功能
*/
@Mixin(value = AEBasePart.class, remap = false)
public class AEBasePartClientSyncMixin {
@Inject(method = "writeToStream", at = @At("TAIL"))
private void extendedae_plus$writeWirelessState(FriendlyByteBuf data, CallbackInfo ci) {
// 检查是否实现了无线链接桥接接口
if (this instanceof InterfaceWirelessLinkBridge) {
InterfaceWirelessLinkBridge bridge = (InterfaceWirelessLinkBridge) this;
// 同步无线连接状态到客户端
boolean connected = false;
try {
// 只在服务端获取真实连接状态
AEBasePart part = (AEBasePart)(Object)this;
if (!part.isClientSide()) {
connected = bridge.extendedae_plus$isWirelessConnected();
// 调试日志记录写入的状态
if (part.getClass().getSimpleName().contains("IOBus")) {
System.out.println("[写入状态] IOBus 无线连接状态: " + connected);
}
}
} catch (Exception e) {
// 忽略异常默认为false
System.err.println("获取无线连接状态失败: " + e.getMessage());
}
data.writeBoolean(connected);
} else {
// 不是无线链接Part写入false
data.writeBoolean(false);
}
}
@Inject(method = "readFromStream", at = @At("TAIL"))
private void extendedae_plus$readWirelessState(FriendlyByteBuf data, CallbackInfoReturnable<Boolean> cir) {
// 读取无线连接状态
boolean connected = data.readBoolean();
// 检查是否实现了无线链接桥接接口
if (this instanceof InterfaceWirelessLinkBridge) {
InterfaceWirelessLinkBridge bridge = (InterfaceWirelessLinkBridge) this;
try {
// 调试日志记录读取的状态
AEBasePart part = (AEBasePart)(Object)this;
if (part.getClass().getSimpleName().contains("IOBus")) {
System.out.println("[读取状态] IOBus 无线连接状态: " + connected);
}
// 更新客户端状态
bridge.extendedae_plus$setClientWirelessState(connected);
} catch (Exception e) {
// 忽略异常
System.err.println("设置客户端无线连接状态失败: " + e.getMessage());
}
}
}
}

View File

@ -5,11 +5,14 @@ import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.helpers.InterfaceLogicHost;
import appeng.parts.automation.IOBusPart;
import net.minecraft.nbt.CompoundTag;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.wireless.WirelessSlaveLink;
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
import net.minecraft.network.FriendlyByteBuf;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@ -24,36 +27,105 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
@Unique
private WirelessSlaveLink extendedae_plus$link;
@Unique
private long extendedae_plus$lastChannel = -1;
@Unique
private boolean extendedae_plus$clientConnected = false;
@Unique
private boolean extendedae_plus$hasTickInitialized = false;
@Inject(method = "upgradesChanged", at = @At("TAIL"))
private void extendedae_plus$onUpgradesChanged(CallbackInfo ci) {
IUpgradeInventory inv = this.getUpgrades();
long channel = 0L;
boolean found = false;
for (var stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
// 只在服务端初始化频道链接
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
extendedae_plus$initializeChannelLink();
}
if (!found) {
// 无频道卡则断开
if (extendedae_plus$link != null) {
extendedae_plus$link.setFrequency(0L);
extendedae_plus$link.updateStatus();
}
}
@Inject(method = "tickingRequest", at = @At("HEAD"))
private void extendedae_plus$beforeTick(appeng.api.networking.IGridNode node, int ticksSinceLastCall, org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
// 在第一次tick时初始化频道链接此时网格节点已经在线
if (!extendedae_plus$hasTickInitialized && !((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
extendedae_plus$hasTickInitialized = true;
extendedae_plus$initializeChannelLink();
}
}
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void extendedae_plus$afterReadFromNBT(CompoundTag extra, CallbackInfo ci) {
// 从NBT加载时重置频道缓存和tick初始化标志
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
extendedae_plus$lastChannel = -1;
extendedae_plus$hasTickInitialized = false; // 重置标志允许再次初始化
}
}
@Unique
private void extendedae_plus$initializeChannelLink() {
// 防止重复调用
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return;
}
if (extendedae_plus$link == null) {
var endpoint = new GenericNodeEndpointImpl(
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
() -> ((IActionHost)(Object)this).getActionableNode()
);
extendedae_plus$link = new WirelessSlaveLink(endpoint);
try {
IUpgradeInventory inv = this.getUpgrades();
long channel = 0L;
boolean found = false;
for (var stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
}
// 频道没有变化则跳过
if (extendedae_plus$lastChannel == channel) {
return;
}
extendedae_plus$lastChannel = channel;
ExtendedAELogger.LOGGER.debug("[服务端] IOBus 初始化频道链接: found={}, channel={}", found, channel);
if (!found) {
// 无频道卡则断开
if (extendedae_plus$link != null) {
extendedae_plus$link.setFrequency(0L);
extendedae_plus$link.updateStatus();
ExtendedAELogger.LOGGER.debug("[服务端] IOBus 断开频道链接");
// 立即通知客户端状态变化断开连接无需延迟
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
}
return;
}
if (extendedae_plus$link == null) {
var endpoint = new GenericNodeEndpointImpl(
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
() -> ((IActionHost)(Object)this).getActionableNode()
);
extendedae_plus$link = new WirelessSlaveLink(endpoint);
ExtendedAELogger.LOGGER.debug("[服务端] IOBus 创建新的无线链接");
}
extendedae_plus$link.setFrequency(channel);
extendedae_plus$link.updateStatus();
// 调试信息检查网格节点状态
var gridNode = ((IActionHost)(Object)this).getActionableNode();
ExtendedAELogger.LOGGER.debug("[服务端] IOBus 设置频道: {}, 连接状态: {}, 网格节点: {}, 在线: {}",
channel, extendedae_plus$link.isConnected(),
gridNode != null ? "exists" : "null",
gridNode != null ? gridNode.isOnline() : "N/A");
// 通知客户端状态变化
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
} catch (Exception e) {
ExtendedAELogger.LOGGER.error("[服务端] IOBus 初始化频道链接失败", e);
}
extendedae_plus$link.setFrequency(channel);
extendedae_plus$link.updateStatus();
}
@Override
@ -62,4 +134,18 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
extendedae_plus$link.updateStatus();
}
}
@Override
public boolean extendedae_plus$isWirelessConnected() {
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return extendedae_plus$clientConnected;
} else {
return extendedae_plus$link != null && extendedae_plus$link.isConnected();
}
}
@Override
public void extendedae_plus$setClientWirelessState(boolean connected) {
extendedae_plus$clientConnected = connected;
}
}

View File

@ -1,9 +1,13 @@
package com.extendedae_plus.mixin.ae2.parts.storagebus;
import appeng.api.networking.IGridNodeListener;
import appeng.api.networking.security.IActionHost;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.parts.storagebus.StorageBusPart;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
@ -23,35 +27,101 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
@Unique
private WirelessSlaveLink extendedae_plus$link;
@Unique
private long extendedae_plus$lastChannel = -1;
@Unique
private boolean extendedae_plus$clientConnected = false;
@Inject(method = "upgradesChanged", at = @At("TAIL"))
private void extendedae_plus$onUpgradesChanged(CallbackInfo ci) {
IUpgradeInventory inv = this.getUpgrades();
long channel = 0L;
boolean found = false;
for (var stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
// 只在服务端初始化频道链接
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
extendedae_plus$initializeChannelLink();
}
if (!found) {
if (extendedae_plus$link != null) {
extendedae_plus$link.setFrequency(0L);
extendedae_plus$link.updateStatus();
}
}
@Inject(method = "onMainNodeStateChanged", at = @At("TAIL"))
private void extendedae_plus$onMainNodeStateChanged(IGridNodeListener.State reason, CallbackInfo ci) {
// 在节点状态变化时包括加载后的GRID_BOOT重新初始化频道链接
if (reason == IGridNodeListener.State.GRID_BOOT && !((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
extendedae_plus$initializeChannelLink();
}
}
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void extendedae_plus$afterReadFromNBT(CompoundTag extra, CallbackInfo ci) {
// 从NBT加载后也重新初始化频道链接只在服务端
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
// 从NBT加载时重置频道缓存强制重新初始化
extendedae_plus$lastChannel = -1;
extendedae_plus$initializeChannelLink();
}
}
@Unique
private void extendedae_plus$initializeChannelLink() {
// 防止重复调用
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return;
}
if (extendedae_plus$link == null) {
var endpoint = new GenericNodeEndpointImpl(
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
() -> ((IActionHost)(Object)this).getActionableNode()
);
extendedae_plus$link = new WirelessSlaveLink(endpoint);
try {
IUpgradeInventory inv = this.getUpgrades();
long channel = 0L;
boolean found = false;
for (var stack : inv) {
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
channel = ChannelCardItem.getChannel(stack);
found = true;
break;
}
}
// 频道没有变化则跳过
if (extendedae_plus$lastChannel == channel) {
return;
}
extendedae_plus$lastChannel = channel;
ExtendedAELogger.LOGGER.debug("[服务端] StorageBus 初始化频道链接: found={}, channel={}", found, channel);
if (!found) {
if (extendedae_plus$link != null) {
extendedae_plus$link.setFrequency(0L);
extendedae_plus$link.updateStatus();
ExtendedAELogger.LOGGER.debug("[服务端] StorageBus 断开频道链接");
// 通知客户端状态变化
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
}
return;
}
if (extendedae_plus$link == null) {
var endpoint = new GenericNodeEndpointImpl(
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
() -> ((IActionHost)(Object)this).getActionableNode()
);
extendedae_plus$link = new WirelessSlaveLink(endpoint);
ExtendedAELogger.LOGGER.debug("[服务端] StorageBus 创建新的无线链接");
}
extendedae_plus$link.setFrequency(channel);
extendedae_plus$link.updateStatus();
// 调试信息检查网格节点状态
var gridNode = ((IActionHost)(Object)this).getActionableNode();
ExtendedAELogger.LOGGER.debug("[服务端] StorageBus 设置频道: {}, 连接状态: {}, 网格节点: {}, 在线: {}",
channel, extendedae_plus$link.isConnected(),
gridNode != null ? "exists" : "null",
gridNode != null ? gridNode.isOnline() : "N/A");
// 通知客户端状态变化
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
} catch (Exception e) {
ExtendedAELogger.LOGGER.error("[服务端] StorageBus 初始化频道链接失败", e);
}
extendedae_plus$link.setFrequency(channel);
extendedae_plus$link.updateStatus();
}
@Override
@ -60,4 +130,18 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
extendedae_plus$link.updateStatus();
}
}
@Override
public boolean extendedae_plus$isWirelessConnected() {
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
return extendedae_plus$clientConnected;
} else {
return extendedae_plus$link != null && extendedae_plus$link.isConnected();
}
}
@Override
public void extendedae_plus$setClientWirelessState(boolean connected) {
extendedae_plus$clientConnected = connected;
}
}

View File

@ -67,6 +67,7 @@
"ae2.helpers.patternprovider.PatternProviderLogicHostUpgradesMixin",
"ae2.menu.PatternProviderMenuUpgradesMixin",
"ae2.helpers.patternprovider.PatternProviderLogicTickerMixin",
"ae2.parts.AEBasePartClientSyncMixin",
"ae2.parts.automation.IOBusPartChannelCardMixin",
"ae2.parts.automation.IOBusPartTickerChannelCardMixin",
"ae2.parts.storagebus.StorageBusPartChannelCardMixin",