Skip to content

Commit 4005a48

Browse files
committed
Implement pattern filtering for the me bridge
1 parent 5bab2e9 commit 4005a48

File tree

6 files changed

+140
-10
lines changed

6 files changed

+140
-10
lines changed

src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/AppEngApi.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import de.srendi.advancedperipherals.common.util.LuaConverter;
2323
import de.srendi.advancedperipherals.common.util.Pair;
2424
import de.srendi.advancedperipherals.common.util.inventory.FluidFilter;
25+
import de.srendi.advancedperipherals.common.util.inventory.GenericFilter;
2526
import de.srendi.advancedperipherals.common.util.inventory.ItemFilter;
2627
import de.srendi.advancedperipherals.common.util.inventory.ItemUtil;
2728
import io.github.projectet.ae2things.item.DISKDrive;
@@ -87,6 +88,45 @@ public static Pair<Long, AEFluidKey> findAEFluidFromFilter(MEStorage monitor, @N
8788
return null;
8889
}
8990

91+
public static Pair<IPatternDetails, String> findPatternFromFilters(ICraftingProvider provider, GenericFilter inputFilter, GenericFilter outputFilter) {
92+
for (IPatternDetails pattern : provider.getAvailablePatterns()) {
93+
if (pattern.getInputs().length == 0)
94+
continue;
95+
if (pattern.getOutputs().length == 0)
96+
continue;
97+
98+
boolean inputMatch = false;
99+
boolean outputMatch = false;
100+
101+
if(!inputFilter.isEmpty()) {
102+
for (IPatternDetails.IInput input : pattern.getInputs()) {
103+
if (inputFilter.test(input.getPossibleInputs()[0])) {
104+
inputMatch = true;
105+
break;
106+
}
107+
}
108+
} else {
109+
inputMatch = true;
110+
}
111+
112+
if(!outputFilter.isEmpty()) {
113+
for (GenericStack output : pattern.getOutputs()) {
114+
if (outputFilter.test(output)) {
115+
outputMatch = true;
116+
break;
117+
}
118+
}
119+
} else {
120+
outputMatch = true;
121+
}
122+
123+
if (inputMatch && outputMatch)
124+
return Pair.of(pattern, null);
125+
}
126+
127+
return Pair.of(null, "NO_PATTERN_FOUND");
128+
}
129+
90130
public static List<Object> listStacks(MEStorage monitor, ICraftingService service, int flag) {
91131
List<Object> items = new ArrayList<>();
92132
KeyCounter keyCounter = monitor.getAvailableStacks();

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MeBridgePeripheral.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.srendi.advancedperipherals.common.addons.computercraft.peripheral;
22

3+
import appeng.api.crafting.IPatternDetails;
34
import appeng.api.networking.IGridNode;
45
import appeng.api.networking.IManagedGridNode;
56
import appeng.api.networking.crafting.ICraftingCPU;
@@ -13,6 +14,7 @@
1314
import dan200.computercraft.api.lua.LuaFunction;
1415
import dan200.computercraft.api.lua.MethodResult;
1516
import dan200.computercraft.api.peripheral.IComputerAccess;
17+
import dan200.computercraft.core.apis.TableHelper;
1618
import dan200.computercraft.core.computer.ComputerSide;
1719
import de.srendi.advancedperipherals.common.addons.appliedenergistics.AppEngApi;
1820
import de.srendi.advancedperipherals.common.addons.appliedenergistics.CraftJob;
@@ -273,25 +275,50 @@ public MethodResult getFilteredPatterns(IArguments arguments) throws LuaExceptio
273275
if (!isAvailable())
274276
return notConnected();
275277

278+
// Expected input is a table with either an input table, an output table or both to filter for both
276279
Map<?, ?> filterTable;
277280
try {
278281
Optional<Map<?, ?>> optionalTable = arguments.optTable(0);
279282
if (optionalTable.isEmpty())
280283
return MethodResult.of(null, "EMPTY_INPUT");
281-
// Expected input is a table with either an input table, an output table or both to filter for both
282284
filterTable = optionalTable.get();
283285
} catch (LuaException e) {
284286
return MethodResult.of(null, "NO_TABLE");
285287
}
286288

287289
boolean hasInputFilter = filterTable.containsKey("input");
288290
boolean hasOutputFilter = filterTable.containsKey("output");
291+
boolean hasAnyFilter = hasInputFilter || hasOutputFilter;
289292

293+
// If the player tries to filter for nothing, return nothing.
294+
if (!hasAnyFilter)
295+
return MethodResult.of(null, "NO_FILTER");
290296

291-
if (hasInputFilter)
292-
return null;
297+
GenericFilter inputFilter = GenericFilter.empty();
298+
GenericFilter outputFilter = GenericFilter.empty();
293299

294-
return null;
300+
if (hasInputFilter) {
301+
Map<?, ?> inputFilterTable = TableHelper.getTableField(filterTable, "input");
302+
303+
inputFilter = GenericFilter.parseGeneric(inputFilterTable).getLeft();
304+
}
305+
if (hasOutputFilter) {
306+
Map<?, ?> outputFilterTable = TableHelper.getTableField(filterTable, "output");
307+
308+
outputFilter = GenericFilter.parseGeneric(outputFilterTable).getLeft();
309+
}
310+
311+
ICraftingProvider provider = node.getService(ICraftingProvider.class);
312+
313+
if (provider == null)
314+
return MethodResult.of(null, "NO_CRAFTING_PROVIDER");
315+
316+
Pair<IPatternDetails, String> pattern = AppEngApi.findPatternFromFilters(provider, inputFilter, outputFilter);
317+
318+
if (pattern.getRight() != null)
319+
return MethodResult.of(null, pattern.getRight());
320+
321+
return MethodResult.of(AppEngApi.getObjectFromPattern(pattern.getLeft()));
295322
}
296323

297324
@Override

src/main/java/de/srendi/advancedperipherals/common/setup/APBlocks.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.srendi.advancedperipherals.common.setup;
22

3-
import de.srendi.advancedperipherals.common.addons.APAddons;
43
import de.srendi.advancedperipherals.common.blocks.PlayerDetectorBlock;
54
import de.srendi.advancedperipherals.common.blocks.RedstoneIntegratorBlock;
65
import de.srendi.advancedperipherals.common.blocks.base.APBlockEntityBlock;

src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidFilter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.srendi.advancedperipherals.common.util.inventory;
22

3+
import appeng.api.stacks.AEFluidKey;
4+
import appeng.api.stacks.GenericStack;
35
import dan200.computercraft.api.lua.LuaException;
46
import dan200.computercraft.core.apis.TableHelper;
57
import de.srendi.advancedperipherals.AdvancedPeripherals;
@@ -97,6 +99,14 @@ public FluidFilter setCount(int count) {
9799
return this;
98100
}
99101

102+
@Override
103+
public boolean test(GenericStack genericStack) {
104+
if (genericStack.what() instanceof AEFluidKey aeFluidKey) {
105+
return test(aeFluidKey.toStack(1));
106+
}
107+
return false;
108+
}
109+
100110
public boolean test(FluidStack stack) {
101111
if (!fingerprint.isEmpty()) {
102112
String testFingerprint = FluidUtil.getFingerprint(stack);
Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,60 @@
11
package de.srendi.advancedperipherals.common.util.inventory;
22

3+
import appeng.api.stacks.GenericStack;
34
import de.srendi.advancedperipherals.common.util.Pair;
5+
import net.minecraftforge.registries.ForgeRegistries;
46

57
import java.util.Map;
68

79
public abstract class GenericFilter {
810

9-
// TODO: Imagine we want to filter for an object which can either a item, a fluid or maybe a chemical from mekanism
10-
// This function should first check if the `name` key can be found in any of the registries and then return the
11-
// right filter according to the registry type which could be an item or a chemical
12-
public static Pair<GenericFilter, String> parseGeneric(Map<?, ?> rawFilter) {
13-
return Pair.of(null, null);
11+
/**
12+
* Try to parse a raw filter table to any existing filter type. Could be a fluid filter, an item filter, maybe something else
13+
* in the future.
14+
* <p>
15+
* If the function can't find a valid type for the given name/resource location, it will return an empty filter with
16+
* a proper error message.
17+
*
18+
* @param rawFilter The raw filter, which is a map of strings and objects
19+
* @return A pair of the parsed filter and an error message, if there is one
20+
*/
21+
public static Pair<? extends GenericFilter, String> parseGeneric(Map<?, ?> rawFilter) {
22+
if (!rawFilter.containsKey("name")) {
23+
// If the filter does not contain a name, which should never happen, but players are players, we will just
24+
// give the ItemFilter the task to parse the filter
25+
return ItemFilter.parse(rawFilter);
26+
}
27+
String name = rawFilter.get("name").toString();
28+
29+
// Let's check in which registry this thing is
30+
if (ItemUtil.getRegistryEntry(name, ForgeRegistries.ITEMS) != null) {
31+
return ItemFilter.parse(rawFilter);
32+
} else if (ItemUtil.getRegistryEntry(name, ForgeRegistries.FLUIDS) != null) {
33+
return FluidFilter.parse(rawFilter);
34+
// TODO: Add chemical filter support
35+
} else {
36+
// If the name is in neither of the registries, we will just return an empty filter
37+
return Pair.of(empty(), "NO_VALID_FILTER_TYPE");
38+
}
39+
40+
}
41+
42+
public abstract boolean isEmpty();
43+
44+
public abstract boolean test(GenericStack genericStack);
45+
46+
public static GenericFilter empty() {
47+
return new GenericFilter() {
48+
@Override
49+
public boolean isEmpty() {
50+
return true;
51+
}
52+
53+
@Override
54+
public boolean test(GenericStack genericStack) {
55+
return false;
56+
}
57+
};
1458
}
1559

1660
}

src/main/java/de/srendi/advancedperipherals/common/util/inventory/ItemFilter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.srendi.advancedperipherals.common.util.inventory;
22

3+
import appeng.api.stacks.AEItemKey;
4+
import appeng.api.stacks.GenericStack;
35
import dan200.computercraft.api.lua.LuaException;
46
import dan200.computercraft.core.apis.TableHelper;
57
import de.srendi.advancedperipherals.AdvancedPeripherals;
@@ -112,6 +114,14 @@ public ItemStack toItemStack() {
112114
return result;
113115
}
114116

117+
@Override
118+
public boolean test(GenericStack genericStack) {
119+
if (genericStack.what() instanceof AEItemKey aeItemKey) {
120+
return test(aeItemKey.toStack());
121+
}
122+
return false;
123+
}
124+
115125
public boolean test(ItemStack stack) {
116126
if (!fingerprint.isEmpty()) {
117127
String testFingerprint = ItemUtil.getFingerprint(stack);

0 commit comments

Comments
 (0)