Skip to content

Commit 1bf285c

Browse files
committed
Fix player could close the terminal when encoding
Support loading items from access terminal Change Log Level to Debug
1 parent 0dac91e commit 1bf285c

9 files changed

Lines changed: 162 additions & 49 deletions

File tree

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ parchment_mappings_version=2025.12.20
2626
mod_id=emi_patternizer
2727
mod_name=EMI Patternizer
2828
mod_license=GNU LGPL 3.0
29-
mod_version=0.1.0
29+
mod_version=0.2.0
3030
mod_group_id=io.github.linkfgfgui
3131
mod_authors=link-fgfgui
32-
mod_description=
32+
mod_description=Automatically Encoding Patterns from the EMI Recipe Tree.
3333
ae2_version=19.2.17
3434
emi_version=1.1.22+1.21.1

src/main/java/io/github/linkfgfgui/emi_patternizer/Emi_patternizer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ public class Emi_patternizer {
3535
public Emi_patternizer(IEventBus modEventBus, ModContainer modContainer) {
3636
modEventBus.addListener(this::clientSetup);
3737
modEventBus.addListener(this::registerKeyMappings);
38-
NeoForge.EVENT_BUS.register(new Patternize());
38+
NeoForge.EVENT_BUS.addListener(Patternize::onKeyPressed);
39+
NeoForge.EVENT_BUS.addListener(ReloadMemory::onScreenOpening);
3940
modContainer.registerConfig(ModConfig.Type.CLIENT, Config.SPEC);
4041
}
4142

4243
private void clientSetup(final FMLClientSetupEvent event) {
43-
LOGGER.info(Emi_patternizer.MODID + " has been initialized");
44+
LOGGER.debug(Emi_patternizer.MODID + " has been initialized");
4445
}
4546

4647
private void registerKeyMappings(final RegisterKeyMappingsEvent event) {

src/main/java/io/github/linkfgfgui/emi_patternizer/Patternize.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@
3232

3333

3434
public class Patternize {
35-
long per = 60;
36-
HashSet<String> EncodedItems = new HashSet<>();
35+
static long per = 60;
36+
public static HashSet<String> EncodedItems = new HashSet<>();
3737
public static volatile boolean operating = false;
3838
private static final Logger LOGGER = LogUtils.getLogger();
3939

40-
public boolean containsAllItems(EmiRecipe r) {
40+
public static boolean containsAllItems(EmiRecipe r) {
4141
return containsAllItems(r.getOutputs());
4242
}
4343

44-
public boolean containsAllItems(List<EmiStack> stackList) {
44+
public static boolean containsAllItems(List<EmiStack> stackList) {
4545
return (stackList.stream().allMatch(emiStack -> EncodedItems.contains(emiStack.getId().toString())));
4646
}
4747

48-
public void Encode(long initDelay, Minecraft minecraft, EmiRecipe recipe, PatternEncodingTermScreen<?> screen, PatternEncodingTermMenu menu, LocalPlayer player, MultiPlayerGameMode gameMode, int encodedPatternSlot) {
48+
public static void Encode(long initDelay, Minecraft minecraft, EmiRecipe recipe, PatternEncodingTermScreen<?> screen, PatternEncodingTermMenu menu, LocalPlayer player, MultiPlayerGameMode gameMode, int encodedPatternSlot) {
4949
CompletableFuture.delayedExecutor(initDelay, TimeUnit.MILLISECONDS).execute(() -> {
5050
minecraft.execute(() -> {
5151
// if (containsAllItems(recipe)) {
@@ -61,7 +61,7 @@ public void Encode(long initDelay, Minecraft minecraft, EmiRecipe recipe, Patter
6161
}
6262
menu.encode();
6363
recipe.getOutputs().forEach(emiStack -> EncodedItems.add(emiStack.getId().toString()));
64-
LOGGER.info("Operating: {}, EncodedItems: {}", operating, EncodedItems);
64+
LOGGER.debug("Operating: {}, EncodedItems: {}", operating, EncodedItems);
6565
});
6666
CompletableFuture.delayedExecutor(per, TimeUnit.MILLISECONDS).execute(() ->
6767
minecraft.execute(() ->
@@ -77,7 +77,7 @@ public void Encode(long initDelay, Minecraft minecraft, EmiRecipe recipe, Patter
7777
});
7878
}
7979

80-
public long CreateTasks(long delay, Minecraft minecraft, @Nullable List<MaterialNode> nodes, PatternEncodingTermScreen<?> screen, PatternEncodingTermMenu menu, LocalPlayer player, MultiPlayerGameMode gameMode, int encodedPatternSlot) {
80+
public static long CreateTasks(long delay, Minecraft minecraft, @Nullable List<MaterialNode> nodes, PatternEncodingTermScreen<?> screen, PatternEncodingTermMenu menu, LocalPlayer player, MultiPlayerGameMode gameMode, int encodedPatternSlot) {
8181
if (nodes == null) {
8282
return delay;
8383
}
@@ -93,36 +93,28 @@ public long CreateTasks(long delay, Minecraft minecraft, @Nullable List<Material
9393
return delay;
9494
}
9595

96-
@SubscribeEvent
97-
public void onScreenOpening(ScreenEvent.Opening event) {
98-
if (event.getScreen() instanceof PatternAccessTermScreen<?> screen) {
99-
EncodedItems.clear();
100-
}
101-
}
102-
103-
@SubscribeEvent
104-
public void onKeyPressed(ScreenEvent.KeyPressed.Post event) {
96+
public static void onKeyPressed(ScreenEvent.KeyPressed.Post event) {
10597
if (!operating && Emi_patternizer.PATTERNIZE_MAPPING.get().isActiveAndMatches(InputConstants.getKey(event.getKeyCode(), event.getScanCode()))) {
10698
if (event.getScreen() instanceof PatternEncodingTermScreen<?> screen) {
107-
LOGGER.info("Catched");
99+
LOGGER.debug("Catched");
108100
PatternEncodingTermMenu menu = screen.getMenu();
109101
int blankPatternSlot = ((AEBaseMenuAccessor) menu).getSlotsBySemantic().get(SlotSemantics.BLANK_PATTERN).getFirst().index;
110102
int encodedPatternSlot = ((AEBaseMenuAccessor) menu).getSlotsBySemantic().get(SlotSemantics.ENCODED_PATTERN).getFirst().index;
111103
if (BoM.craftingMode) {
112-
LOGGER.info("BoM crafting");
104+
LOGGER.debug("BoM crafting");
113105
Minecraft minecraft = Minecraft.getInstance();
114106
LocalPlayer player = minecraft.player;
115107
MultiPlayerGameMode gameMode = minecraft.gameMode;
116108

117109

118110
MaterialNode goal = BoM.tree.goal;
119111
operating = true;
120-
LOGGER.info(String.valueOf(operating));
112+
LOGGER.debug(String.valueOf(operating));
121113
long maxDelay = CreateTasks(0, minecraft, List.of(goal), screen, menu, player, gameMode, encodedPatternSlot);
122114
CompletableFuture.delayedExecutor(maxDelay + per, TimeUnit.MILLISECONDS).execute(() -> {
123115
operating = false;
124116
BoM.craftingMode=false;
125-
LOGGER.info(String.valueOf(operating));
117+
LOGGER.debug(String.valueOf(operating));
126118
});
127119
}
128120
} else {
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package io.github.linkfgfgui.emi_patternizer;
2+
3+
import appeng.api.crafting.IPatternDetails;
4+
import appeng.api.crafting.PatternDetailsHelper;
5+
import appeng.api.storage.IPatternAccessTermMenuHost;
6+
import appeng.client.gui.me.patternaccess.PatternAccessTermScreen;
7+
import appeng.client.gui.me.patternaccess.PatternContainerRecord;
8+
import appeng.menu.implementations.PatternAccessTermMenu;
9+
import com.mojang.logging.LogUtils;
10+
import dev.emi.emi.api.recipe.handler.EmiCraftContext;
11+
import dev.emi.emi.registry.EmiRecipeFiller;
12+
import io.github.linkfgfgui.emi_patternizer.mixin.PatternAccessTermScreenAccessor;
13+
import net.minecraft.client.Minecraft;
14+
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
15+
import net.minecraft.network.chat.Component;
16+
import net.minecraft.sounds.SoundEvents;
17+
import net.minecraft.world.level.Level;
18+
import net.neoforged.neoforge.client.event.ScreenEvent;
19+
20+
import static io.github.linkfgfgui.emi_patternizer.Patternize.EncodedItems;
21+
22+
import org.slf4j.Logger;
23+
24+
import java.util.Collection;
25+
import java.util.Set;
26+
import java.util.concurrent.CompletableFuture;
27+
import java.util.concurrent.TimeUnit;
28+
29+
public class ReloadMemory {
30+
static long PatternCount = 0;
31+
private static final Logger LOGGER = LogUtils.getLogger();
32+
33+
public static void onScreenOpening(ScreenEvent.Opening event) {
34+
if (event.getScreen() instanceof PatternAccessTermScreen<?> screen) {
35+
EncodedItems.clear();
36+
Minecraft minecraft = Minecraft.getInstance();
37+
Level level = minecraft.level;
38+
CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS).execute(() -> {
39+
minecraft.execute(() -> {
40+
PatternCount = 0;
41+
Collection<PatternContainerRecord> patternContainerRecordSet = ((PatternAccessTermScreenAccessor) screen).getById().values();
42+
LOGGER.debug(patternContainerRecordSet.toString());
43+
for (PatternContainerRecord entry : patternContainerRecordSet) {
44+
entry.getInventory().toItemContainerContents().stream().forEach((item) -> {
45+
IPatternDetails details = PatternDetailsHelper.decodePattern(item, level);
46+
PatternCount++;
47+
if (details == null) {
48+
} else {
49+
details.getOutputs().forEach(
50+
genericStack -> {
51+
EncodedItems.add(genericStack.what().getId().toString());
52+
}
53+
);
54+
}
55+
});
56+
}
57+
if (minecraft.player != null) {
58+
minecraft.player.sendSystemMessage(Component.translatable("chat.emi_patternizer.loaded", EncodedItems.size(), PatternCount));
59+
}
60+
});
61+
});
62+
63+
64+
//
65+
// ((PatternAccessTermScreenAccessor) menu).getPinnedHosts().forEach(patternContainer ->
66+
// {
67+
//
68+
// patternContainer.getGrid().getNodes().forEach(node ->
69+
// {
70+
// if (node instanceof IPatternAccessTermMenuHost) {
71+
// node.
72+
// }
73+
// }
74+
// );
75+
// });
76+
77+
78+
//
79+
// CompletableFuture.delayedExecutor(1000, TimeUnit.MILLISECONDS).execute(() -> minecraft.execute(() -> {
80+
// IPatternAccessTermMenuHost node = ((PatternAccessTermMenuAccessor) menu).getHost();
81+
// if (node == null) {
82+
// LOGGER.error("PatternAccessTermMenu node is null");
83+
// return;
84+
// }
85+
// LOGGER.info(node.toString());
86+
// }));
87+
88+
// IGridNode node = ((PatternAccessTermMenuAccessor) menu).getHost().getGridNode();
89+
// if (node == null) {
90+
// LOGGER.error("PatternAccessTermMenu node is null");
91+
// return;
92+
// }
93+
// IGrid grid = node.getGrid();
94+
// ICraftingService craftingService = grid.getService(ICraftingService.class);
95+
// if (craftingService == null) {
96+
//
97+
//
98+
// LOGGER.error("craftingService is null");
99+
// return;
100+
// }
101+
// craftingService.getCraftables(AEKeyFilter.none()).forEach(
102+
// key -> {
103+
// LOGGER.info(key.getId().toString());
104+
// }
105+
// );
106+
107+
108+
// // 获取所有提供样板的“提供者”
109+
// for (ICraftingProvider provider : craftingService.getCraftables()) {
110+
// // 在 1.21 中,直接获取该提供者当前可用的所有样板详情
111+
// for (IPatternDetails pattern : provider.getAvailablePatterns()) {
112+
// // pattern 就是具体的样板信息(输入、输出等)
113+
// System.out.println("输出物品: " + pattern.getPrimaryOutput());
114+
// }
115+
// }
116+
117+
118+
}
119+
}
120+
}

src/main/java/io/github/linkfgfgui/emi_patternizer/mixin/AbstractContainerScreenMixin.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.linkfgfgui.emi_patternizer.mixin;
22

3+
import appeng.client.gui.me.items.PatternEncodingTermScreen;
34
import appeng.client.gui.me.patternaccess.PatternAccessTermScreen;
45
import com.mojang.logging.LogUtils;
56
import io.github.linkfgfgui.emi_patternizer.Patternize;
@@ -17,12 +18,12 @@ public class AbstractContainerScreenMixin {
1718
@Inject(method = "onClose", at = @At("HEAD"), cancellable = true)
1819
private void preventScreenClose(CallbackInfo ci) {
1920
Screen currentScreen = (Screen) (Object) this;
20-
if (currentScreen instanceof PatternAccessTermScreen<?> && Patternize.operating) {
21+
if (currentScreen instanceof PatternEncodingTermScreen<?> && Patternize.operating) {
2122
ci.cancel();
22-
LOGGER.info("try to cancel");
23+
LOGGER.debug("try to cancel");
2324

2425
}else{
25-
LOGGER.info(currentScreen.toString());
26+
LOGGER.debug(currentScreen.toString());
2627
}
2728
}
2829
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.linkfgfgui.emi_patternizer.mixin;
2+
3+
import appeng.api.storage.IPatternAccessTermMenuHost;
4+
import appeng.client.gui.me.patternaccess.PatternAccessTermScreen;
5+
import appeng.client.gui.me.patternaccess.PatternContainerRecord;
6+
import appeng.helpers.patternprovider.PatternContainer;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.gen.Accessor;
9+
10+
import java.util.HashMap;
11+
import java.util.Set;
12+
13+
@Mixin(PatternAccessTermScreen.class)
14+
public interface PatternAccessTermScreenAccessor {
15+
@Accessor("byId")
16+
HashMap<Long, PatternContainerRecord> getById();
17+
}

src/main/java/io/github/linkfgfgui/emi_patternizer/mixin/PatternEncodingTermMenuMixin.java

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"itemGroup.emi_patternizer": "EMI Patternizer",
33
"key.emi_patternizer.patternize": "Encode Pattern",
4-
"key.categories.emi_patternizer.category": "EMI Patternizer"
4+
"key.categories.emi_patternizer.category": "EMI Patternizer",
5+
"chat.emi_patternizer.loaded": "Loaded %d Item(s) from %d Pattern(s)"
56
}

src/main/resources/emi_patternizer.mixins.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
"mixins": [
77
],
88
"client": [
9-
"AEBaseMenuAccessor",
109
"AbstractContainerScreenMixin",
10+
"AEBaseMenuAccessor",
1111
"PatternEncodingTermMenuAccessor",
12-
"PatternEncodingTermMenuMixin"
12+
"PatternAccessTermScreenAccessor"
1313
],
1414
"injectors": {
1515
"defaultRequire": 1

0 commit comments

Comments
 (0)