mixin
This commit is contained in:
parent
d7a690da14
commit
27f7ed0122
10
build.gradle
10
build.gradle
|
|
@ -135,21 +135,13 @@ sourceSets.main.java {
|
|||
// 允许 accessor
|
||||
include 'com/extendedae_plus/mixin/**/accessor/**'
|
||||
// 排除具体的非 accessor mixin 目录
|
||||
// AE2 相关非 accessor
|
||||
exclude 'com/extendedae_plus/mixin/ae2/helpers/**'
|
||||
exclude 'com/extendedae_plus/mixin/ae2/autopattern/**'
|
||||
exclude 'com/extendedae_plus/mixin/ae2/client/**'
|
||||
exclude 'com/extendedae_plus/mixin/ae2/menu/**'
|
||||
exclude 'com/extendedae_plus/mixin/ae2/AEProcessingPatternMixin.java'
|
||||
// 排除 ae2 根目录下的普通 mixin(保留 accessor 子目录)
|
||||
exclude 'com/extendedae_plus/mixin/ae2/*.java'
|
||||
// AE2 相关非 accessor(已启用,需要参与编译与运行)
|
||||
// 其他模块的非 accessor mixin
|
||||
exclude 'com/extendedae_plus/mixin/ae2WTlib/**'
|
||||
// 保留 mixin/jei/accessor,但排除其余
|
||||
exclude 'com/extendedae_plus/mixin/jei/*.java'
|
||||
// 排除顶层 mixin 文件
|
||||
exclude 'com/extendedae_plus/mixin/PickFromWirelessMixin.java'
|
||||
exclude 'com/extendedae_plus/mixin/extendedae/**'
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import org.slf4j.Logger;
|
|||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
import com.extendedae_plus.init.ModMenuTypes;
|
||||
import com.extendedae_plus.network.ModNetwork;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
@ -80,6 +81,8 @@ public class ExtendedAEPlus {
|
|||
ITEMS.register(modEventBus);
|
||||
// Register the Deferred Register to the mod event bus so tabs get registered
|
||||
CREATIVE_MODE_TABS.register(modEventBus);
|
||||
// Register the Deferred Register to the mod event bus so menu types get registered
|
||||
ModMenuTypes.MENUS.register(modEventBus);
|
||||
|
||||
// Register ourselves for server and other game events we are interested in.
|
||||
// Note that this is necessary if and only if we want *this* class (ExtendedAEPlus) to respond directly to events.
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ package com.extendedae_plus.mixin.ae2;
|
|||
import appeng.crafting.pattern.EncodedPatternItem;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -20,10 +21,13 @@ public class EncodedPatternItemMixin {
|
|||
// 客户端:在 HoverText 显示样板的编码玩家
|
||||
@Inject(method = "appendHoverText", at = @At("TAIL"))
|
||||
public void epp$appendHoverText(ItemStack stack, Level level, List<Component> lines, TooltipFlag advancedTooltips, CallbackInfo ci){
|
||||
if (stack.hasTag() && ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()) {
|
||||
CompoundTag tag = stack.getOrCreateTag();
|
||||
String name = tag.getString("encodePlayer");
|
||||
lines.add(Component.translatable("extendedae_plus.pattern.hovertext.player", name).withStyle(ChatFormatting.GRAY));
|
||||
if (ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()) {
|
||||
var customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||
var tag = customData.copyTag();
|
||||
if (tag.contains("encodePlayer")) {
|
||||
String name = tag.getString("encodePlayer");
|
||||
lines.add(Component.translatable("extendedae_plus.pattern.hovertext.player", name).withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.neoforged.fml.ModList;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import net.minecraft.client.renderer.Rect2i;
|
|||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
|
@ -79,7 +80,7 @@ public abstract class AEBaseScreenMixin {
|
|||
try {
|
||||
LogUtils.getLogger().info("EAP: Send CraftingMonitorJumpC2SPacket: {}", key);
|
||||
} catch (Throwable ignored2) {}
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key));
|
||||
PacketDistributor.sendToServer(new CraftingMonitorJumpC2SPacket(key));
|
||||
cir.setReturnValue(true);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
|
@ -113,7 +114,7 @@ public abstract class AEBaseScreenMixin {
|
|||
try {
|
||||
LogUtils.getLogger().info("EAP: Send CraftingMonitorOpenProviderC2SPacket: {}", key);
|
||||
} catch (Throwable ignored2) {}
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key));
|
||||
PacketDistributor.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key));
|
||||
cir.setReturnValue(true);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
|
@ -183,10 +184,10 @@ public abstract class AEBaseScreenMixin {
|
|||
GuiUtil.drawAmountText(guiGraphics, font, amountText, appEngSlot.x, appEngSlot.y, 0.6f);
|
||||
|
||||
try {
|
||||
var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level, false);
|
||||
var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level);
|
||||
try {
|
||||
if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) {
|
||||
AEKey key = details.getOutputs()[0].what();
|
||||
if (details != null && details.getOutputs() != null && !details.getOutputs().isEmpty()) {
|
||||
AEKey key = details.getOutputs().get(0).what();
|
||||
if (key != null && ClientPatternHighlightStore.hasHighlight(key)) {
|
||||
try {
|
||||
GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import net.minecraft.client.gui.GuiGraphics;
|
|||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.client.renderer.Rect2i;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -40,7 +41,7 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
|
|||
}
|
||||
// 复用已存在的按钮实例,避免重复创建
|
||||
if (eap$uploadBtn == null) {
|
||||
eap$uploadBtn = new IconButton(btn -> ModNetwork.CHANNEL
|
||||
eap$uploadBtn = new IconButton(btn -> PacketDistributor
|
||||
.sendToServer(new com.extendedae_plus.network.RequestProvidersListC2SPacket())) {
|
||||
private final float eap$scale = 0.75f; // 约 12x12
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ import appeng.menu.me.items.PatternEncodingTermMenu;
|
|||
import appeng.menu.slot.RestrictedInputSlot;
|
||||
import appeng.parts.encoding.EncodingMode;
|
||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
||||
import com.glodblock.github.glodium.network.packet.sync.ActionMap;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
@ -30,7 +32,7 @@ import java.util.function.Consumer;
|
|||
public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHolder {
|
||||
|
||||
@Unique
|
||||
private final Map<String, Consumer<Paras>> eap$actions = createHolder();
|
||||
private final ActionMap eap$actions = ActionMap.create();
|
||||
|
||||
@Unique
|
||||
private Player epp$player;
|
||||
|
|
@ -75,7 +77,7 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo
|
|||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
public ActionMap getActionMap() {
|
||||
return this.eap$actions;
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +119,11 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo
|
|||
@Inject(method = "encodePattern", at = @At("TAIL"), remap = false, cancellable = true)
|
||||
private void eap$writeEncodePlayerToPattern(CallbackInfoReturnable<ItemStack> cir) {
|
||||
ItemStack itemStack = cir.getReturnValue();
|
||||
itemStack.getOrCreateTag().putString("encodePlayer", this.epp$player.getGameProfile().getName());
|
||||
cir.setReturnValue(itemStack);
|
||||
if (itemStack != null && !itemStack.isEmpty()) {
|
||||
CustomData.update(DataComponents.CUSTOM_DATA, itemStack, tag -> {
|
||||
tag.putString("encodePlayer", this.epp$player.getGameProfile().getName());
|
||||
});
|
||||
cir.setReturnValue(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@ public abstract class MEStorageMenuMixin {
|
|||
}
|
||||
Setting<T> typedSetting = (Setting<T>) setting;
|
||||
T typedValue = (T) value;
|
||||
client.registerSetting(typedSetting, typedValue);
|
||||
// 仅当具体实现为 ConfigManager 时,才能调用 registerSetting
|
||||
if (client instanceof appeng.util.ConfigManager cm) {
|
||||
cm.registerSetting(typedSetting, typedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public abstract class PatternEncodingTermMenuMixin {
|
|||
var current = blankInv.getStackInSlot(0);
|
||||
int limit = blankInv.getSlotLimit(0);
|
||||
int space = Math.max(0, limit - current.getCount());
|
||||
space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize());
|
||||
space = Math.min(space, AEItems.BLANK_PATTERN.stack(1).getMaxStackSize());
|
||||
if (space <= 0) {
|
||||
return; // 已满,无需填充
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ public abstract class PatternEncodingTermMenuMixin {
|
|||
var current = blankInv.getStackInSlot(0);
|
||||
int limit = blankInv.getSlotLimit(0);
|
||||
int space = Math.max(0, limit - current.getCount());
|
||||
space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize());
|
||||
space = Math.min(space, AEItems.BLANK_PATTERN.stack(1).getMaxStackSize());
|
||||
if (space <= 0) {
|
||||
this.eap$blankAutoFilled = true;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import java.lang.reflect.Method;
|
|||
|
||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||
|
||||
@Mixin(GuiExPatternProvider.class)
|
||||
@Mixin(value = GuiExPatternProvider.class, remap = false)
|
||||
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> implements ExPatternButtonsAccessor, com.extendedae_plus.api.ExPatternPageAccessor {
|
||||
|
||||
@Unique
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import appeng.client.gui.widgets.IconButton;
|
|||
import appeng.menu.AEBaseMenu;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor;
|
||||
import com.extendedae_plus.network.ModNetwork;
|
||||
import com.extendedae_plus.network.OpenProviderUiC2SPacket;
|
||||
import com.extendedae_plus.util.GuiUtil;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
|
||||
|
|
@ -28,6 +27,7 @@ import net.minecraft.world.entity.player.Inventory;
|
|||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -39,12 +39,16 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
@Pseudo
|
||||
@Mixin(value = GuiExPatternTerminal.class)
|
||||
@Mixin(value = GuiExPatternTerminal.class, remap = false)
|
||||
public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu> {
|
||||
|
||||
@Unique
|
||||
|
|
@ -187,7 +191,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
|
|||
ArrayList<?> rows = acc.getRows();
|
||||
|
||||
// 找到该分组对应的第一个 PatternContainerRecord
|
||||
Class<?> cls = GuiExPatternTerminal.class;
|
||||
Class<?> cls = this.getClass();
|
||||
var byGroupField = cls.getDeclaredField("byGroup");
|
||||
byGroupField.setAccessible(true);
|
||||
Object byGroup = byGroupField.get(this); // HashMultimap<PatternContainerGroup, PatternContainerRecord>
|
||||
|
|
@ -236,7 +240,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
|
|||
try {
|
||||
var dimRl = net.minecraft.resources.ResourceLocation.parse(dimStr);
|
||||
if (dimRl != null) {
|
||||
ModNetwork.CHANNEL.sendToServer(new OpenProviderUiC2SPacket(
|
||||
PacketDistributor.sendToServer(new OpenProviderUiC2SPacket(
|
||||
posLong,
|
||||
dimRl,
|
||||
faceOrd
|
||||
|
|
@ -258,8 +262,12 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
|
|||
this.eap$currentlyChoicePatterProvider = -1;
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"), remap = false)
|
||||
private void injectConstructor(CallbackInfo ci) {
|
||||
@Inject(method = "<init>(Lcom/glodblock/github/extendedae/container/ContainerExPatternTerminal;Lnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/network/chat/Component;Lappeng/client/gui/style/ScreenStyle;)V", at = @At("TAIL"), remap = false)
|
||||
private void injectConstructor(com.glodblock.github.extendedae.container.ContainerExPatternTerminal menu,
|
||||
Inventory playerInventory,
|
||||
Component title,
|
||||
ScreenStyle style,
|
||||
CallbackInfo ci) {
|
||||
// 根据配置初始化默认显示/隐藏状态
|
||||
try {
|
||||
this.eap$showSlots = ModConfigs.PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT.get();
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ package com.extendedae_plus.mixin.extendedae.common;
|
|||
import com.extendedae_plus.config.ModConfigs;
|
||||
import com.glodblock.github.extendedae.common.parts.PartExPatternProvider;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Pseudo
|
||||
@Mixin(value = PartExPatternProvider.class, priority = 3000, remap = false)
|
||||
public abstract class PartExPatternProviderMixin {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,24 +10,22 @@ import appeng.menu.guisync.GuiSync;
|
|||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import appeng.menu.slot.AppEngSlot;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(value = ContainerExPatternProvider.class, priority = 3000)
|
||||
public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu implements IActionHolder {
|
||||
@Pseudo
|
||||
@Mixin(value = ContainerExPatternProvider.class, priority = 3000, remap = false)
|
||||
public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu {
|
||||
|
||||
// 使用高位唯一ID,避免与其他模组在同一类上的 @GuiSync 冲突
|
||||
@GuiSync(31415)
|
||||
|
|
@ -40,8 +38,7 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
@Unique
|
||||
private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位
|
||||
|
||||
@Unique
|
||||
private final Map<String, Consumer<Paras>> eap$actions = createHolder();
|
||||
// glodium IActionHolder 已移除,相关 actionMap 由专用网络包替代。
|
||||
|
||||
public ContainerExPatternProviderMixin(MenuType<? extends PatternProviderMenu> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host) {
|
||||
super(menuType, id, playerInventory, host);
|
||||
|
|
@ -72,18 +69,10 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
public void init(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V", at = @At("TAIL"), remap = false, require = 0)
|
||||
private void eap$initPages(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||
int maxSlots = this.getSlots(SlotSemantics.ENCODED_PATTERN).size();
|
||||
this.eap$maxPage = (maxSlots + SLOTS_PER_PAGE - 1) / SLOTS_PER_PAGE;
|
||||
|
||||
// 注册通用动作(供 CGenericPacket 分发)
|
||||
this.eap$actions.put("multiply2", p -> { eap$modifyPatterns(2, false); });
|
||||
this.eap$actions.put("divide2", p -> { eap$modifyPatterns(2, true); });
|
||||
this.eap$actions.put("multiply5", p -> { eap$modifyPatterns(5, false); });
|
||||
this.eap$actions.put("divide5", p -> { eap$modifyPatterns(5, true); });
|
||||
this.eap$actions.put("multiply10", p -> { eap$modifyPatterns(10, false);});
|
||||
this.eap$actions.put("divide10", p -> { eap$modifyPatterns(10, true); });
|
||||
}
|
||||
|
||||
@Unique
|
||||
|
|
@ -102,15 +91,13 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
for (var slot : this.getSlots(SlotSemantics.ENCODED_PATTERN)) {
|
||||
var stack = slot.getItem();
|
||||
if (stack.getItem() instanceof EncodedPatternItem pattern) {
|
||||
var detail = pattern.decode(stack, this.getPlayer().level(), false);
|
||||
var detail = PatternDetailsHelper.decodePattern(stack, this.getPlayer().level());
|
||||
if (detail instanceof AEProcessingPattern process) {
|
||||
var input = process.getSparseInputs();
|
||||
var output = process.getOutputs();
|
||||
var input = process.getSparseInputs(); // List<GenericStack>
|
||||
var output = process.getOutputs(); // List<GenericStack>
|
||||
if (eap$checkModify(input, scale, div) && eap$checkModify(output, scale, div)) {
|
||||
var mulInput = new GenericStack[input.length];
|
||||
var mulOutput = new GenericStack[output.length];
|
||||
eap$modifyStacks(input, mulInput, scale, div);
|
||||
eap$modifyStacks(output, mulOutput, scale, div);
|
||||
var mulInput = eap$modifyStacks(input, scale, div);
|
||||
var mulOutput = eap$modifyStacks(output, scale, div);
|
||||
var newPattern = PatternDetailsHelper.encodeProcessingPattern(mulInput, mulOutput);
|
||||
slot.set(newPattern);
|
||||
}
|
||||
|
|
@ -120,7 +107,7 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
}
|
||||
|
||||
@Unique
|
||||
private boolean eap$checkModify(GenericStack[] stacks, int scale, boolean div) {
|
||||
private boolean eap$checkModify(java.util.List<GenericStack> stacks, int scale, boolean div) {
|
||||
if (stacks == null) return false;
|
||||
if (div) {
|
||||
for (var stack : stacks) {
|
||||
|
|
@ -145,22 +132,17 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
}
|
||||
|
||||
@Unique
|
||||
private void eap$modifyStacks(GenericStack[] src, GenericStack[] dst, int scale, boolean div) {
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
var stack = src[i];
|
||||
private java.util.List<GenericStack> eap$modifyStacks(java.util.List<GenericStack> src, int scale, boolean div) {
|
||||
var dst = new java.util.ArrayList<GenericStack>(src.size());
|
||||
for (var stack : src) {
|
||||
if (stack != null) {
|
||||
long amt = stack.amount();
|
||||
long newAmt = div ? (amt / scale) : (amt * scale);
|
||||
dst[i] = new GenericStack(stack.what(), newAmt);
|
||||
dst.add(new GenericStack(stack.what(), newAmt));
|
||||
} else {
|
||||
dst[i] = null;
|
||||
dst.add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
return this.eap$actions;
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +1,21 @@
|
|||
package com.extendedae_plus.mixin.extendedae.container;
|
||||
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.api.storage.IPatternAccessTermMenuHost;
|
||||
import appeng.menu.guisync.GuiSync;
|
||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternTerminal;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
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;
|
||||
|
||||
@Mixin(ContainerExPatternTerminal.class)
|
||||
public abstract class ContainerExPatternTerminalMixin implements IActionHolder {
|
||||
@Pseudo
|
||||
@Mixin(value = ContainerExPatternTerminal.class, remap = false)
|
||||
public abstract class ContainerExPatternTerminalMixin {
|
||||
|
||||
@GuiSync(25564)
|
||||
@Unique
|
||||
|
|
@ -56,142 +36,15 @@ public abstract class ContainerExPatternTerminalMixin implements IActionHolder {
|
|||
this.eap$hidePatternSlots = !this.eap$hidePatternSlots;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Map<String, Consumer<Paras>> eap$actions;
|
||||
|
||||
@Unique
|
||||
private Player epp$player;
|
||||
|
||||
@Unique
|
||||
private static final Logger EAP_LOGGER = LogManager.getLogger("ExtendedAE_Plus");
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, IConfigurableObject host, CallbackInfo ci) {
|
||||
if (this.eap$actions == null) {
|
||||
this.eap$actions = createHolder();
|
||||
}
|
||||
@Inject(method = "<init>*", at = @At("TAIL"), remap = false)
|
||||
private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, IPatternAccessTermMenuHost host, CallbackInfo ci) {
|
||||
this.epp$player = playerInventory.player;
|
||||
// 注册上传动作:参数顺序必须与客户端 CGenericPacket 保持一致
|
||||
this.eap$actions.put("upload", p -> {
|
||||
try {
|
||||
Object o0 = p.get(0);
|
||||
Object o1 = p.get(1);
|
||||
int playerSlotIndex = (o0 instanceof Number) ? ((Number) o0).intValue() : Integer.parseInt(String.valueOf(o0));
|
||||
long providerId = (o1 instanceof Number) ? ((Number) o1).longValue() : Long.parseLong(String.valueOf(o1));
|
||||
var sp = (ServerPlayer) this.epp$player;
|
||||
ExtendedAEPatternUploadUtil.uploadPatternToProvider(sp, playerSlotIndex, providerId);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
// 注册打开UI动作:open_ui(posLong, dimensionId, faceOrdinal?)
|
||||
this.eap$actions.put("open_ui", p -> {
|
||||
try {
|
||||
// 参数解析
|
||||
Object po = p.get(0); // BlockPos as long (BlockPos#asLong)
|
||||
Object do0 = p.get(1); // Dimension id string (e.g., minecraft:overworld)
|
||||
Object fo;
|
||||
try {
|
||||
fo = p.get(2); // Optional face ordinal
|
||||
} catch (Throwable __ignored) {
|
||||
fo = null;
|
||||
}
|
||||
|
||||
long posLong = (po instanceof Number) ? ((Number) po).longValue() : Long.parseLong(String.valueOf(po));
|
||||
String dimStr = String.valueOf(do0);
|
||||
int faceOrd = -1;
|
||||
if (fo != null) {
|
||||
faceOrd = (fo instanceof Number) ? ((Number) fo).intValue() : Integer.parseInt(String.valueOf(fo));
|
||||
}
|
||||
|
||||
BlockPos pos = BlockPos.of(posLong);
|
||||
ResourceLocation dimId = ResourceLocation.tryParse(dimStr);
|
||||
if (dimId == null) {
|
||||
EAP_LOGGER.warn("[EPlus] open_ui: invalid dim '{}'", dimStr);
|
||||
return;
|
||||
}
|
||||
ResourceKey<Level> dimKey = ResourceKey.create(Registries.DIMENSION, dimId);
|
||||
|
||||
if (!(this.epp$player instanceof ServerPlayer sp)) {
|
||||
EAP_LOGGER.warn("[EPlus] open_ui: not a ServerPlayer");
|
||||
return;
|
||||
}
|
||||
|
||||
ServerLevel level = sp.server.getLevel(dimKey);
|
||||
if (level == null) {
|
||||
EAP_LOGGER.warn("[EPlus] open_ui: level null for key {}", dimKey);
|
||||
return;
|
||||
}
|
||||
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: pos={}, dim={}, faceOrd={}", pos, dimKey.location(), faceOrd);
|
||||
|
||||
// 目标应为供应器所面向/连接的相邻方块,而非供应器自身
|
||||
Direction[] tries = (faceOrd >= 0 && faceOrd < Direction.values().length)
|
||||
? new Direction[]{Direction.values()[faceOrd]}
|
||||
: Direction.values();
|
||||
|
||||
// 1) 先尝试在相邻方块直接打开 MenuProvider
|
||||
for (Direction dir : tries) {
|
||||
BlockPos targetPos = pos.relative(dir);
|
||||
BlockEntity be = level.getBlockEntity(targetPos);
|
||||
if (be instanceof MenuProvider provider) {
|
||||
NetworkHooks.openScreen(sp, provider, targetPos);
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: opened BE MenuProvider at {} (neighbor via {})", targetPos, dir);
|
||||
return;
|
||||
}
|
||||
var state = level.getBlockState(targetPos);
|
||||
MenuProvider provider = state.getMenuProvider(level, targetPos);
|
||||
if (provider != null) {
|
||||
NetworkHooks.openScreen(sp, provider, targetPos);
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: opened State MenuProvider at {} (neighbor via {})", targetPos, dir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 兜底:为避免误触发放置/覆盖,仅在手上至少有一只手为空时,使用 BlockState.use 进行一次“徒手交互”
|
||||
boolean hasFace = (faceOrd >= 0 && faceOrd < Direction.values().length);
|
||||
boolean anyHandEmpty = sp.getMainHandItem().isEmpty() || sp.getOffhandItem().isEmpty();
|
||||
if (anyHandEmpty) {
|
||||
InteractionHand hand = sp.getMainHandItem().isEmpty() ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND;
|
||||
if (hasFace) {
|
||||
Direction dir = Direction.values()[faceOrd];
|
||||
BlockPos targetPos = pos.relative(dir);
|
||||
var state2 = level.getBlockState(targetPos);
|
||||
var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), dir.getOpposite(), targetPos, false);
|
||||
InteractionResult r = state2.use(level, sp, hand, hit);
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: fallback(state.use) at {} hit {} (via {}), result={}", targetPos, dir.getOpposite(), dir, r);
|
||||
} else {
|
||||
// 无朝向:优先尝试有方块实体的邻居,否则尝试实心方块邻居,各只尝试一次
|
||||
Direction chosen = null;
|
||||
for (Direction d : Direction.values()) {
|
||||
if (level.getBlockEntity(pos.relative(d)) != null) { chosen = d; break; }
|
||||
}
|
||||
if (chosen == null) {
|
||||
for (Direction d : Direction.values()) {
|
||||
if (!level.getBlockState(pos.relative(d)).isAir()) { chosen = d; break; }
|
||||
}
|
||||
}
|
||||
if (chosen != null) {
|
||||
BlockPos targetPos = pos.relative(chosen);
|
||||
var state2 = level.getBlockState(targetPos);
|
||||
var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), chosen.getOpposite(), targetPos, false);
|
||||
InteractionResult r = state2.use(level, sp, hand, hit);
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: fallback(state.use) at {} hit {} (auto via {}), result={}", targetPos, chosen.getOpposite(), chosen, r);
|
||||
} else {
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: no neighbor candidate for fallback (faceOrd<0)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EAP_LOGGER.debug("[EPlus] open_ui: skip fallback (hands occupied)");
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
return this.eap$actions;
|
||||
// glodium IActionHolder 已移除,此处逻辑改为使用专用网络包的途径,详见 network 包。
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +1,25 @@
|
|||
package com.extendedae_plus.mixin.extendedae.container;
|
||||
|
||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
||||
import com.glodblock.github.extendedae.common.me.itemhost.HostWirelessExPAT;
|
||||
import com.glodblock.github.extendedae.container.ContainerWirelessExPAT;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.glodblock.github.extendedae.xmod.wt.ContainerWirelessExPAT;
|
||||
import com.glodblock.github.extendedae.xmod.wt.HostWirelessExPAT;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 为无线样板访问终端容器注册通用动作(CGenericPacket 分发)
|
||||
*/
|
||||
@Pseudo
|
||||
@Mixin(ContainerWirelessExPAT.class)
|
||||
public abstract class ContainerWirelessExPatternTerminalMixin implements IActionHolder {
|
||||
@Mixin(value = ContainerWirelessExPAT.class, remap = false)
|
||||
public abstract class ContainerWirelessExPatternTerminalMixin {
|
||||
// 1.21 版本中 ExtendedAE 不再使用 glodium IActionHolder。
|
||||
// 保留空混入以便后续需要时扩展。
|
||||
|
||||
@Unique
|
||||
private final Map<String, Consumer<Paras>> eap$actions = createHolder();
|
||||
|
||||
@Unique
|
||||
private Player epp$player;
|
||||
|
||||
// 明确目标构造签名:<init>(int, Inventory, HostWirelessExPAT)
|
||||
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lcom/glodblock/github/extendedae/common/me/itemhost/HostWirelessExPAT;)V", at = @At("TAIL"), require = 0)
|
||||
private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, HostWirelessExPAT host, CallbackInfo ci) {
|
||||
this.epp$player = playerInventory.player;
|
||||
// 注册上传动作:参数顺序必须与客户端 CGenericPacket 保持一致
|
||||
this.eap$actions.put("upload", p -> {
|
||||
try {
|
||||
Object o0 = p.get(0);
|
||||
Object o1 = p.get(1);
|
||||
int playerSlotIndex = (o0 instanceof Number) ? ((Number) o0).intValue() : Integer.parseInt(String.valueOf(o0));
|
||||
long providerId = (o1 instanceof Number) ? ((Number) o1).longValue() : Long.parseLong(String.valueOf(o1));
|
||||
var sp = (ServerPlayer) this.epp$player;
|
||||
ExtendedAEPatternUploadUtil.uploadPatternToProvider(sp, playerSlotIndex, providerId);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
return this.eap$actions;
|
||||
// 构造方法注入(显式签名),与 ExtendedAE 源码保持一致
|
||||
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lcom/glodblock/github/extendedae/xmod/wt/HostWirelessExPAT;)V", at = @At("TAIL"), require = 0, remap = false)
|
||||
private void init$eap(int id, net.minecraft.world.entity.player.Inventory playerInventory, HostWirelessExPAT host, CallbackInfo ci) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,18 @@
|
|||
"ae2.helpers.PatternProviderLogicAdvancedMixin",
|
||||
"ae2.helpers.PatternProviderLogicDoublingMixin",
|
||||
"ae2.AEProcessingPatternMixin",
|
||||
"extendedae.client.gui.GuiExPatternProviderMixin",
|
||||
|
||||
"ae2.autopattern.CraftingTreeNodeAccessor",
|
||||
"ae2.autopattern.CraftingTreeProcessMixin"
|
||||
"ae2.autopattern.CraftingTreeProcessMixin",
|
||||
"extendedae.common.PartExPatternProviderMixin",
|
||||
"extendedae.common.TileExPatternProviderMixin",
|
||||
"extendedae.container.ContainerExPatternProviderMixin",
|
||||
"extendedae.container.ContainerExPatternTerminalMixin",
|
||||
"extendedae.container.ContainerWirelessExPatternTerminalMixin"
|
||||
],
|
||||
"client": [
|
||||
|
||||
"extendedae.accessor.GuiExPatternTerminalAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user