This commit is contained in:
XianYuFish001 2025-09-24 14:06:45 +08:00
parent 8e74d13d73
commit 1c1eb8bc0c
66 changed files with 353 additions and 776 deletions

View File

@ -1,25 +0,0 @@
Installation information
=======
This template repository can be directly cloned to get you started with a new
mod. Simply create a new repository cloned from this one, by following the
instructions provided by [GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template).
Once you have your clone, simply open the repository in the IDE of your choice. The usual recommendation for an IDE is either IntelliJ IDEA or Eclipse.
If at any point you are missing libraries in your IDE, or you've run into problems you can
run `gradlew --refresh-dependencies` to refresh the local cache. `gradlew clean` to reset everything
{this does not affect your code} and then start the process again.
Mapping Names:
============
By default, the MDK is configured to use the official mapping names from Mojang for methods and fields
in the Minecraft codebase. These names are covered by a specific license. All modders should be aware of this
license. For the latest license text, refer to the mapping file itself, or the reference copy here:
https://github.com/NeoForged/NeoForm/blob/main/Mojang.md
Additional Resources:
==========
Community Documentation: https://docs.neoforged.net/
NeoForged Discord: https://discord.neoforged.net/

View File

@ -1,24 +0,0 @@
MIT License
Copyright (c) 2023 NeoForged project
This license applies to the template files as supplied by github.com/NeoForged/MDK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -144,7 +144,6 @@ dependencies {
compileOnly "curse.maven:mega-cells-622112:6005043" compileOnly "curse.maven:mega-cells-622112:6005043"
compileOnly "curse.maven:jade-324717:5427817" compileOnly "curse.maven:jade-324717:5427817"
compileOnly "me.shedaniel:RoughlyEnoughItems-neoforge:16.0.729" compileOnly "me.shedaniel:RoughlyEnoughItems-neoforge:16.0.729"
// compileOnly "mekanism:Mekanism:1.21.1-10.7.0.55"
compileOnly "curse.maven:applied-mekanistics-574300:5978711" compileOnly "curse.maven:applied-mekanistics-574300:5978711"
compileOnly "dev.latvian.mods:kubejs-neoforge:2101.7.1-build.188" compileOnly "dev.latvian.mods:kubejs-neoforge:2101.7.1-build.188"
compileOnly "dev.latvian.mods:rhino:2101.2.5-build.54" compileOnly "dev.latvian.mods:rhino:2101.2.5-build.54"
@ -159,24 +158,12 @@ dependencies {
runtimeOnly "de.mari_023:ae2wtlib:19.2.1" runtimeOnly "de.mari_023:ae2wtlib:19.2.1"
runtimeOnly "curse.maven:jade-324717:5427817" runtimeOnly "curse.maven:jade-324717:5427817"
runtimeOnly "curse.maven:mega-cells-622112:6005043" runtimeOnly "curse.maven:mega-cells-622112:6005043"
// runtimeOnly "mekanism:Mekanism:1.21.1-10.7.0.55"
runtimeOnly "curse.maven:ex-pattern-provider-892005:6863556" runtimeOnly "curse.maven:ex-pattern-provider-892005:6863556"
// setup Xei (EMI/REI/JEI) using project property 'use_Xei' // setup Xei (EMI/REI/JEI) using project property 'use_Xei'
switch (project.findProperty('use_Xei') ?: 'emi') { runtimeOnly "dev.emi:emi-neoforge:${emi_version}+1.21"
case 'emi':
runtimeOnly "dev.emi:emi-neoforge:1.1.10+1.21"
break
case 'rei':
runtimeOnly "me.shedaniel:RoughlyEnoughItems-neoforge:16.0.729"
runtimeOnly "dev.architectury:architectury-neoforge:13.0.1"
runtimeOnly "curse.maven:cloth-config-348521:5424576"
break
case 'jei':
runtimeOnly "mezz.jei:jei-1.21.1-neoforge:19.21.0.247" runtimeOnly "mezz.jei:jei-1.21.1-neoforge:19.21.0.247"
runtimeOnly "curse.maven:ae2-jei-integration-1074338:5748513" runtimeOnly "curse.maven:ae2-jei-integration-1074338:5748513"
break
}
} }
// This block of code expands all declared replace properties in the specified resource targets. // This block of code expands all declared replace properties in the specified resource targets.

View File

@ -1,47 +1,25 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.caching=true org.gradle.caching=true
org.gradle.configuration-cache=true org.gradle.configuration-cache=true
#read more on this at https://github.com/neoforged/ModDevGradle?tab=readme-ov-file#better-minecraft-parameter-names--javadoc-parchment
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
parchment_minecraft_version=1.21.1 parchment_minecraft_version=1.21.1
parchment_mappings_version=2024.11.17 parchment_mappings_version=2024.11.17
# Environment Properties
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
# The Minecraft version must agree with the Neo version to get a valid artifact
minecraft_version=1.21.1 minecraft_version=1.21.1
# The Minecraft version range can use any release version of Minecraft as bounds.
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
# as they do not follow standard versioning conventions.
minecraft_version_range=[1.21.1] minecraft_version_range=[1.21.1]
# The Neo version must agree with the Minecraft version to get a valid artifact
neo_version=21.1.206 neo_version=21.1.206
# The loader version range can only use the major version of FML as bounds
loader_version_range=[1,) loader_version_range=[1,)
## Mod Properties ## Mod Properties
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
# Must match the String constant located in the main mod class annotated with @Mod.
mod_id=extendedae_plus mod_id=extendedae_plus
# The human-readable display name for the mod.
mod_name=ExtendedAE-Plus mod_name=ExtendedAE-Plus
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT
mod_license=All Rights Reserved mod_version=1.0.0
# The mod version. See https://semver.org/
mod_version=1.21.1-1.4.0-fix
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
mod_group_id=com.extendedae_plus mod_group_id=com.extendedae_plus
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. mod_authors=GaLicn, XianYuFish001
mod_authors=YourNameHere, OtherNameHere mod_description=
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
mod_description=Example mod description.\nNewline characters can be used and will be replaced properly.
## UI item explorer selection (emi | rei | jei)
# Default to 'emi' per request; you can override by running with -Puse_Xei=rei or -Puse_Xei=jei ## Dependencies Properties
use_Xei=jei emi_version=1.1.10

View File

@ -1,42 +0,0 @@
package com.extendedae_plus;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.config.ModConfigEvent;
import net.neoforged.neoforge.common.ModConfigSpec;
// An example config class. This is not required, but it's a good idea to have one to keep your config organized.
// Demonstrates how to use Neo's config APIs
public class Config {
private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
.comment("Whether to log the dirt block on common setup")
.define("logDirtBlock", true);
public static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER
.comment("A magic number")
.defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.ConfigValue<String> MAGIC_NUMBER_INTRODUCTION = BUILDER
.comment("What you want the introduction message to be for the magic number")
.define("magicNumberIntroduction", "The magic number is... ");
// a list of strings that are treated as resource locations for items
public static final ModConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
.comment("A list of items to log on common setup.")
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName);
static final ModConfigSpec SPEC = BUILDER.build();
private static boolean validateItemName(final Object obj) {
return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName));
}
}

View File

@ -5,7 +5,7 @@ import appeng.block.AEBaseEntityBlock;
import appeng.blockentity.crafting.CraftingBlockEntity; import appeng.blockentity.crafting.CraftingBlockEntity;
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler; import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler;
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellInventory; import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellInventory;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.init.*; import com.extendedae_plus.init.*;
import com.extendedae_plus.network.ModNetwork; import com.extendedae_plus.network.ModNetwork;
import com.extendedae_plus.util.storage.InfinityStorageManager; import com.extendedae_plus.util.storage.InfinityStorageManager;
@ -18,7 +18,6 @@ import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.level.LevelEvent; import net.neoforged.neoforge.event.level.LevelEvent;
@ -44,6 +43,14 @@ public class ExtendedAEPlus {
// 注册能力 AE2 电缆识别我们的 In-World Grid Node Host // 注册能力 AE2 电缆识别我们的 In-World Grid Node Host
modEventBus.addListener(ModCapabilities::onRegisterCapabilities); modEventBus.addListener(ModCapabilities::onRegisterCapabilities);
/*
TODO
将这literal地狱烧成灰(bushi
反正就是引入dataGeneration, 多写点translatable
顺便不小心露出我无敌的component工具类(
还有改一下config的结构
*/
// 注册本模组方块/物品/创造物品栏 // 注册本模组方块/物品/创造物品栏
ModBlocks.BLOCKS.register(modEventBus); ModBlocks.BLOCKS.register(modEventBus);
ModItems.ITEMS.register(modEventBus); ModItems.ITEMS.register(modEventBus);
@ -62,7 +69,7 @@ public class ExtendedAEPlus {
NeoForge.EVENT_BUS.addListener(InfinityBigIntegerCellInventory::onServerStopping); NeoForge.EVENT_BUS.addListener(InfinityBigIntegerCellInventory::onServerStopping);
// 注册配置接入自定义的 ModConfigs // 注册配置接入自定义的 ModConfigs
modContainer.registerConfig(ModConfig.Type.COMMON, ModConfigs.COMMON_SPEC); modContainer.registerConfig(net.neoforged.fml.config.ModConfig.Type.COMMON, ModConfig.COMMON_SPEC);
} }
// 便捷 ResourceLocation 工具 // 便捷 ResourceLocation 工具

View File

@ -1,11 +1,11 @@
package com.extendedae_plus.client; package com.extendedae_plus.client;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.ModelEvent;
import net.minecraft.client.resources.model.ModelResourceLocation;
/** /**
* 确保在模型烘焙/资源重载期间也会注册内置模型避免在刷新资源后丢失内置模型映射 * 确保在模型烘焙/资源重载期间也会注册内置模型避免在刷新资源后丢失内置模型映射

View File

@ -3,16 +3,14 @@ package com.extendedae_plus.client;
import appeng.client.render.crafting.CraftingCubeModel; import appeng.client.render.crafting.CraftingCubeModel;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider; import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider;
import com.extendedae_plus.client.screen.GlobalProviderModesScreen;
import com.extendedae_plus.init.ModMenuTypes;
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType; import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
import com.extendedae_plus.hooks.BuiltInModelHooks; import com.extendedae_plus.hooks.BuiltInModelHooks;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import com.extendedae_plus.init.ModMenuTypes;
import net.minecraft.client.gui.screens.MenuScreens;
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
/** /**
* 客户端模型注册 formed 模型注册为内置模型 * 客户端模型注册 formed 模型注册为内置模型

View File

@ -2,92 +2,70 @@ package com.extendedae_plus.client;
import appeng.api.stacks.GenericStack; import appeng.api.stacks.GenericStack;
import appeng.client.gui.me.common.MEStorageScreen; import appeng.client.gui.me.common.MEStorageScreen;
import appeng.core.AEConfig;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.integration.jei.JeiRuntimeProxy;
import com.extendedae_plus.mixin.ae2.accessor.MEStorageScreenAccessor; import com.extendedae_plus.mixin.ae2.accessor.MEStorageScreenAccessor;
import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor; import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor;
import com.extendedae_plus.network.OpenCraftFromJeiC2SPacket; import com.extendedae_plus.network.OpenCraftFromJeiC2SPacket;
import com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket; import com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket;
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal; import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
import mezz.jei.api.ingredients.ITypedIngredient; import dev.emi.emi.api.EmiApi;
import dev.emi.emi.api.stack.EmiStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.material.Fluid;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.neoforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.event.ScreenEvent;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.Optional; import java.util.List;
@EventBusSubscriber(modid = ExtendedAEPlus.MODID, value = Dist.CLIENT) @EventBusSubscriber(modid = ExtendedAEPlus.MODID, value = Dist.CLIENT)
public final class InputEvents { public final class InputEvents {
private InputEvents() {} private InputEvents() {}
// 临时适配在缺少 AE2 JEI 辅助类时仅尝试从 JEI 提供的原生 ItemStack 获取否则不处理 private static GenericStack toGenericStack(EmiStack stack) {
private static GenericStack toGenericStack(ITypedIngredient<?> typed) {
try { try {
Optional<ItemStack> maybe = typed.getItemStack(); GenericStack genericStack = null;
if (maybe.isPresent()) { Object typed = stack.getKey();
ItemStack is = maybe.get(); if (typed instanceof Item item) genericStack = GenericStack.fromItemStack(new ItemStack(item));
// 尝试使用 AE2 的通用构造若不可用则返回 null else if (typed instanceof Fluid fluid) genericStack = GenericStack.fromFluidStack(new FluidStack(fluid, 1000));
try { return genericStack;
return GenericStack.fromItemStack(is); } catch (Throwable ignored) {}
} catch (Throwable ignored) {
return null;
}
}
} catch (Throwable ignored) {
}
return null; return null;
} }
@SubscribeEvent @SubscribeEvent
public static void onMouseButtonPre(ScreenEvent.MouseButtonPressed.Pre event) { public static void onMouseButtonPre(InputEvent.MouseButton.Pre event) {
if (event.getAction() != GLFW.GLFW_PRESS) return;
if (Minecraft.getInstance().screen == null) return;
// 优先处理Shift + 左键拉取或下单 // 优先处理Shift + 左键拉取或下单
if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_LEFT && Screen.hasShiftDown()) { if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_LEFT && Screen.hasShiftDown()) {
double mouseX = event.getMouseX(); // 🤓哎wc这Jemi兼容层怎么这么好用啊(
double mouseY = event.getMouseY(); // 😡我们要完全去jei化, 不准用
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(mouseX, mouseY); // 😭
if (hovered.isEmpty()) { // Optional<ITypedIngredient<?>> hovered = new JemiBookmarkOverlay().getIngredientUnderMouse();
hovered = JeiRuntimeProxy.getIngredientUnderMouse(); List<EmiStack> stacks = EmiApi.getHoveredStack(false).getStack().getEmiStacks();
} if (stacks.isEmpty()) return;
if (hovered.isPresent()) { GenericStack stack = toGenericStack(stacks.getFirst());
// JEI 作弊模式开启则放行给 JEI 处理Shift+左键=一组 if (stack == null) return;
if (JeiRuntimeProxy.isJeiCheatModeEnabled()) {
return;
}
ITypedIngredient<?> typed = hovered.get();
GenericStack stack = toGenericStack(typed);
if (stack != null) {
// 发送到服务端若网络有库存则拉取一组到空槽否则若可合成则打开下单界面
PacketDistributor.sendToServer(new PullFromJeiOrCraftC2SPacket(stack)); PacketDistributor.sendToServer(new PullFromJeiOrCraftC2SPacket(stack));
// 消费此次点击避免 JEI/原版对左键的其它处理
event.setCanceled(true);
return;
}
}
} }
// 中键打开 AE 下单界面保持原有功能 // 中键打开 AE 下单界面保持原有功能
if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) { if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) {
// 优先在 JEI 配方界面基于坐标获取若无再从覆盖层/书签获取 // 优先在 JEI 配方界面基于坐标获取若无再从覆盖层/书签获取
double mouseX = event.getMouseX(); List<EmiStack> stacks = EmiApi.getHoveredStack(false).getStack().getEmiStacks();
double mouseY = event.getMouseY(); if (stacks.isEmpty()) return;
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(mouseX, mouseY);
if (hovered.isEmpty()) {
hovered = JeiRuntimeProxy.getIngredientUnderMouse();
}
if (hovered.isEmpty()) return;
ITypedIngredient<?> typed = hovered.get(); GenericStack stack = toGenericStack(stacks.getFirst());
// JEI 作弊模式开启则放行给 JEI 处理中键=一组
if (JeiRuntimeProxy.isJeiCheatModeEnabled()) {
return;
}
GenericStack stack = toGenericStack(typed);
if (stack == null) return; if (stack == null) return;
// 发送到服务端让其验证并打开 CraftAmountMenu // 发送到服务端让其验证并打开 CraftAmountMenu
@ -103,30 +81,32 @@ public final class InputEvents {
if (event.getKeyCode() != GLFW.GLFW_KEY_F) return; if (event.getKeyCode() != GLFW.GLFW_KEY_F) return;
// 仅当鼠标确实悬停在 JEI 配料上时触发 // 仅当鼠标确实悬停在 JEI 配料上时触发
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(); // 大概会在一格有多个(?)stack的时候出bug, 但是真的会有那种时候吗?
if (hovered.isEmpty()) return; List<EmiStack> stack = EmiApi.getHoveredStack(false).getStack().getEmiStacks();
if (stack.isEmpty()) return;
ITypedIngredient<?> typed = hovered.get(); String name = stack.getFirst().getName().getString();
if (name.isEmpty()) return;
// 通用获取显示名称兼容物品/流体等
String name = JeiRuntimeProxy.getTypedIngredientDisplayName(typed);
if (name == null || name.isEmpty()) return;
// 写入 AE2 终端的搜索框 // 写入 AE2 终端的搜索框
var screen = Minecraft.getInstance().screen; var screen = Minecraft.getInstance().screen;
if (screen instanceof MEStorageScreen<?> me) { if (screen instanceof MEStorageScreen<?> me) {
try { try {
MEStorageScreenAccessor acc = (MEStorageScreenAccessor) (Object) me; // 如果用EMI搜索框
if (AEConfig.instance().isUseExternalSearch()) EmiApi.setSearchText(name);
else {
MEStorageScreenAccessor acc = (MEStorageScreenAccessor) me;
acc.eap$getSearchField().setValue(name); acc.eap$getSearchField().setValue(name);
acc.eap$setSearchText(name); // 同步到 Repo 并刷新 acc.eap$setSearchText(name); // 同步到 Repo 并刷新
event.setCanceled(true);
return;
} catch (Throwable ignored) {
} }
event.setCanceled(true);
} catch (Throwable ignored) {}
} else if (screen instanceof GuiExPatternTerminal<?> gpt) { } else if (screen instanceof GuiExPatternTerminal<?> gpt) {
try { try {
if (AEConfig.instance().isUseExternalSearch()) EmiApi.setSearchText(name);
else {
GuiExPatternTerminalAccessor acc = (GuiExPatternTerminalAccessor) gpt; GuiExPatternTerminalAccessor acc = (GuiExPatternTerminalAccessor) gpt;
acc.getSearchField().setValue(name); acc.getSearchField().setValue(name);
}
event.setCanceled(true); event.setCanceled(true);
} catch (Throwable ignored) {} } catch (Throwable ignored) {}
} }

View File

@ -1,6 +1,5 @@
package com.extendedae_plus.client.ui; package com.extendedae_plus.client.ui;
import com.extendedae_plus.network.ModNetwork;
import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket; import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Button;

View File

@ -2,53 +2,61 @@ package com.extendedae_plus.config;
import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
public final class ModConfigs { public final class ModConfig {
public static final ModConfigSpec COMMON_SPEC; public static final ModConfigSpec COMMON_SPEC;
public static final ModConfigSpec.IntValue PAGE_MULTIPLIER; public static final ModConfigSpec.IntValue PAGE_MULTIPLIER;
public static final ModConfigSpec.DoubleValue WIRELESS_MAX_RANGE; public static final ModConfigSpec.DoubleValue WIRELESS_MAX_RANGE;
public static final ModConfigSpec.BooleanValue WIRELESS_CROSS_DIM_ENABLE; public static final ModConfigSpec.BooleanValue WIRELESS_CROSS_DIM_ENABLE;
public static final ModConfigSpec.BooleanValue SHOW_ENCOD_PATTERN_PLAYER; public static final ModConfigSpec.BooleanValue SHOW_ENCODE_PATTERN_PLAYER;
public static final ModConfigSpec.BooleanValue PROVIDER_ROUND_ROBIN_ENABLE; public static final ModConfigSpec.BooleanValue PROVIDER_ROUND_ROBIN_ENABLE;
public static final ModConfigSpec.BooleanValue PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT; public static final ModConfigSpec.BooleanValue PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT;
public static final ModConfigSpec.IntValue SMART_SCALING_MAX_MULTIPLIER; public static final ModConfigSpec.IntValue SMART_SCALING_MAX_MULTIPLIER;
public static final ModConfigSpec.BooleanValue OVERRIDE_AE2WT_PICKING;
public static final ModConfigSpec.BooleanValue INDEPENDENT_UPLOADING_BUTTON;
static { static {
ModConfigSpec.Builder builder = new ModConfigSpec.Builder(); ModConfigSpec.Builder builder = new ModConfigSpec.Builder();
// General settings // General settings
builder.push("general"); builder.push("general");
PAGE_MULTIPLIER = builder PAGE_MULTIPLIER = builder.comment(
.comment(
"扩展样板供应器总槽位容量的倍率", "扩展样板供应器总槽位容量的倍率",
"基础为36每页仍显示36格倍率会增加总页数/总容量", "基础为36每页仍显示36格倍率会增加总页数/总容量",
"建议范围 1-16") "建议范围 1-16")
.defineInRange("pageMultiplier", 1, 1, 64); .defineInRange("pageMultiplier", 1, 1, 64);
// 是否显示样板编码玩家通用 // 是否显示样板编码玩家通用
SHOW_ENCOD_PATTERN_PLAYER = builder SHOW_ENCODE_PATTERN_PLAYER = builder.comment(
.comment(
"是否显示样板编码玩家", "是否显示样板编码玩家",
"开启后将在样板 HoverText 上添加样板的编码玩家" "开启后将在样板 HoverText 上添加样板的编码玩家")
)
.define("showEncoderPatternPlayer", true); .define("showEncoderPatternPlayer", true);
// 模式访问终端ExtendedAE 图样终端默认是否显示槽位渲染SlotsRow // 模式访问终端ExtendedAE 图样终端默认是否显示槽位渲染SlotsRow
// true: 默认显示可通过界面按钮临时隐藏false: 默认隐藏可通过按钮显示 // true: 默认显示可通过界面按钮临时隐藏false: 默认隐藏可通过按钮显示
PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT = builder PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT = builder.comment(
.comment(
"样板终端默认是否显示槽位", "样板终端默认是否显示槽位",
"影响进入界面时SlotsRow的默认可见性仅影响客户端显示" "影响进入界面时SlotsRow的默认可见性仅影响客户端显示")
)
.define("patternTerminalShowSlotsDefault", true); .define("patternTerminalShowSlotsDefault", true);
OVERRIDE_AE2WT_PICKING = builder
.translation("config.extendedae_plus.override_ae2wt_picking")
.comment("是否覆盖AE2WT使用中键从终端选取方块的逻辑",
"开启后选取方块的数量将不被限制在32个",
"(不建议使用,在EMI环境下可能出现奇怪bug)")
.define("overrideAE2WTPicking", false);
INDEPENDENT_UPLOADING_BUTTON = builder
.translation("config.extendedae_plus.independent_uploading_button")
.comment("启用后,在样板编码终端会出现一个独立的按钮用于上传样板")
.define("independentUploadingButton", false);
// end general // end general
builder.pop(); builder.pop();
// Smart-scaling group // Smart-scaling group
builder.push("smartScaling"); builder.push("smartScaling");
// 智能倍增是否在样板供应器间轮询分配请求量开启 provider 均分关闭不拆分 // 智能倍增是否在样板供应器间轮询分配请求量开启 provider 均分关闭不拆分
PROVIDER_ROUND_ROBIN_ENABLE = builder PROVIDER_ROUND_ROBIN_ENABLE = builder.comment(
.comment(
"智能倍增时是否对样板供应器轮询分配", "智能倍增时是否对样板供应器轮询分配",
"仅多个供应器有相同样板时生效,开启后请求会均分到所有可用供应器,关闭则全部分配给单一供应器", "仅多个供应器有相同样板时生效,开启后请求会均分到所有可用供应器,关闭则全部分配给单一供应器",
"注意:所有相关供应器需开启智能倍增,否则可能失效", "注意:所有相关供应器需开启智能倍增,否则可能失效",
@ -57,8 +65,7 @@ public final class ModConfigs {
// 智能倍增的最大倍数以单次样板产出为单位 // 智能倍增的最大倍数以单次样板产出为单位
// 0 表示不限制>0 表示最大倍增倍数上限例如 64 表示最多放大到 64 // 0 表示不限制>0 表示最大倍增倍数上限例如 64 表示最多放大到 64
SMART_SCALING_MAX_MULTIPLIER = builder SMART_SCALING_MAX_MULTIPLIER = builder.comment(
.comment(
"智能倍增的最大倍数0 表示不限制)", "智能倍增的最大倍数0 表示不限制)",
"此倍数是针对单次样板产出的放大倍数上限,用于限制一次推送中按倍增缩放的规模") "此倍数是针对单次样板产出的放大倍数上限,用于限制一次推送中按倍增缩放的规模")
.defineInRange("smartScalingMaxMultiplier", 0, 0, 1048576); .defineInRange("smartScalingMaxMultiplier", 0, 0, 1048576);
@ -69,24 +76,23 @@ public final class ModConfigs {
builder.push("wireless"); builder.push("wireless");
// 无线收发器最大连接距离单位方块 // 无线收发器最大连接距离单位方块
// 一对多从端连接主端时将以该值作为范围限制 // 一对多从端连接主端时将以该值作为范围限制
WIRELESS_MAX_RANGE = builder WIRELESS_MAX_RANGE = builder.comment(
.comment(
"无线收发器最大连接距离(单位:方块)", "无线收发器最大连接距离(单位:方块)",
"从端与主端的直线距离需小于等于该值才会建立连接。") "从端与主端的直线距离需小于等于该值才会建立连接。")
.defineInRange("wirelessMaxRange", 256.0D, 1.0D, 4096.0D); .defineInRange("wirelessMaxRange", 256.0D, 1.0D, 4096.0D);
// 是否允许跨维度连接忽略维度差异进行频道传输 // 是否允许跨维度连接忽略维度差异进行频道传输
WIRELESS_CROSS_DIM_ENABLE = builder WIRELESS_CROSS_DIM_ENABLE = builder.comment(
.comment(
"是否允许无线收发器跨维度建立连接", "是否允许无线收发器跨维度建立连接",
"开启后,从端可连接到不同维度的主端(忽略距离限制)") "开启后,从端可连接到不同维度的主端(忽略距离限制)")
.define("wirelessCrossDimEnable", true); .define("wirelessCrossDimEnable", true);
builder.pop(); // pop wireless builder.pop(); // pop wireless
// builder.pop(); // pop extendedae_plus // builder.pop(); // pop extendedae_plus
COMMON_SPEC = builder.build(); COMMON_SPEC = builder.build();
} }
private ModConfigs() {} private ModConfig() {}
} }

View File

@ -1,8 +1,6 @@
package com.extendedae_plus.content; package com.extendedae_plus.content;
import appeng.api.stacks.AEKey; import appeng.api.stacks.AEKey;
import appeng.api.crafting.IPatternDetails;
import appeng.client.gui.me.patternaccess.PatternContainerRecord;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;

View File

@ -1,20 +1,13 @@
package com.extendedae_plus.content.controller; package com.extendedae_plus.content.controller;
import appeng.api.networking.GridHelper; import appeng.api.networking.*;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridNodeListener;
import appeng.api.networking.IInWorldGridNodeHost;
import appeng.api.networking.IManagedGridNode;
import com.extendedae_plus.init.ModBlockEntities; import com.extendedae_plus.init.ModBlockEntities;
import com.extendedae_plus.init.ModMenuTypes;
import com.extendedae_plus.menu.NetworkPatternControllerMenu; import com.extendedae_plus.menu.NetworkPatternControllerMenu;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.MenuProvider; import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;

View File

@ -1,9 +1,8 @@
package com.extendedae_plus.content.crafting; package com.extendedae_plus.content.crafting;
import appeng.block.crafting.ICraftingUnitType; import appeng.block.crafting.ICraftingUnitType;
import net.minecraft.world.item.Item;
import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModItems;
import net.minecraft.world.item.Item;
public enum EPlusCraftingUnitType implements ICraftingUnitType { public enum EPlusCraftingUnitType implements ICraftingUnitType {
ACCELERATOR_4x(0, 4), ACCELERATOR_4x(0, 4),

View File

@ -1,10 +1,9 @@
package com.extendedae_plus.hooks; package com.extendedae_plus.hooks;
import appeng.block.crafting.CraftingUnitBlock;
import appeng.util.InteractionUtil; import appeng.util.InteractionUtil;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity;
import appeng.block.crafting.CraftingUnitBlock;
import appeng.blockentity.crafting.CraftingBlockEntity;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
@ -14,7 +13,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;

View File

@ -1,11 +1,11 @@
package com.extendedae_plus.init; package com.extendedae_plus.init;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity;
import com.extendedae_plus.content.controller.NetworkPatternControllerBlockEntity;
import appeng.blockentity.crafting.CraftingBlockEntity; import appeng.blockentity.crafting.CraftingBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.content.controller.NetworkPatternControllerBlockEntity;
import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;

View File

@ -1,11 +1,9 @@
package com.extendedae_plus.init; package com.extendedae_plus.init;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.content.wireless.WirelessTransceiverBlock;
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
import appeng.block.crafting.CraftingUnitBlock; import appeng.block.crafting.CraftingUnitBlock;
import appeng.blockentity.crafting.CraftingBlockEntity; import com.extendedae_plus.ExtendedAEPlus;
import appeng.core.definitions.AEBlockEntities; import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
import com.extendedae_plus.content.wireless.WirelessTransceiverBlock;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.material.MapColor;

View File

@ -2,11 +2,11 @@ package com.extendedae_plus.init;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.menu.NetworkPatternControllerMenu; import com.extendedae_plus.menu.NetworkPatternControllerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.world.inventory.MenuType;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
public final class ModMenuTypes { public final class ModMenuTypes {
private ModMenuTypes() {} private ModMenuTypes() {}

View File

@ -1,22 +0,0 @@
package com.extendedae_plus.integration.jei;
import com.extendedae_plus.ExtendedAEPlus;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
import mezz.jei.api.runtime.IJeiRuntime;
import net.minecraft.resources.ResourceLocation;
@JeiPlugin
public class ExtendedAEJeiPlugin implements IModPlugin {
private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "jei_plugin");
@Override
public ResourceLocation getPluginUid() {
return UID;
}
@Override
public void onRuntimeAvailable(IJeiRuntime jeiRuntime) {
JeiRuntimeProxy.setRuntime(jeiRuntime);
}
}

View File

@ -1,177 +0,0 @@
package com.extendedae_plus.integration.jei;
import com.extendedae_plus.mixin.jei.accessor.BookmarkOverlayAccessor;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.ingredients.ITypedIngredient;
import mezz.jei.api.runtime.IBookmarkOverlay;
import mezz.jei.api.runtime.IIngredientListOverlay;
import mezz.jei.api.runtime.IJeiRuntime;
import mezz.jei.gui.bookmarks.BookmarkList;
import mezz.jei.gui.bookmarks.IngredientBookmark;
import mezz.jei.gui.overlay.elements.IElement;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* 线程安全地缓存并访问 JEI Runtime
*/
public final class JeiRuntimeProxy {
private static volatile IJeiRuntime RUNTIME;
private JeiRuntimeProxy() {}
static void setRuntime(IJeiRuntime runtime) {
RUNTIME = runtime;
}
@Nullable
public static IJeiRuntime get() {
return RUNTIME;
}
public static Optional<ITypedIngredient<?>> getIngredientUnderMouse() {
IJeiRuntime rt = RUNTIME;
if (rt == null) return Optional.empty();
IIngredientListOverlay list = rt.getIngredientListOverlay();
if (list != null) {
var ing = list.getIngredientUnderMouse();
if (ing.isPresent()) return ing.map(i -> (ITypedIngredient<?>) i);
}
IBookmarkOverlay bm = rt.getBookmarkOverlay();
if (bm != null) {
var ing = bm.getIngredientUnderMouse();
if (ing.isPresent()) return ing.map(i -> (ITypedIngredient<?>) i);
}
return Optional.empty();
}
/**
* JEI 配方界面区域内基于屏幕坐标查询鼠标下的配料优先物品其次流体
*/
public static Optional<ITypedIngredient<?>> getIngredientUnderMouse(double mouseX, double mouseY) {
IJeiRuntime rt = RUNTIME;
if (rt == null || rt.getRecipesGui() == null) return Optional.empty();
var ingredientManager = rt.getIngredientManager();
// 支持物品通用且所有版本可用如需流体可后续按版本判断再扩展
var item = rt.getRecipesGui().getIngredientUnderMouse(VanillaTypes.ITEM_STACK)
.flatMap(v -> ingredientManager.createTypedIngredient(VanillaTypes.ITEM_STACK, v))
.map(x -> (ITypedIngredient<?>) x);
if (item.isPresent()) return Optional.of(item.get());
return Optional.empty();
}
/**
* 检测 JEI 是否开启了作弊模式给物品
* 使用 JEI 内部开关 JEI 未初始化或异常则返回 false
*/
public static boolean isJeiCheatModeEnabled() {
try {
// 使用完全限定名以避免在源码缺失时的编译依赖问题
return mezz.jei.common.Internal.getClientToggleState().isCheatItemsEnabled();
} catch (Throwable t) {
return false;
}
}
/**
* 将文本写入 JEI 的搜索过滤框
* JEI runtime 不可用则静默返回
*/
public static void setIngredientFilterText(String text) {
IJeiRuntime rt = RUNTIME;
if (rt == null) return;
try {
rt.getIngredientFilter().setFilterText(text == null ? "" : text);
} catch (Throwable ignored) {
// 兼容不同 JEI 版本或在启动阶段尚未就绪
}
}
/**
* 通用获取 JEI 悬浮配料的本地化显示名称适配物品/流体等
* 若无法安全获取则返回空字符串
*/
public static <T> String getTypedIngredientDisplayName(ITypedIngredient<T> typed) {
IJeiRuntime rt = RUNTIME;
if (rt == null || typed == null) return "";
try {
var manager = rt.getIngredientManager();
var helper = manager.getIngredientHelper(typed.getType());
// JEI IIngredientHelper#getDisplayName 返回 Component新版本 String旧版本
// 统一转为字符串使用 toString() 兜底
Object display = helper.getDisplayName(typed.getIngredient());
if (display == null) return "";
// 新版net.minecraft.network.chat.Component
if (display instanceof net.minecraft.network.chat.Component comp) {
String s = comp.getString();
return s == null ? "" : s;
}
String s = display.toString();
return s == null ? "" : s;
} catch (Throwable ignored) {
}
return "";
}
/**
* 获取JEI书签列表
*/
public static List<? extends ITypedIngredient<?>> getBookmarkList() {
IJeiRuntime rt = RUNTIME;
if (rt == null) return Collections.emptyList();
IBookmarkOverlay bookmarkOverlay = rt.getBookmarkOverlay();
if (bookmarkOverlay instanceof BookmarkOverlayAccessor accessor) {
BookmarkList bookmarkList = accessor.eap$getBookmarkList();
return bookmarkList.getElements().stream().map(IElement::getTypedIngredient).toList();
}
return Collections.emptyList();
}
/**
* 将物品添加到 JEI 书签
*/
public static void addBookmark(ItemStack stack) {
IJeiRuntime rt = RUNTIME;
if (rt == null || stack == null || stack.isEmpty()) return;
IBookmarkOverlay overlay = rt.getBookmarkOverlay();
if (overlay instanceof BookmarkOverlayAccessor accessor) {
BookmarkList list = accessor.eap$getBookmarkList();
try {
var typedOpt = rt.getIngredientManager().createTypedIngredient(VanillaTypes.ITEM_STACK, stack);
typedOpt.ifPresent(typed -> {
IngredientBookmark<ItemStack> bookmark = IngredientBookmark.create(typed, rt.getIngredientManager());
list.add(bookmark); // add 内部会自动保存到配置
});
} catch (Throwable ignored) {}
}
}
/**
* JEI 书签移除物品
*/
public static void removeBookmark(ItemStack stack) {
IJeiRuntime rt = RUNTIME;
if (rt == null || stack == null || stack.isEmpty()) return;
IBookmarkOverlay overlay = rt.getBookmarkOverlay();
if (overlay instanceof BookmarkOverlayAccessor accessor) {
BookmarkList list = accessor.eap$getBookmarkList();
try {
var typedOpt = rt.getIngredientManager().createTypedIngredient(VanillaTypes.ITEM_STACK, stack);
typedOpt.ifPresent(typed -> {
IngredientBookmark<ItemStack> bookmark = IngredientBookmark.create(typed, rt.getIngredientManager());
list.remove(bookmark);
});
} catch (Throwable ignored) {}
}
}
}

View File

@ -2,12 +2,12 @@ package com.extendedae_plus.menu;
import com.extendedae_plus.init.ModMenuTypes; import com.extendedae_plus.init.ModMenuTypes;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import org.jetbrains.annotations.Nullable;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
public class NetworkPatternControllerMenu extends AbstractContainerMenu { public class NetworkPatternControllerMenu extends AbstractContainerMenu {
private final BlockPos bePos; private final BlockPos bePos;

View File

@ -1,8 +1,8 @@
package com.extendedae_plus.menu.host; package com.extendedae_plus.menu.host;
import appeng.api.storage.ISubMenuHost;
import appeng.menu.ISubMenu; import appeng.menu.ISubMenu;
import appeng.menu.locator.ItemMenuHostLocator; import appeng.menu.locator.ItemMenuHostLocator;
import appeng.api.storage.ISubMenuHost;
import de.mari_023.ae2wtlib.api.terminal.ItemWT; import de.mari_023.ae2wtlib.api.terminal.ItemWT;
import de.mari_023.ae2wtlib.api.terminal.WTMenuHost; import de.mari_023.ae2wtlib.api.terminal.WTMenuHost;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;

View File

@ -1,8 +1,8 @@
package com.extendedae_plus.menu.host; package com.extendedae_plus.menu.host;
import appeng.items.tools.powered.WirelessTerminalItem;
import appeng.helpers.WirelessTerminalMenuHost;
import appeng.api.storage.ISubMenuHost; import appeng.api.storage.ISubMenuHost;
import appeng.helpers.WirelessTerminalMenuHost;
import appeng.items.tools.powered.WirelessTerminalItem;
import appeng.menu.ISubMenu; import appeng.menu.ISubMenu;
import appeng.menu.locator.ItemMenuHostLocator; import appeng.menu.locator.ItemMenuHostLocator;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;

View File

@ -1,12 +1,12 @@
package com.extendedae_plus.menu.host; package com.extendedae_plus.menu.host;
import appeng.helpers.WirelessTerminalMenuHost; import appeng.helpers.WirelessTerminalMenuHost;
import appeng.menu.ISubMenu;
import appeng.items.tools.powered.WirelessTerminalItem; import appeng.items.tools.powered.WirelessTerminalItem;
import appeng.menu.ISubMenu;
import appeng.menu.locator.ItemMenuHostLocator; import appeng.menu.locator.ItemMenuHostLocator;
import com.extendedae_plus.menu.locator.CuriosItemLocator;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import com.extendedae_plus.menu.locator.CuriosItemLocator;
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler; import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
/** /**

View File

@ -1,5 +1,6 @@
package com.extendedae_plus.mixin; package com.extendedae_plus.mixin;
import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.network.PickFromWirelessC2SPacket; import com.extendedae_plus.network.PickFromWirelessC2SPacket;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.LocalPlayer;
@ -12,6 +13,7 @@ import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -24,19 +26,25 @@ public class PickFromWirelessMixin {
@Shadow public HitResult hitResult; @Shadow public HitResult hitResult;
@Inject(method = "pickBlock", at = @At("HEAD"), cancellable = true) @Inject(method = "pickBlock", at = @At("HEAD"), cancellable = true)
private void eap$pickFromAeWireless(CallbackInfo ci) { private void onPickBlock(CallbackInfo ci) {
if (ModConfig.OVERRIDE_AE2WT_PICKING.getAsBoolean() && eaep$overridePicking())
ci.cancel();
}
@Unique
private boolean eaep$overridePicking() {
if (this.player == null || this.hitResult == null || this.hitResult.getType() != HitResult.Type.BLOCK) { if (this.player == null || this.hitResult == null || this.hitResult.getType() != HitResult.Type.BLOCK) {
return; return false;
} }
// 仅生存模式 // 仅生存模式
GameType type = Minecraft.getInstance().gameMode != null ? Minecraft.getInstance().gameMode.getPlayerMode() : null; GameType type = Minecraft.getInstance().gameMode != null ? Minecraft.getInstance().gameMode.getPlayerMode() : null;
if (type == null || type.isCreative()) { if (type == null || type.isCreative()) {
return; return false;
} }
// 若背包已有该物品让原版逻辑处理将该物品切换到主手 // 若背包已有该物品让原版逻辑处理将该物品切换到主手
BlockHitResult bhr = (BlockHitResult) this.hitResult; BlockHitResult bhr = (BlockHitResult) this.hitResult;
var level = Minecraft.getInstance().level; var level = Minecraft.getInstance().level;
if (level != null) { if (level == null) return false;
try { try {
BlockState state = level.getBlockState(bhr.getBlockPos()); BlockState state = level.getBlockState(bhr.getBlockPos());
if (state != null && !state.isAir()) { if (state != null && !state.isAir()) {
@ -49,21 +57,20 @@ public class PickFromWirelessMixin {
if (!ItemStack.isSameItemSameComponents(picked, this.player.getMainHandItem())) { if (!ItemStack.isSameItemSameComponents(picked, this.player.getMainHandItem())) {
int slot = this.player.getInventory().findSlotMatchingItem(picked); int slot = this.player.getInventory().findSlotMatchingItem(picked);
if (slot != -1) { if (slot != -1) {
return; // 交给原版 pickBlock 处理 return false; // 交给原版 pickBlock 处理
} }
} }
} }
} }
} catch (Throwable t) { } catch (Throwable ignored) {
// 若其它模组导致 getCloneItemStack 出异常放弃拦截保持原版行为确保健壮性 // 若其它模组导致 getCloneItemStack 出异常放弃拦截保持原版行为确保健壮性
return; return false;
}
} }
// 不在客户端检查是否持有无线合成终端由服务端权威校验 Curios 支持以避免整合包环境下的软依赖与槽位问题 // 不在客户端检查是否持有无线合成终端由服务端权威校验 Curios 支持以避免整合包环境下的软依赖与槽位问题
// 背包没有发送到服务端处理 AE2 网络拉取并拦截原版 // 背包没有发送到服务端处理 AE2 网络拉取并拦截原版
Vec3 loc = bhr.getLocation(); Vec3 loc = bhr.getLocation();
PacketDistributor.sendToServer(new PickFromWirelessC2SPacket(bhr.getBlockPos(), bhr.getDirection(), loc)); PacketDistributor.sendToServer(new PickFromWirelessC2SPacket(bhr.getBlockPos(), bhr.getDirection(), loc));
ci.cancel(); return true;
} }
} }

View File

@ -1,14 +1,14 @@
package com.extendedae_plus.mixin.ae2; package com.extendedae_plus.mixin.ae2;
import appeng.crafting.pattern.EncodedPatternItem; import appeng.crafting.pattern.EncodedPatternItem;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component; 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.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.CustomData;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@ -21,7 +21,7 @@ public class EncodedPatternItemMixin {
// 客户端 HoverText 显示样板的编码玩家 // 客户端 HoverText 显示样板的编码玩家
@Inject(method = "appendHoverText", at = @At("TAIL")) @Inject(method = "appendHoverText", at = @At("TAIL"))
public void epp$appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> lines, TooltipFlag advancedTooltips, CallbackInfo ci){ public void epp$appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> lines, TooltipFlag advancedTooltips, CallbackInfo ci){
if (ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()) { if (ModConfig.SHOW_ENCODE_PATTERN_PLAYER.get()) {
var customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); var customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
var tag = customData.copyTag(); var tag = customData.copyTag();
if (tag.contains("encodePlayer")) { if (tag.contains("encodePlayer")) {

View File

@ -2,8 +2,10 @@ package com.extendedae_plus.mixin.ae2.accessor;
import appeng.menu.me.items.PatternEncodingTermMenu; import appeng.menu.me.items.PatternEncodingTermMenu;
import appeng.menu.slot.RestrictedInputSlot; import appeng.menu.slot.RestrictedInputSlot;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(PatternEncodingTermMenu.class) @Mixin(PatternEncodingTermMenu.class)
public interface PatternEncodingTermMenuAccessor { public interface PatternEncodingTermMenuAccessor {
@ -12,4 +14,10 @@ public interface PatternEncodingTermMenuAccessor {
@Accessor("blankPatternSlot") @Accessor("blankPatternSlot")
RestrictedInputSlot eap$getBlankPatternSlot(); RestrictedInputSlot eap$getBlankPatternSlot();
@Invoker("encodePattern")
ItemStack eaep$encodePattern();
@Invoker("isPattern")
boolean eaep$isPattern(ItemStack output);
} }

View File

@ -10,7 +10,7 @@ import appeng.crafting.CraftingTreeProcess;
import appeng.crafting.pattern.AEProcessingPattern; import appeng.crafting.pattern.AEProcessingPattern;
import appeng.me.service.CraftingService; import appeng.me.service.CraftingService;
import com.extendedae_plus.api.SmartDoublingAwarePattern; import com.extendedae_plus.api.SmartDoublingAwarePattern;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.content.ScaledProcessingPattern; import com.extendedae_plus.content.ScaledProcessingPattern;
import com.extendedae_plus.util.PatternScaler; import com.extendedae_plus.util.PatternScaler;
import com.extendedae_plus.util.RequestedAmountHolder; import com.extendedae_plus.util.RequestedAmountHolder;
@ -58,7 +58,7 @@ public abstract class CraftingTreeProcessMixin {
// 根据配置决定是否在 provider 间轮询分配请求量默认开启 // 根据配置决定是否在 provider 间轮询分配请求量默认开启
long perProvider = 1L; long perProvider = 1L;
if (!ModConfigs.PROVIDER_ROUND_ROBIN_ENABLE.get()) { if (!ModConfig.PROVIDER_ROUND_ROBIN_ENABLE.get()) {
// 关闭轮询直接使用完整请求量不需要查询 provider 列表 // 关闭轮询直接使用完整请求量不需要查询 provider 列表
perProvider = requested; perProvider = requested;
if (perProvider <= 0) perProvider = 1L; if (perProvider <= 0) perProvider = 1L;

View File

@ -17,7 +17,6 @@ import com.extendedae_plus.api.ExPatternPageAccessor;
import com.extendedae_plus.content.ClientPatternHighlightStore; import com.extendedae_plus.content.ClientPatternHighlightStore;
import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket; import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket;
import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket; import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket;
import com.extendedae_plus.network.ModNetwork;
import com.extendedae_plus.util.GuiUtil; import com.extendedae_plus.util.GuiUtil;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;

View File

@ -6,7 +6,7 @@ import appeng.client.gui.me.items.PatternEncodingTermScreen;
import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.style.WidgetStyle; import appeng.client.gui.style.WidgetStyle;
import appeng.client.gui.widgets.IconButton; import appeng.client.gui.widgets.IconButton;
import appeng.menu.AEBaseMenu; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor; import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
import com.extendedae_plus.mixin.accessor.ScreenAccessor; import com.extendedae_plus.mixin.accessor.ScreenAccessor;
import com.extendedae_plus.mixin.ae2.accessor.AEBaseScreenAccessor; import com.extendedae_plus.mixin.ae2.accessor.AEBaseScreenAccessor;
@ -28,7 +28,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
* 通过解析 AE2 样式中 encodePattern 的坐标将按钮放在其左侧紧挨位置 * 通过解析 AE2 样式中 encodePattern 的坐标将按钮放在其左侧紧挨位置
*/ */
@Mixin(value = AEBaseScreen.class, remap = false) @Mixin(value = AEBaseScreen.class, remap = false)
public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> { public abstract class PatternEncodingTermScreenMixin {
@Unique @Unique
private IconButton eap$uploadBtn; private IconButton eap$uploadBtn;
@ -36,9 +36,9 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
@Inject(method = "init", at = @At("TAIL"), remap = false) @Inject(method = "init", at = @At("TAIL"), remap = false)
private void eap$addUploadButton(CallbackInfo ci) { private void eap$addUploadButton(CallbackInfo ci) {
// 仅在图样编码终端界面中添加按钮 // 仅在图样编码终端界面中添加按钮
if (!(((Object) this) instanceof PatternEncodingTermScreen)) { if (!(((Object) this) instanceof PatternEncodingTermScreen &&
ModConfig.INDEPENDENT_UPLOADING_BUTTON.getAsBoolean()))
return; return;
}
// 复用已存在的按钮实例避免重复创建 // 复用已存在的按钮实例避免重复创建
if (eap$uploadBtn == null) { if (eap$uploadBtn == null) {
eap$uploadBtn = new IconButton(btn -> PacketDistributor eap$uploadBtn = new IconButton(btn -> PacketDistributor
@ -98,12 +98,12 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
// 解析 encodePattern 的样式位置 // 解析 encodePattern 的样式位置
try { try {
ScreenStyle style = ((AEBaseScreenAccessor<?>) (Object) this).eap$getStyle(); ScreenStyle style = ((AEBaseScreenAccessor<?>) this).eap$getStyle();
WidgetStyle ws = style.getWidget("encodePattern"); WidgetStyle ws = style.getWidget("encodePattern");
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos(); int leftPos = ((AbstractContainerScreenAccessor<?>) this).eap$getLeftPos();
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos(); int topPos = ((AbstractContainerScreenAccessor<?>) this).eap$getTopPos();
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth(); int imageWidth = ((AbstractContainerScreenAccessor<?>) this).eap$getImageWidth();
int imageHeight = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageHeight(); int imageHeight = ((AbstractContainerScreenAccessor<?>) this).eap$getImageHeight();
Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight); Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight);
var pos = ws.resolve(bounds); var pos = ws.resolve(bounds);
int baseW = ws.getWidth() > 0 ? ws.getWidth() : 12; int baseW = ws.getWidth() > 0 ? ws.getWidth() : 12;
@ -120,15 +120,15 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
// 回退放在界面右侧大致位置避免不可见 // 回退放在界面右侧大致位置避免不可见
eap$uploadBtn.setWidth(12); eap$uploadBtn.setWidth(12);
eap$uploadBtn.setHeight(12); eap$uploadBtn.setHeight(12);
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos(); int leftPos = ((AbstractContainerScreenAccessor<?>) this).eap$getLeftPos();
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos(); int topPos = ((AbstractContainerScreenAccessor<?>) this).eap$getTopPos();
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth(); int imageWidth = ((AbstractContainerScreenAccessor<?>) this).eap$getImageWidth();
eap$uploadBtn.setX(leftPos + imageWidth - 12 - 8 + 2); // 向右微移 2px eap$uploadBtn.setX(leftPos + imageWidth - 12 - 8 + 2); // 向右微移 2px
eap$uploadBtn.setY(topPos + 88); eap$uploadBtn.setY(topPos + 88);
} }
// 直接向 renderables / children 列表添加避免依赖受保护方法 // 直接向 renderables / children 列表添加避免依赖受保护方法
var accessor = (ScreenAccessor) (Object) this; var accessor = (ScreenAccessor) this;
var renderables = accessor.eap$getRenderables(); var renderables = accessor.eap$getRenderables();
var children = accessor.eap$getChildren(); var children = accessor.eap$getChildren();
if (!renderables.contains(eap$uploadBtn)) { if (!renderables.contains(eap$uploadBtn)) {
@ -141,22 +141,22 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
@Inject(method = "containerTick", at = @At("TAIL"), remap = false) @Inject(method = "containerTick", at = @At("TAIL"), remap = false)
private void eap$ensureUploadButton(CallbackInfo ci) { private void eap$ensureUploadButton(CallbackInfo ci) {
if (!(((Object) this) instanceof PatternEncodingTermScreen)) { if (!(((Object) this) instanceof PatternEncodingTermScreen &&
ModConfig.INDEPENDENT_UPLOADING_BUTTON.getAsBoolean()))
return; return;
}
if (eap$uploadBtn == null) { if (eap$uploadBtn == null) {
return; return;
} }
var renderables2 = ((ScreenAccessor) (Object) this).eap$getRenderables(); var renderables2 = ((ScreenAccessor) this).eap$getRenderables();
if (!renderables2.contains(eap$uploadBtn)) { if (!renderables2.contains(eap$uploadBtn)) {
// 被其它模组清空/替换后重新计算一次位置并补回 // 被其它模组清空/替换后重新计算一次位置并补回
try { try {
ScreenStyle style = ((AEBaseScreenAccessor<?>) (Object) this).eap$getStyle(); ScreenStyle style = ((AEBaseScreenAccessor<?>) this).eap$getStyle();
WidgetStyle ws = style.getWidget("encodePattern"); WidgetStyle ws = style.getWidget("encodePattern");
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos(); int leftPos = ((AbstractContainerScreenAccessor<?>) this).eap$getLeftPos();
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos(); int topPos = ((AbstractContainerScreenAccessor<?>) this).eap$getTopPos();
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth(); int imageWidth = ((AbstractContainerScreenAccessor<?>) this).eap$getImageWidth();
int imageHeight = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageHeight(); int imageHeight = ((AbstractContainerScreenAccessor<?>) this).eap$getImageHeight();
Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight); Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight);
var pos = ws.resolve(bounds); var pos = ws.resolve(bounds);
int baseW = ws.getWidth() > 0 ? ws.getWidth() : 16; int baseW = ws.getWidth() > 0 ? ws.getWidth() : 16;
@ -168,15 +168,15 @@ public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
eap$uploadBtn.setX(pos.getX() - targetW); // 原为 -targetW - 2再右移 2px eap$uploadBtn.setX(pos.getX() - targetW); // 原为 -targetW - 2再右移 2px
eap$uploadBtn.setY(pos.getY()); eap$uploadBtn.setY(pos.getY());
} catch (Throwable t) { } catch (Throwable t) {
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos(); int leftPos = ((AbstractContainerScreenAccessor<?>) this).eap$getLeftPos();
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos(); int topPos = ((AbstractContainerScreenAccessor<?>) this).eap$getTopPos();
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth(); int imageWidth = ((AbstractContainerScreenAccessor<?>) this).eap$getImageWidth();
eap$uploadBtn.setWidth(12); eap$uploadBtn.setWidth(12);
eap$uploadBtn.setHeight(12); eap$uploadBtn.setHeight(12);
eap$uploadBtn.setX(leftPos + imageWidth - 12 - 8 + 2); eap$uploadBtn.setX(leftPos + imageWidth - 12 - 8 + 2);
eap$uploadBtn.setY(topPos + 88); eap$uploadBtn.setY(topPos + 88);
} }
var accessor2 = (ScreenAccessor) (Object) this; var accessor2 = (ScreenAccessor) this;
var r = accessor2.eap$getRenderables(); var r = accessor2.eap$getRenderables();
var c = accessor2.eap$getChildren(); var c = accessor2.eap$getChildren();
if (!r.contains(eap$uploadBtn)) { if (!r.contains(eap$uploadBtn)) {

View File

@ -8,7 +8,6 @@ import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderTarget; import appeng.helpers.patternprovider.PatternProviderTarget;
import com.extendedae_plus.api.AdvancedBlockingHolder; import com.extendedae_plus.api.AdvancedBlockingHolder;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;

View File

@ -7,7 +7,6 @@ import com.extendedae_plus.api.SmartDoublingAwarePattern;
import com.extendedae_plus.api.SmartDoublingHolder; import com.extendedae_plus.api.SmartDoublingHolder;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor; import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;

View File

@ -7,12 +7,12 @@ import appeng.parts.encoding.EncodingMode;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil; import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import com.glodblock.github.glodium.network.packet.sync.ActionMap; 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.IActionHolder;
import net.minecraft.core.component.DataComponents;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; 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 net.minecraft.world.item.component.CustomData;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
@ -21,9 +21,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
import java.util.function.Consumer;
/** /**
* AE2 PatternEncodingTermMenu 增加一个通用动作持有者实现接收 EPP CGenericPacket 动作 * AE2 PatternEncodingTermMenu 增加一个通用动作持有者实现接收 EPP CGenericPacket 动作
* 注册动作 "upload_to_matrix"仅上传合成图样 ExtendedAE 装配矩阵 * 注册动作 "upload_to_matrix"仅上传合成图样 ExtendedAE 装配矩阵

View File

@ -3,8 +3,10 @@ package com.extendedae_plus.mixin.ae2.menu;
import appeng.menu.me.crafting.CraftConfirmMenu; import appeng.menu.me.crafting.CraftConfirmMenu;
import appeng.menu.me.crafting.CraftingPlanSummary; import appeng.menu.me.crafting.CraftingPlanSummary;
import appeng.menu.me.crafting.CraftingPlanSummaryEntry; import appeng.menu.me.crafting.CraftingPlanSummaryEntry;
import com.extendedae_plus.integration.jei.JeiRuntimeProxy; import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.runtime.EmiFavorites;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.world.item.crafting.Ingredient;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@ -46,7 +48,8 @@ public class CraftConfirmMenuGoBackMixin {
var display = entry.getWhat().wrapForDisplayOrFilter(); var display = entry.getWhat().wrapForDisplayOrFilter();
if (display != null && !display.isEmpty()) { if (display != null && !display.isEmpty()) {
// wrapForDisplayOrFilter 返回 ItemStack // wrapForDisplayOrFilter 返回 ItemStack
JeiRuntimeProxy.addBookmark(display); // JeiRuntimeProxy.addBookmark(display);
EmiFavorites.addFavorite(EmiIngredient.of(Ingredient.of(display)));
} }
} catch (Throwable ignored) {} } catch (Throwable ignored) {}
} }

View File

@ -11,9 +11,15 @@ import appeng.helpers.IPatternTerminalMenuHost;
import appeng.menu.me.common.MEStorageMenu; import appeng.menu.me.common.MEStorageMenu;
import appeng.menu.me.items.PatternEncodingTermMenu; import appeng.menu.me.items.PatternEncodingTermMenu;
import appeng.menu.slot.RestrictedInputSlot; import appeng.menu.slot.RestrictedInputSlot;
import appeng.parts.encoding.EncodingMode;
import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.mixin.ae2.accessor.MEStorageMenuAccessor; import com.extendedae_plus.mixin.ae2.accessor.MEStorageMenuAccessor;
import com.extendedae_plus.network.C2SPacketEncodeFinished;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.neoforged.neoforge.network.PacketDistributor;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
@ -23,7 +29,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PatternEncodingTermMenu.class) @Mixin(PatternEncodingTermMenu.class)
public abstract class PatternEncodingTermMenuMixin { public abstract class PatternEncodingTermMenuMixin {
// 防止重复执行 // 防止重复执行
@Unique @Unique
private boolean eap$blankAutoFilled = false; private boolean eap$blankAutoFilled = false;
@ -31,6 +36,9 @@ public abstract class PatternEncodingTermMenuMixin {
@Shadow @Shadow
private RestrictedInputSlot blankPatternSlot; private RestrictedInputSlot blankPatternSlot;
@Shadow
public EncodingMode mode;
@Unique @Unique
private void eap$tryFill(IPatternTerminalMenuHost host, Inventory ip) { private void eap$tryFill(IPatternTerminalMenuHost host, Inventory ip) {
try { try {
@ -40,10 +48,10 @@ public abstract class PatternEncodingTermMenuMixin {
return; return;
} }
// 必须可与网络交互 // 必须可与网络交互
var acc = (MEStorageMenuAccessor) (Object) ((MEStorageMenu) self); var acc = (MEStorageMenuAccessor) self;
MEStorage storage = acc.getStorage(); MEStorage storage = acc.getStorage();
IEnergySource power = acc.getEnergySource(); IEnergySource power = acc.getEnergySource();
boolean canInteract = storage != null && power != null && ((MEStorageMenu) self).getLinkStatus().connected(); boolean canInteract = storage != null && power != null && self.getLinkStatus().connected();
if (!canInteract) { if (!canInteract) {
return; return;
} }
@ -149,4 +157,12 @@ public abstract class PatternEncodingTermMenuMixin {
} }
this.eap$blankAutoFilled = true; this.eap$blankAutoFilled = true;
} }
@Inject(method = "encode", at = @At("TAIL"))
private void eaep$onEncode(CallbackInfo ci) {
if (ModConfig.INDEPENDENT_UPLOADING_BUTTON.getAsBoolean()) return;
if (!Screen.hasShiftDown()) return;
var self = (PatternEncodingTermMenu) (Object) this;
PacketDistributor.sendToPlayer((ServerPlayer) self.getPlayer(), C2SPacketEncodeFinished.INSTANCE);
}
} }

View File

@ -1,15 +1,11 @@
package com.extendedae_plus.mixin.ae2.menu; package com.extendedae_plus.mixin.ae2.menu;
import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.menu.AEBaseMenu; import appeng.menu.AEBaseMenu;
import appeng.menu.guisync.GuiSync; import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu; import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.AdvancedBlockingHolder; import com.extendedae_plus.api.AdvancedBlockingHolder;
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync; import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;

View File

@ -6,8 +6,6 @@ import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu; import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.PatternProviderMenuDoublingSync; import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
import com.extendedae_plus.api.SmartDoublingHolder; import com.extendedae_plus.api.SmartDoublingHolder;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;

View File

@ -1,22 +0,0 @@
package com.extendedae_plus.mixin.ae2WTlib;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* 为通用无线样板访问终端AE2WTlib 集成容器注册通用动作CGenericPacket 分发
*/
@Pseudo
@Mixin(targets = "com.glodblock.github.extendedae.xmod.wt.ContainerUWirelessExPAT", remap = false)
public abstract class ContainerUWirelessExPatternTerminalMixin {
// 1.21 环境下Glodium IActionHolder 已被移除改为 no-op 保留占位以便未来扩展
// 明确目标构造签名<init>(int, Inventory, HostUWirelessExPAT)
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Ljava/lang/Object;)V", at = @At("TAIL"), remap = false)
private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, Object host, CallbackInfo ci) {
// no-op
}
}

View File

@ -0,0 +1,30 @@
package com.extendedae_plus.mixin.emi;
import appeng.integration.modules.emi.EmiEncodePatternHandler;
import appeng.integration.modules.itemlists.EncodingHelper;
import appeng.menu.AEBaseMenu;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import dev.emi.emi.api.recipe.EmiRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
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;
@Mixin(value = EmiEncodePatternHandler.class, remap = false)
public abstract class MixinEncodePatternTransfer {
@Inject(method = "transferRecipe(Lappeng/menu/AEBaseMenu;Lnet/minecraft/world/item/crafting/RecipeHolder;Ldev/emi/emi/api/recipe/EmiRecipe;Z)Lappeng/integration/modules/emi/AbstractRecipeHandler$Result;",
at = @At("HEAD"), remap = false, require = 0)
private static void onTransfer(AEBaseMenu menu, RecipeHolder<?> holder,
EmiRecipe emiRecipe, boolean doTransfer, CallbackInfoReturnable<?> cir) {
if (!doTransfer) return;
var recipe = holder != null ? holder.value() : null;
// 技术力不够,忍痛不兼容gtceu(
// 对不起老牛😭
if (recipe == null) return;
if (EncodingHelper.isSupportedCraftingRecipe(recipe)) return;
String name = ExtendedAEPatternUploadUtil.mapRecipeTypeToSearchKey(recipe);
if (name == null || name.isBlank()) return;
ExtendedAEPatternUploadUtil.setLastProcessingName(name);
}
}

View File

@ -1,4 +1,4 @@
package com.extendedae_plus.mixin.jei; package com.extendedae_plus.mixin.emi;
import appeng.api.stacks.AEFluidKey; import appeng.api.stacks.AEFluidKey;
import appeng.api.stacks.AEItemKey; import appeng.api.stacks.AEItemKey;
@ -6,32 +6,31 @@ import appeng.api.stacks.AEKey;
import appeng.integration.modules.itemlists.EncodingHelper; import appeng.integration.modules.itemlists.EncodingHelper;
import appeng.menu.me.common.GridInventoryEntry; import appeng.menu.me.common.GridInventoryEntry;
import appeng.menu.me.common.MEStorageMenu; import appeng.menu.me.common.MEStorageMenu;
import com.extendedae_plus.integration.jei.JeiRuntimeProxy; import dev.emi.emi.runtime.EmiFavorites;
import mezz.jei.api.constants.VanillaTypes; import net.minecraft.world.item.Item;
import mezz.jei.api.neoforge.NeoForgeTypes; import net.minecraft.world.level.material.Fluid;
import mezz.jei.api.ingredients.ITypedIngredient;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@Mixin(EncodingHelper.class) @Mixin(EncodingHelper.class)
public class EncodingHelperMixin { public class MixinEncodingHelper {
// 客户端注入优先使用JEI书签的物品流体 // 客户端注入优先使用JEI书签的物品流体
@Inject(method = "getIngredientPriorities", at = @At("TAIL"), cancellable = true, remap = false) @Inject(method = "getIngredientPriorities", at = @At("TAIL"), cancellable = true, remap = false)
private static void epp$addJeiIngredientPriorities(MEStorageMenu menu, Comparator<GridInventoryEntry> comparator, CallbackInfoReturnable<Map<AEKey, Integer>> cir){ private static void epp$addJeiIngredientPriorities(MEStorageMenu menu, Comparator<GridInventoryEntry> comparator, CallbackInfoReturnable<Map<AEKey, Integer>> cir){
Map<AEKey, Integer> result = cir.getReturnValue(); Map<AEKey, Integer> result = cir.getReturnValue();
AtomicInteger index = new AtomicInteger(Integer.MAX_VALUE); AtomicInteger index = new AtomicInteger(Integer.MAX_VALUE);
List<? extends ITypedIngredient<?>> list = JeiRuntimeProxy.getBookmarkList(); EmiFavorites.favorites.forEach(favorite -> {
for (ITypedIngredient<?> ingredient : list) { Object stack = favorite.getEmiStacks().getFirst().getKey();
ingredient.getIngredient(VanillaTypes.ITEM_STACK).ifPresent(itemStack -> result.put(AEItemKey.of(itemStack), index.getAndDecrement())); if (stack instanceof Item item) result.put(AEItemKey.of(item), index.getAndDecrement());
ingredient.getIngredient(NeoForgeTypes.FLUID_STACK).ifPresent(fluidStack -> result.put(AEFluidKey.of(fluidStack), index.getAndDecrement())); else if (stack instanceof Fluid fluid) result.put(AEFluidKey.of(fluid), index.getAndDecrement());
} });
cir.setReturnValue(result); cir.setReturnValue(result);
} }
} }

View File

@ -7,14 +7,13 @@ import appeng.menu.SlotSemantics;
import appeng.menu.slot.AppEngSlot; import appeng.menu.slot.AppEngSlot;
import com.extendedae_plus.NewIcon; import com.extendedae_plus.NewIcon;
import com.extendedae_plus.api.ExPatternButtonsAccessor; import com.extendedae_plus.api.ExPatternButtonsAccessor;
import com.extendedae_plus.api.ExPatternPageAccessor; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.network.ScalePatternsC2SPacket;
import com.glodblock.github.extendedae.client.button.ActionEPPButton; import com.glodblock.github.extendedae.client.button.ActionEPPButton;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import com.glodblock.github.extendedae.container.ContainerExPatternProvider; import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import com.extendedae_plus.network.ScalePatternsC2SPacket; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
@ -66,7 +65,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
private int getMaxPage() { private int getMaxPage() {
// 优先使用配置倍数 // 优先使用配置倍数
try { try {
int cfg = ModConfigs.PAGE_MULTIPLIER.get(); int cfg = ModConfig.PAGE_MULTIPLIER.get();
if (cfg > 1) return cfg; if (cfg > 1) return cfg;
} catch (Throwable ignored) {} } catch (Throwable ignored) {}
try { try {
@ -125,7 +124,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
// 计算并下发 maxPage配置优先其次按槽位总数计算 // 计算并下发 maxPage配置优先其次按槽位总数计算
int totalSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size(); int totalSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size();
int cfgPages = 1; int cfgPages = 1;
try { cfgPages = Math.max(1, ModConfigs.PAGE_MULTIPLIER.get()); } catch (Throwable ignored) {} try { cfgPages = Math.max(1, ModConfig.PAGE_MULTIPLIER.get()); } catch (Throwable ignored) {}
int calcPages = Math.max(1, (int) Math.ceil(totalSlots / (double) SLOTS_PER_PAGE)); int calcPages = Math.max(1, (int) Math.ceil(totalSlots / (double) SLOTS_PER_PAGE));
int desiredMaxPage = Math.max(cfgPages, calcPages); int desiredMaxPage = Math.max(cfgPages, calcPages);
LOGGER.info("[EAP] GuiExPatternProvider init: totalSlots={}, cfgPages={}, calcPages={}, desiredMaxPage={}", totalSlots, cfgPages, calcPages, desiredMaxPage); LOGGER.info("[EAP] GuiExPatternProvider init: totalSlots={}, cfgPages={}, calcPages={}, desiredMaxPage={}", totalSlots, cfgPages, calcPages, desiredMaxPage);

View File

@ -5,10 +5,9 @@ import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.Icon; import appeng.client.gui.Icon;
import appeng.client.gui.me.patternaccess.PatternContainerRecord; import appeng.client.gui.me.patternaccess.PatternContainerRecord;
import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.widgets.AETextField;
import appeng.client.gui.widgets.IconButton; import appeng.client.gui.widgets.IconButton;
import appeng.menu.AEBaseMenu; import appeng.menu.AEBaseMenu;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor; import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor;
import com.extendedae_plus.network.OpenProviderUiC2SPacket; import com.extendedae_plus.network.OpenProviderUiC2SPacket;
import com.extendedae_plus.util.GuiUtil; import com.extendedae_plus.util.GuiUtil;
@ -22,7 +21,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -32,20 +30,14 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 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.lang.reflect.Method;
import java.util.*;
@Pseudo @Pseudo
@Mixin(value = GuiExPatternTerminal.class, remap = false) @Mixin(value = GuiExPatternTerminal.class, remap = false)
@ -141,6 +133,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
ItemStack itemToUpload = this.minecraft.player.getInventory().getItem(playerSlotIndex); ItemStack itemToUpload = this.minecraft.player.getInventory().getItem(playerSlotIndex);
if (!itemToUpload.isEmpty() && PatternDetailsHelper.isEncodedPattern(itemToUpload)) { if (!itemToUpload.isEmpty() && PatternDetailsHelper.isEncodedPattern(itemToUpload)) {
// 什么逆天ide的中文语法检查(
// 改用我们自己的网络包直接将玩家槽位 选择的供应器ID发送到服务器 // 改用我们自己的网络包直接将玩家槽位 选择的供应器ID发送到服务器
try { try {
PacketDistributor.sendToServer(new com.extendedae_plus.network.UploadInventoryPatternToProviderC2SPacket( PacketDistributor.sendToServer(new com.extendedae_plus.network.UploadInventoryPatternToProviderC2SPacket(
@ -245,14 +238,6 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
} }
} }
/**
* 重置当前选择的样板供应器ID
*/
@Unique
public void resetCurrentlyChoicePatternProvider() {
this.eap$currentlyChoicePatterProvider = -1;
}
@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, require = 0) @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, require = 0)
private void injectConstructor(com.glodblock.github.extendedae.container.ContainerExPatternTerminal menu, private void injectConstructor(com.glodblock.github.extendedae.container.ContainerExPatternTerminal menu,
Inventory playerInventory, Inventory playerInventory,
@ -261,7 +246,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
CallbackInfo ci) { CallbackInfo ci) {
// 根据配置初始化默认显示/隐藏状态 // 根据配置初始化默认显示/隐藏状态
try { try {
this.eap$showSlots = ModConfigs.PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT.get(); this.eap$showSlots = ModConfig.PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT.get();
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
// 创建切换槽位显示的按钮 // 创建切换槽位显示的按钮

View File

@ -1,6 +1,6 @@
package com.extendedae_plus.mixin.extendedae.common; package com.extendedae_plus.mixin.extendedae.common;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.glodblock.github.extendedae.common.parts.PartExPatternProvider; import com.glodblock.github.extendedae.common.parts.PartExPatternProvider;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Pseudo;
@ -20,7 +20,7 @@ public abstract class PartExPatternProviderMixin {
index = 2 index = 2
) )
private int eap$multiplyCapacity(int original) { private int eap$multiplyCapacity(int original) {
int mult = ModConfigs.PAGE_MULTIPLIER.get(); int mult = ModConfig.PAGE_MULTIPLIER.get();
if (mult < 1) mult = 1; if (mult < 1) mult = 1;
if (mult > 64) mult = 64; if (mult > 64) mult = 64;
return Math.max(1, original) * mult; return Math.max(1, original) * mult;

View File

@ -1,6 +1,6 @@
package com.extendedae_plus.mixin.extendedae.common; package com.extendedae_plus.mixin.extendedae.common;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.glodblock.github.extendedae.common.tileentities.TileExPatternProvider; import com.glodblock.github.extendedae.common.tileentities.TileExPatternProvider;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -18,7 +18,7 @@ public abstract class TileExPatternProviderMixin {
index = 2 index = 2
) )
private int eap$multiplyCapacity(int original) { private int eap$multiplyCapacity(int original) {
int mult = ModConfigs.PAGE_MULTIPLIER.get(); int mult = ModConfig.PAGE_MULTIPLIER.get();
if (mult < 1) mult = 1; if (mult < 1) mult = 1;
if (mult > 64) mult = 64; if (mult > 64) mult = 64;
return Math.max(1, original) * mult; return Math.max(1, original) * mult;

View File

@ -13,7 +13,6 @@ import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;

View File

@ -1,16 +1,14 @@
package com.extendedae_plus.mixin.hooks; package com.extendedae_plus.mixin.hooks;
import com.extendedae_plus.hooks.BuiltInModelHooks;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.resources.ResourceLocation;
import com.extendedae_plus.hooks.BuiltInModelHooks;
/** /**
* 复制 MAE2/AE2 的做法在模型加载时优先查询我们的内置模型表 * 复制 MAE2/AE2 的做法在模型加载时优先查询我们的内置模型表
* 若命中则缓存并阻止继续查找 JSON 模型 * 若命中则缓存并阻止继续查找 JSON 模型

View File

@ -1,49 +0,0 @@
package com.extendedae_plus.mixin.jei;
import appeng.integration.modules.itemlists.EncodingHelper;
import appeng.menu.me.items.PatternEncodingTermMenu;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
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 tamaized.ae2jeiintegration.integration.modules.jei.transfer.EncodePatternTransferHandler;
/**
* 针对 AE2 JEI Integration 的转移处理器在点击 JEI "+" 将配方填入编码终端时
* 捕获处理配方并记录一个可用于搜索的关键字以便 ProviderSelectScreen 自动预填搜索框
*/
@Mixin(value = EncodePatternTransferHandler.class, remap = false)
public abstract class AE2JeiEncodePatternTransferHandlerMixin<T extends PatternEncodingTermMenu> {
@Inject(method = "transferRecipe", at = @At("HEAD"), require = 0, remap = false)
private void extendedae_plus$captureProcessingName(T menu,
Object recipeBase,
IRecipeSlotsView slotsView,
Player player,
boolean maxTransfer,
boolean doTransfer,
CallbackInfoReturnable<mezz.jei.api.recipe.transfer.IRecipeTransferError> cir) {
if (!doTransfer) return;
String name = null;
Recipe<?> recipe = null;
if (recipeBase instanceof RecipeHolder<?> holder) {
recipe = holder.value();
}
if (recipe != null) {
// 仅记录处理配方 3x3 合成
if (EncodingHelper.isSupportedCraftingRecipe(recipe)) return;
name = ExtendedAEPatternUploadUtil.mapRecipeTypeToSearchKey(recipe);
} else {
// 非原版 Recipe<?> 的显示尝试从 recipeBase 类名/包名推导关键词
name = ExtendedAEPatternUploadUtil.deriveSearchKeyFromUnknownRecipe(recipeBase);
}
if (name != null && !name.isBlank()) {
ExtendedAEPatternUploadUtil.setLastProcessingName(name);
}
}
}

View File

@ -1,42 +0,0 @@
package com.extendedae_plus.mixin.jei;
import appeng.integration.modules.itemlists.EncodingHelper;
import appeng.integration.modules.rei.transfer.EncodePatternTransferHandler;
import appeng.menu.me.items.PatternEncodingTermMenu;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
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 me.shedaniel.rei.api.common.display.Display;
/**
* 捕获通过 JEI 点击 + 填充到样板编码终端的处理配方并记录其工艺名称烧炼
*/
@Mixin(value = EncodePatternTransferHandler.class, remap = false)
public abstract class EncodePatternTransferHandlerMixin {
@Inject(method = "transferRecipe", at = @At("HEAD"), require = 0, remap = false)
private void extendedae_plus$captureProcessingName(PatternEncodingTermMenu menu,
RecipeHolder<?> holder,
Display display,
boolean doTransfer,
CallbackInfoReturnable<me.shedaniel.rei.api.client.registry.transfer.TransferHandler.Result> cir) {
if (!doTransfer) return;
String name = null;
Recipe<?> recipe = holder != null ? holder.value() : null;
if (recipe != null) {
// 仅记录处理配方 3x3 合成
if (EncodingHelper.isSupportedCraftingRecipe(recipe)) return;
name = ExtendedAEPatternUploadUtil.mapRecipeTypeToSearchKey(recipe);
} else {
// 非原版 Recipe<?> 的显示尝试从 display 类名/包名推导关键词
name = ExtendedAEPatternUploadUtil.deriveSearchKeyFromUnknownRecipe(display);
}
if (name != null && !name.isBlank()) {
ExtendedAEPatternUploadUtil.setLastProcessingName(name);
}
}
}

View File

@ -1,12 +0,0 @@
package com.extendedae_plus.mixin.jei.accessor;
import mezz.jei.gui.bookmarks.BookmarkList;
import mezz.jei.gui.overlay.bookmarks.BookmarkOverlay;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(BookmarkOverlay.class)
public interface BookmarkOverlayAccessor {
@Accessor("bookmarkList")
BookmarkList eap$getBookmarkList();
}

View File

@ -0,0 +1,27 @@
package com.extendedae_plus.network;
import com.extendedae_plus.ExtendedAEPlus;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public record C2SPacketEncodeFinished() implements CustomPacketPayload {
public static final Type<C2SPacketEncodeFinished> TYPE = new Type<>(
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "encode_finished"));
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public static final C2SPacketEncodeFinished INSTANCE = new C2SPacketEncodeFinished();
public static final StreamCodec<RegistryFriendlyByteBuf, C2SPacketEncodeFinished> STREAM_CODEC = StreamCodec.unit(INSTANCE);
public static void handle(final C2SPacketEncodeFinished packet, final IPayloadContext context) {
if (context.player().level().isClientSide) PacketDistributor.sendToServer(RequestProvidersListC2SPacket.INSTANCE);
}
}

View File

@ -2,7 +2,6 @@ package com.extendedae_plus.network;
import appeng.api.crafting.IPatternDetails; import appeng.api.crafting.IPatternDetails;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
import appeng.api.stacks.AEKey; import appeng.api.stacks.AEKey;
import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogic;
@ -18,12 +17,7 @@ import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; 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.MenuProvider;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext;
import java.util.Collection; import java.util.Collection;

View File

@ -17,13 +17,12 @@ import com.glodblock.github.extendedae.util.FCClientUtil;
import com.glodblock.github.glodium.util.GlodUtil; import com.glodblock.github.glodium.util.GlodUtil;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;

View File

@ -3,6 +3,7 @@ package com.extendedae_plus.network;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.config.YesNo; import appeng.api.config.YesNo;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IInWorldGridNodeHost;
import appeng.blockentity.crafting.PatternProviderBlockEntity; import appeng.blockentity.crafting.PatternProviderBlockEntity;
import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.helpers.patternprovider.PatternProviderLogicHost;
@ -10,18 +11,17 @@ import appeng.parts.crafting.PatternProviderPart;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.api.AdvancedBlockingHolder; import com.extendedae_plus.api.AdvancedBlockingHolder;
import com.extendedae_plus.api.SmartDoublingHolder; import com.extendedae_plus.api.SmartDoublingHolder;
import appeng.api.networking.IInWorldGridNodeHost;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext;
import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
/** /**
* C2S全网批量切换样板供应器的三种模式 * C2S全网批量切换样板供应器的三种模式

View File

@ -1,7 +1,7 @@
package com.extendedae_plus.network; package com.extendedae_plus.network;
import appeng.menu.implementations.InterfaceMenu;
import appeng.api.stacks.GenericStack; import appeng.api.stacks.GenericStack;
import appeng.menu.implementations.InterfaceMenu;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;

View File

@ -23,14 +23,18 @@ public class ModNetwork {
registrar.playToServer(UploadEncodedPatternToProviderC2SPacket.TYPE, UploadEncodedPatternToProviderC2SPacket.STREAM_CODEC, UploadEncodedPatternToProviderC2SPacket::handle); registrar.playToServer(UploadEncodedPatternToProviderC2SPacket.TYPE, UploadEncodedPatternToProviderC2SPacket.STREAM_CODEC, UploadEncodedPatternToProviderC2SPacket::handle);
registrar.playToServer(UploadInventoryPatternToProviderC2SPacket.TYPE, UploadInventoryPatternToProviderC2SPacket.STREAM_CODEC, UploadInventoryPatternToProviderC2SPacket::handle); registrar.playToServer(UploadInventoryPatternToProviderC2SPacket.TYPE, UploadInventoryPatternToProviderC2SPacket.STREAM_CODEC, UploadInventoryPatternToProviderC2SPacket::handle);
// 新增JEI 中键打开合成界面 & 无线终端拾取方块物品 // 新增JEI 中键打开合成界面 & 无线终端拾取方块物品
registrar.playToServer(com.extendedae_plus.network.OpenCraftFromJeiC2SPacket.TYPE, registrar.playToServer(OpenCraftFromJeiC2SPacket.TYPE,
com.extendedae_plus.network.OpenCraftFromJeiC2SPacket.STREAM_CODEC, OpenCraftFromJeiC2SPacket.STREAM_CODEC,
com.extendedae_plus.network.OpenCraftFromJeiC2SPacket::handle); OpenCraftFromJeiC2SPacket::handle);
registrar.playToServer(com.extendedae_plus.network.PickFromWirelessC2SPacket.TYPE, registrar.playToServer(PickFromWirelessC2SPacket.TYPE,
com.extendedae_plus.network.PickFromWirelessC2SPacket.STREAM_CODEC, PickFromWirelessC2SPacket.STREAM_CODEC,
com.extendedae_plus.network.PickFromWirelessC2SPacket::handle); PickFromWirelessC2SPacket::handle);
registrar.playToServer(com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket.TYPE, registrar.playToServer(PullFromJeiOrCraftC2SPacket.TYPE,
com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket.STREAM_CODEC, PullFromJeiOrCraftC2SPacket.STREAM_CODEC,
com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket::handle); PullFromJeiOrCraftC2SPacket::handle);
registrar.playToClient(C2SPacketEncodeFinished.TYPE,
C2SPacketEncodeFinished.STREAM_CODEC,
C2SPacketEncodeFinished::handle);
} }
} }

View File

@ -1,22 +1,18 @@
package com.extendedae_plus.network; package com.extendedae_plus.network;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.InteractionResult;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.MenuProvider; import net.minecraft.world.MenuProvider;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext;
public class OpenProviderUiC2SPacket implements CustomPacketPayload { public class OpenProviderUiC2SPacket implements CustomPacketPayload {

View File

@ -1,8 +1,8 @@
package com.extendedae_plus.network; package com.extendedae_plus.network;
import appeng.api.stacks.AEKey; import appeng.api.stacks.AEKey;
import com.extendedae_plus.content.ClientPatternHighlightStore;
import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.content.ClientPatternHighlightStore;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;

View File

@ -1,17 +1,17 @@
package com.extendedae_plus.network; package com.extendedae_plus.network;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.menu.implementations.PatternProviderMenu; import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.api.AdvancedBlockingHolder; import com.extendedae_plus.api.AdvancedBlockingHolder;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor; import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
import com.extendedae_plus.ExtendedAEPlus;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import appeng.api.config.Settings; import net.neoforged.neoforge.network.handling.IPayloadContext;
import appeng.api.config.YesNo;
/** /**
* C2S切换高级阻挡模式 * C2S切换高级阻挡模式

View File

@ -1,15 +1,15 @@
package com.extendedae_plus.network; package com.extendedae_plus.network;
import appeng.menu.implementations.PatternProviderMenu; import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.api.SmartDoublingHolder; import com.extendedae_plus.api.SmartDoublingHolder;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor; import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
import com.extendedae_plus.ExtendedAEPlus;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
/** /**
* C2S切换智能翻倍启用状态 * C2S切换智能翻倍启用状态

View File

@ -4,20 +4,18 @@ import appeng.api.crafting.IPatternDetails;
import appeng.api.crafting.PatternDetailsHelper; import appeng.api.crafting.PatternDetailsHelper;
import appeng.api.inventories.InternalInventory; import appeng.api.inventories.InternalInventory;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.core.definitions.AEItems;
import appeng.menu.AEBaseMenu;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
import appeng.core.definitions.AEItems;
import appeng.crafting.pattern.AECraftingPattern; import appeng.crafting.pattern.AECraftingPattern;
import appeng.crafting.pattern.AESmithingTablePattern; import appeng.crafting.pattern.AESmithingTablePattern;
import appeng.crafting.pattern.AEStonecuttingPattern; import appeng.crafting.pattern.AEStonecuttingPattern;
import appeng.helpers.patternprovider.PatternContainer; import appeng.helpers.patternprovider.PatternContainer;
import appeng.menu.AEBaseMenu;
import appeng.menu.implementations.PatternAccessTermMenu; import appeng.menu.implementations.PatternAccessTermMenu;
import appeng.menu.me.items.PatternEncodingTermMenu; import appeng.menu.me.items.PatternEncodingTermMenu;
import appeng.util.inv.FilteredInternalInventory; import appeng.util.inv.FilteredInternalInventory;
import appeng.util.inv.filter.IAEItemFilter; import appeng.util.inv.filter.IAEItemFilter;
import com.extendedae_plus.mixin.ae2.accessor.PatternEncodingTermMenuAccessor; import com.extendedae_plus.mixin.ae2.accessor.PatternEncodingTermMenuAccessor;
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixBase;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -35,7 +33,10 @@ import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**

View File

@ -4,15 +4,13 @@ import appeng.api.crafting.IPatternDetails.IInput;
import appeng.api.stacks.AEKey; import appeng.api.stacks.AEKey;
import appeng.api.stacks.GenericStack; import appeng.api.stacks.GenericStack;
import appeng.crafting.pattern.AEProcessingPattern; import appeng.crafting.pattern.AEProcessingPattern;
import com.extendedae_plus.content.ScaledProcessingPattern;
import com.extendedae_plus.api.SmartDoublingAwarePattern; import com.extendedae_plus.api.SmartDoublingAwarePattern;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import com.extendedae_plus.content.ScaledProcessingPattern;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
public final class PatternScaler { public final class PatternScaler {
private PatternScaler() { private PatternScaler() {
} }
@ -65,7 +63,7 @@ public final class PatternScaler {
} }
// 应用配置的最大倍数上限0 表示不限制 // 应用配置的最大倍数上限0 表示不限制
try { try {
int maxMul = ModConfigs.SMART_SCALING_MAX_MULTIPLIER.get(); int maxMul = ModConfig.SMART_SCALING_MAX_MULTIPLIER.get();
if (maxMul > 0 && multiplier > maxMul) { if (maxMul > 0 && multiplier > maxMul) {
multiplier = maxMul; multiplier = maxMul;
} }

View File

@ -1,6 +1,6 @@
package com.extendedae_plus.wireless; package com.extendedae_plus.wireless;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -63,7 +63,7 @@ public final class WirelessMasterRegistry {
} }
private static boolean useGlobal() { private static boolean useGlobal() {
return ModConfigs.WIRELESS_CROSS_DIM_ENABLE.get(); return ModConfig.WIRELESS_CROSS_DIM_ENABLE.get();
} }
private record Key(ResourceKey<Level> dim, long freq) { private record Key(ResourceKey<Level> dim, long freq) {

View File

@ -3,7 +3,7 @@ package com.extendedae_plus.wireless;
import appeng.api.networking.GridHelper; import appeng.api.networking.GridHelper;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.me.service.helpers.ConnectionWrapper; import appeng.me.service.helpers.ConnectionWrapper;
import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.config.ModConfig;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import java.util.Objects; import java.util.Objects;
@ -64,12 +64,12 @@ public class WirelessSlaveLink {
shutdown = false; shutdown = false;
distance = 0.0D; distance = 0.0D;
boolean crossDim = ModConfigs.WIRELESS_CROSS_DIM_ENABLE.get(); boolean crossDim = ModConfig.WIRELESS_CROSS_DIM_ENABLE.get();
if (master != null && !master.isEndpointRemoved() && (crossDim || master.getServerLevel() == level)) { if (master != null && !master.isEndpointRemoved() && (crossDim || master.getServerLevel() == level)) {
if (!crossDim) { if (!crossDim) {
distance = Math.sqrt(master.getBlockPos().distSqr(host.getBlockPos())); distance = Math.sqrt(master.getBlockPos().distSqr(host.getBlockPos()));
} }
double maxRange = ModConfigs.WIRELESS_MAX_RANGE.get(); double maxRange = ModConfig.WIRELESS_MAX_RANGE.get();
if (crossDim || distance <= maxRange) { if (crossDim || distance <= maxRange) {
// 保持/建立连接 // 保持/建立连接
try { try {

View File

@ -31,6 +31,8 @@
"screen.extendedae_plus.title": "ExtendedAE Plus Config", "screen.extendedae_plus.title": "ExtendedAE Plus Config",
"config.extendedae_plus": "ExtendedAE Plus", "config.extendedae_plus": "ExtendedAE Plus",
"config.extendedae_plus.override_ae2wt_picking": "Override AE2WT Picking",
"extendedae_plus.configuration.general": "General", "extendedae_plus.configuration.general": "General",
"extendedae_plus.configuration.pageMultiplier": "Pattern Provider Page Multiplier", "extendedae_plus.configuration.pageMultiplier": "Pattern Provider Page Multiplier",
"extendedae_plus.configuration.pageMultiplier_with_range": "Pattern Provider Page Multiplier (1-64)", "extendedae_plus.configuration.pageMultiplier_with_range": "Pattern Provider Page Multiplier (1-64)",

View File

@ -44,6 +44,7 @@
"screen.extendedae_plus.title": "ExtendedAE Plus 配置", "screen.extendedae_plus.title": "ExtendedAE Plus 配置",
"config.extendedae_plus": "ExtendedAE Plus", "config.extendedae_plus": "ExtendedAE Plus",
"config.extendedae_plus.override_ae2wt_picking": "覆盖AE2WT选取",
"extendedae_plus.configuration.general": "通用", "extendedae_plus.configuration.general": "通用",
"extendedae_plus.configuration.pageMultiplier": "扩展样板供应器槽位倍率", "extendedae_plus.configuration.pageMultiplier": "扩展样板供应器槽位倍率",

View File

@ -25,7 +25,7 @@
"ae2.menu.PatternEncodingTermMenuMixin", "ae2.menu.PatternEncodingTermMenuMixin",
"ae2.menu.PatternProviderMenuAdvancedMixin", "ae2.menu.PatternProviderMenuAdvancedMixin",
"ae2.menu.PatternProviderMenuDoublingMixin", "ae2.menu.PatternProviderMenuDoublingMixin",
"ae2WTlib.ContainerUWirelessExPatternTerminalMixin", "emi.MixinEncodePatternTransfer",
"extendedae.common.PartExPatternProviderMixin", "extendedae.common.PartExPatternProviderMixin",
"extendedae.common.TileExPatternProviderMixin", "extendedae.common.TileExPatternProviderMixin",
"extendedae.container.ContainerExPatternProviderMixin", "extendedae.container.ContainerExPatternProviderMixin",
@ -36,28 +36,25 @@
"PickFromWirelessMixin", "PickFromWirelessMixin",
"accessor.AbstractContainerScreenAccessor", "accessor.AbstractContainerScreenAccessor",
"accessor.ScreenAccessor", "accessor.ScreenAccessor",
"ae2.menu.CraftConfirmMenuGoBackMixin",
"ae2.accessor.AEBaseScreenAccessor", "ae2.accessor.AEBaseScreenAccessor",
"ae2.accessor.AEBaseScreenInvoker", "ae2.accessor.AEBaseScreenInvoker",
"ae2.accessor.MEStorageScreenAccessor", "ae2.accessor.MEStorageScreenAccessor",
"ae2.accessor.PatternAccessTermScreenAccessor", "ae2.accessor.PatternAccessTermScreenAccessor",
"ae2.accessor.PatternAccessTermScreenSlotsRowAccessor", "ae2.accessor.PatternAccessTermScreenSlotsRowAccessor",
"ae2.client.gui.InterfaceScreenMixin",
"ae2.client.gui.AEBaseScreenMixin", "ae2.client.gui.AEBaseScreenMixin",
"ae2.client.gui.InterfaceScreenMixin",
"ae2.client.gui.PatternEncodingTermScreenMixin", "ae2.client.gui.PatternEncodingTermScreenMixin",
"ae2.client.gui.PatternProviderCloseMixin", "ae2.client.gui.PatternProviderCloseMixin",
"ae2.client.gui.PatternProviderScreenMixin", "ae2.client.gui.PatternProviderScreenMixin",
"ae2.client.gui.SlotGridLayoutMixin", "ae2.client.gui.SlotGridLayoutMixin",
"ae2.menu.CraftConfirmMenuGoBackMixin",
"emi.MixinEncodingHelper",
"extendedae.accessor.GuiExPatternTerminalAccessor", "extendedae.accessor.GuiExPatternTerminalAccessor",
"extendedae.accessor.GuiExPatternTerminalSlotsRowAccessor", "extendedae.accessor.GuiExPatternTerminalSlotsRowAccessor",
"extendedae.client.HighlightButtonMixin", "extendedae.client.HighlightButtonMixin",
"extendedae.client.gui.GuiExPatternProviderMixin", "extendedae.client.gui.GuiExPatternProviderMixin",
"extendedae.client.gui.GuiExPatternTerminalMixin", "extendedae.client.gui.GuiExPatternTerminalMixin",
"hooks.ModelBakeryMixin", "hooks.ModelBakeryMixin"
"jei.AE2JeiEncodePatternTransferHandlerMixin",
"jei.EncodePatternTransferHandlerMixin",
"jei.EncodingHelperMixin",
"jei.accessor.BookmarkOverlayAccessor"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1