ExtendedAE_Plus/src/main/java/com/extendedae_plus/mixin/ContainerPatternEncodingTermMenuMixin.java

114 lines
5.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.extendedae_plus.mixin;
import appeng.menu.me.items.PatternEncodingTermMenu;
import appeng.menu.slot.RestrictedInputSlot;
import appeng.api.crafting.PatternDetailsHelper;
import appeng.parts.encoding.EncodingMode;
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
import com.glodblock.github.glodium.network.packet.sync.Paras;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
import java.util.function.Consumer;
/**
* 给 AE2 的 PatternEncodingTermMenu 增加一个通用动作持有者,实现接收 EPP 的 CGenericPacket 动作。
* 注册动作 "upload_to_matrix":仅上传“合成图样”到 ExtendedAE 装配矩阵。
*/
@Mixin(PatternEncodingTermMenu.class)
public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHolder {
@Unique
private final Map<String, Consumer<Paras>> actions = createHolder();
@Unique
private Player epp$player;
@Shadow(remap = false)
private RestrictedInputSlot encodedPatternSlot;
@Unique
private void epp$scheduleUploadWithRetry(ServerPlayer sp, PatternEncodingTermMenu menu, int attemptsLeft) {
sp.server.execute(() -> {
try {
if (attemptsLeft < 0) {
return;
}
var stack = this.encodedPatternSlot != null ? this.encodedPatternSlot.getItem() : net.minecraft.world.item.ItemStack.EMPTY;
if (stack != null && !stack.isEmpty() && PatternDetailsHelper.isEncodedPattern(stack)) {
System.out.println("[EAE+][Server] Auto-upload crafting pattern after encode.");
ExtendedAEPatternUploadUtil.uploadFromEncodingMenuToMatrix(sp, menu);
} else {
// 槽位可能尚未同步到位,继续下一 tick 重试
if (attemptsLeft > 0) {
epp$scheduleUploadWithRetry(sp, menu, attemptsLeft - 1);
} else {
System.out.println("[EAE+][Server] Auto-upload aborted: encoded slot still empty or not encoded after retries.");
}
}
} catch (Throwable t) {
System.out.println("[EAE+][Server] Auto-upload after encode failed: " + t);
t.printStackTrace();
}
});
}
// AE2 终端主构造PatternEncodingTermMenu(int id, Inventory ip, IPatternTerminalMenuHost host)
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;)V", at = @At("TAIL"), remap = false)
private void epp$ctorA(int id, net.minecraft.world.entity.player.Inventory ip, appeng.helpers.IPatternTerminalMenuHost host, CallbackInfo ci) {
this.epp$player = ip.player;
// 不再注册任何上传相关动作
}
// AE2 另一个构造PatternEncodingTermMenu(MenuType, int, Inventory, IPatternTerminalMenuHost, boolean)
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;Z)V", at = @At("TAIL"), remap = false)
private void epp$ctorB(net.minecraft.world.inventory.MenuType<?> menuType, int id, net.minecraft.world.entity.player.Inventory ip, appeng.helpers.IPatternTerminalMenuHost host, boolean bindInventory, CallbackInfo ci) {
this.epp$player = ip.player;
// 不再注册任何上传相关动作
}
@NotNull
@Override
public Map<String, Consumer<Paras>> getActionMap() {
return this.actions;
}
// 服务器端:在 encode() 执行完毕后,如果已编码槽位存在样板且当前为“合成模式”,则上传到装配矩阵
@Inject(method = "encode", at = @At("TAIL"), remap = false)
private void epp$serverUploadAfterEncode(CallbackInfo ci) {
try {
if (!(this.epp$player instanceof ServerPlayer sp)) {
return; // 仅服务器执行
}
var menu = (PatternEncodingTermMenu) (Object) this;
if (menu.getMode() != EncodingMode.CRAFTING) {
return; // 只处理合成样板
}
if (this.encodedPatternSlot == null) {
return;
}
var stack = this.encodedPatternSlot.getItem();
if (stack == null || stack.isEmpty()) {
return; // 没有编码样板
}
if (!PatternDetailsHelper.isEncodedPattern(stack)) {
return; // 不是编码样板
}
// 为兼容整合包中可能出现的延后写槽位/同步,增加多次重试(共 5 次,每次间隔 1 tick
epp$scheduleUploadWithRetry(sp, menu, 5);
} catch (Throwable t) {
System.out.println("[EAE+][Server] epp$serverUploadAfterEncode error: " + t);
t.printStackTrace();
}
}
}