From 5262e400306c48310418e3459d21a50bfbf0462e Mon Sep 17 00:00:00 2001 From: GaLi <3096147684@qq.com> Date: Tue, 7 Apr 2026 11:50:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=95=9C=E5=83=8F=E6=A0=B7=E6=9D=BF=E4=BE=9B?= =?UTF-8?q?=E5=BA=94=E5=99=A8=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96&?= =?UTF-8?q?=E6=97=A0=E7=BA=BF=E6=94=B6=E5=8F=91=E5=99=A8=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ae2/MirrorPatternProviderBlockEntity.java | 147 ++++++++---------- .../CraftingSimulationStateMixin.java | 35 ++++- .../wireless_transceiver_4.json | 54 ++++++- 3 files changed, 151 insertions(+), 85 deletions(-) diff --git a/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java index 1a8544d..e75a0ca 100644 --- a/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java +++ b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java @@ -34,7 +34,9 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity private static final String TAG_MASTER = "mirrorMaster"; private static final String TAG_MASTER_DIMENSION = "dimension"; private static final String TAG_MASTER_POS = "pos"; - private static final int SYNC_INTERVAL = 2; + private static final int FAST_SYNC_INTERVAL = 2; + private static final int STABLE_SYNC_INTERVAL = 20; + private static final int UNLOADED_MASTER_RETRY_INTERVAL = 40; private static final int AE2_PATTERN_SLOTS = 9; private static final int EXTENDED_PATTERN_PROVIDER_BASE_SLOTS = 36; private static final InternalInventory DISABLED_PATTERN_INVENTORY = new AppEngInternalInventory(0); @@ -45,6 +47,8 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity @Nullable private BlockPos masterPos; + private long nextSyncTick = Long.MIN_VALUE; + public MirrorPatternProviderBlockEntity(BlockPos pos, BlockState blockState) { super(ModBlockEntities.MIRROR_PATTERN_PROVIDER_BE.get(), pos, blockState); } @@ -72,18 +76,19 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity } private void serverTick(ServerLevel level) { - if (Math.floorMod(level.getGameTime() + this.getBlockPos().asLong(), SYNC_INTERVAL) != 0) { + if (level.getGameTime() < this.nextSyncTick) { return; } - this.syncBoundMaster(); + this.nextSyncTick = level.getGameTime() + this.syncBoundMaster(); } @Override public void onReady() { super.onReady(); if (this.getLevel() instanceof ServerLevel serverLevel) { - this.syncBoundMaster(); + this.scheduleImmediateSync(); + this.nextSyncTick = serverLevel.getGameTime() + this.syncBoundMaster(); } } @@ -107,6 +112,7 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity this.masterDimension = null; this.masterPos = null; + this.scheduleImmediateSync(); if (data.contains(TAG_MASTER, Tag.TAG_COMPOUND)) { var masterTag = data.getCompound(TAG_MASTER); if (masterTag.contains(TAG_MASTER_DIMENSION, Tag.TAG_STRING) @@ -155,14 +161,11 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity return false; } - var changed = !Objects.equals(this.masterDimension, master.dimension()) - || !Objects.equals(this.masterPos, master.pos()); - this.masterDimension = master.dimension(); - this.masterPos = master.pos().immutable(); + var changed = this.setBoundMaster(master.dimension(), master.pos()); if (changed) { - this.saveChanges(); - this.markForUpdate(); + this.flushStateChanges(); } + this.scheduleImmediateSync(); return true; } @@ -205,16 +208,21 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity return Component.translatable("extendedae_plus.message.mirror_pattern_provider.missing_master"); } - private void syncBoundMaster() { + private int syncBoundMaster() { var master = this.getMaster(); if (master != null) { - this.syncFromMaster(master); - return; + return this.syncFromMaster(master) ? FAST_SYNC_INTERVAL : STABLE_SYNC_INTERVAL; } if (this.shouldClearBrokenBinding()) { - this.clearMasterBinding(true); + if (this.clearMasterBinding(true)) { + this.flushStateChanges(); + return FAST_SYNC_INTERVAL; + } + return STABLE_SYNC_INTERVAL; } + + return UNLOADED_MASTER_RETRY_INTERVAL; } private boolean shouldClearBrokenBinding() { @@ -230,7 +238,7 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity return !isValidMaster(masterLevel.getBlockEntity(this.masterPos)); } - private void clearMasterBinding(boolean clearMirroredPatterns) { + private boolean clearMasterBinding(boolean clearMirroredPatterns) { var hadBinding = this.masterDimension != null || this.masterPos != null; this.masterDimension = null; @@ -241,36 +249,30 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity changed |= this.clearMirroredPatterns(); } - if (changed) { - this.saveChanges(); - this.markForUpdate(); - } + return changed; } - private boolean bindToMaster(PatternProviderBlockEntity master) { + private boolean setBoundMaster(ResourceKey dimension, BlockPos pos) { + var newPos = pos.immutable(); + var changed = !Objects.equals(this.masterDimension, dimension) || !Objects.equals(this.masterPos, newPos); + + this.masterDimension = dimension; + this.masterPos = newPos; + return changed; + } + + private boolean syncFromMaster(PatternProviderBlockEntity master) { var masterLevel = master.getLevel(); if (masterLevel == null) { return false; } - var newDimension = masterLevel.dimension(); - var newPos = master.getBlockPos().immutable(); - var changed = !Objects.equals(this.masterDimension, newDimension) || !Objects.equals(this.masterPos, newPos); - - this.masterDimension = newDimension; - this.masterPos = newPos; - - return changed; - } - - private boolean syncFromMaster(PatternProviderBlockEntity master) { - var changed = this.bindToMaster(master); + var changed = this.setBoundMaster(masterLevel.dimension(), master.getBlockPos()); changed |= this.syncMirroredSettings(master); changed |= this.syncMirroredPatterns(master); if (changed) { - this.saveChanges(); - this.markForUpdate(); + this.flushStateChanges(); } return changed; @@ -315,71 +317,49 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity private boolean syncMirroredPatterns(PatternProviderBlockEntity master) { var mirrorInventory = this.getPatternInventory(); - var desiredInventory = this.createDesiredPatternInventory(master); + var masterInventory = asPatternInventory(master.getLogic().getPatternInv()); + var mirrorSize = mirrorInventory.size(); + var masterSize = masterInventory.size(); + var changed = false; - if (this.hasSamePatterns(desiredInventory, mirrorInventory)) { - return false; + for (int slot = 0; slot < mirrorSize; slot++) { + var desiredStack = slot < masterSize ? masterInventory.getStackInSlot(slot) : ItemStack.EMPTY; + var currentStack = mirrorInventory.getStackInSlot(slot); + if (!sameStack(desiredStack, currentStack)) { + mirrorInventory.setItemDirect(slot, desiredStack.isEmpty() ? ItemStack.EMPTY : desiredStack.copy()); + changed = true; + } } - this.clearInventory(mirrorInventory); - for (int slot = 0; slot < desiredInventory.size(); slot++) { - mirrorInventory.setItemDirect(slot, desiredInventory.getStackInSlot(slot).copy()); + if (changed) { + this.getLogic().updatePatterns(); } - this.getLogic().updatePatterns(); - return true; + + return changed; } private boolean clearMirroredPatterns() { var patternInventory = this.getPatternInventory(); - if (this.isPatternInventoryEmpty(patternInventory)) { - return false; - } + var changed = false; - this.clearInventory(patternInventory); - this.getLogic().updatePatterns(); - return true; - } - - private boolean hasSamePatterns(AppEngInternalInventory masterInventory, AppEngInternalInventory mirrorInventory) { - if (masterInventory.size() != mirrorInventory.size()) { - return false; - } - - for (int slot = 0; slot < masterInventory.size(); slot++) { - if (!sameStack(masterInventory.getStackInSlot(slot), mirrorInventory.getStackInSlot(slot))) { - return false; + for (int slot = 0; slot < patternInventory.size(); slot++) { + if (!patternInventory.getStackInSlot(slot).isEmpty()) { + patternInventory.setItemDirect(slot, ItemStack.EMPTY); + changed = true; } } - return true; - } - - private boolean isPatternInventoryEmpty(AppEngInternalInventory inventory) { - for (int slot = 0; slot < inventory.size(); slot++) { - if (!inventory.getStackInSlot(slot).isEmpty()) { - return false; - } + if (changed) { + this.getLogic().updatePatterns(); } - return true; + return changed; } private AppEngInternalInventory getPatternInventory() { return ((MirrorLogic) this.getLogic()).getActualPatternInventory(); } - private AppEngInternalInventory createDesiredPatternInventory(PatternProviderBlockEntity master) { - var desiredInventory = new AppEngInternalInventory(this.getPatternInventory().size()); - var masterInventory = asPatternInventory(master.getLogic().getPatternInv()); - var copySlotCount = Math.min(masterInventory.size(), desiredInventory.size()); - - for (int slot = 0; slot < copySlotCount; slot++) { - desiredInventory.setItemDirect(slot, masterInventory.getStackInSlot(slot).copy()); - } - - return desiredInventory; - } - private ItemStack[] copyInventoryContents(AppEngInternalInventory inventory) { var contents = new ItemStack[inventory.size()]; for (int slot = 0; slot < inventory.size(); slot++) { @@ -401,6 +381,15 @@ public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity } } + private void flushStateChanges() { + this.saveChanges(); + this.markForUpdate(); + } + + private void scheduleImmediateSync() { + this.nextSyncTick = Long.MIN_VALUE; + } + @Nullable private ServerLevel getMasterLevel(ServerLevel serverLevel) { if (serverLevel.dimension() == this.masterDimension) { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingSimulationStateMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingSimulationStateMixin.java index 645f665..8b044d9 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingSimulationStateMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingSimulationStateMixin.java @@ -1,6 +1,7 @@ package com.extendedae_plus.mixin.ae2.autopattern; import appeng.api.crafting.IPatternDetails; +import appeng.api.networking.crafting.ICraftingProvider; import appeng.crafting.CraftingCalculation; import appeng.crafting.CraftingPlan; import appeng.crafting.inv.CraftingSimulationState; @@ -11,12 +12,12 @@ import com.extendedae_plus.api.smartDoubling.ICraftingCalculationExt; import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.util.smartDoubling.PatternScaler; -import com.google.common.collect.Iterables; 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.CallbackInfoReturnable; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -34,6 +35,7 @@ public abstract class CraftingSimulationStateMixin { Map crafts = accessor.getCrafts(); // 存放最终分配后的 crafts Map finalCrafts = new LinkedHashMap<>(); + Map providerCountCache = new HashMap<>(); for (Map.Entry entry : crafts.entrySet()) { IPatternDetails details = entry.getKey(); @@ -65,7 +67,11 @@ public abstract class CraftingSimulationStateMixin { // 检查是否开启 provider 轮询分配功能 if (ModConfig.INSTANCE.providerRoundRobinEnable) { CraftingService craftingService = (CraftingService) ((ICraftingCalculationExt) calculation).getGrid().getCraftingService(); - int providerCount = Math.max(Iterables.size(craftingService.getProviders(processingPattern)), 1); + int providerCount = Math.max( + providerCountCache.computeIfAbsent( + getProviderCacheKey(processingPattern), + key -> countProvidersUpTo(craftingService.getProviders(key), totalAmount)), + 1); // totalAmount < providerCount → 只激活 totalAmount 台 provider if (totalAmount < providerCount) { @@ -111,4 +117,27 @@ public abstract class CraftingSimulationStateMixin { crafts.clear(); crafts.putAll(finalCrafts); } -} \ No newline at end of file + + private static IPatternDetails getProviderCacheKey(IPatternDetails pattern) { + if (pattern instanceof ScaledProcessingPattern scaled) { + return scaled.getOriginal(); + } + return pattern; + } + + private static int countProvidersUpTo(Iterable providers, long maxNeeded) { + int count = 0; + int limit = maxNeeded <= 0 + ? Integer.MAX_VALUE + : maxNeeded >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) maxNeeded; + + for (var ignored : providers) { + count++; + if (count >= limit) { + break; + } + } + + return count; + } +} diff --git a/src/main/resources/assets/extendedae_plus/models/block/wirelesstransceiver/wireless_transceiver_4.json b/src/main/resources/assets/extendedae_plus/models/block/wirelesstransceiver/wireless_transceiver_4.json index d5eac6b..5ff73c6 100644 --- a/src/main/resources/assets/extendedae_plus/models/block/wirelesstransceiver/wireless_transceiver_4.json +++ b/src/main/resources/assets/extendedae_plus/models/block/wirelesstransceiver/wireless_transceiver_4.json @@ -1,7 +1,55 @@ { + "format_version": "1.21.11", + "credit": "Made with Blockbench", "parent": "minecraft:block/cube_all", "textures": { - "all": "extendedae_plus:block/wireless_transceiver/wireless_transceiver_4" + "particle": "extendedae_plus:block/wireless_transceiver/wireless_transceiver_4", + "side": "extendedae_plus:block/wireless_transceiver/wireless_transceiver_4", + "top": "extendedae_plus:block/wireless_transceiver/wireless_transceiver_4_top" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top", "cullface": "up"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#top", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, -135, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } } -} - +} \ No newline at end of file