Skip to content

Commit 328f5d9

Browse files
[backport] Prevent recipe transfers from touching output slots (#3720)
cherry-picked from the commit 99ff43b
1 parent 60045a8 commit 328f5d9

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

Common/src/main/java/mezz/jei/common/transfer/RecipeTransferUtil.java

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,8 @@ public static boolean validateSlots(
101101
.toList();
102102
if (!invalidRecipeIndexes.isEmpty()) {
103103
LOGGER.error(
104-
"Transfer handler has invalid slots for the destination of the recipe, " +
105-
"the slots are not included in the list of crafting slots. " +
106-
StringUtil.intsToString(invalidRecipeIndexes)
104+
"Transfer request has invalid slots for the destination of the recipe, the slots are not included in the list of crafting slots. {}",
105+
StringUtil.intsToString(invalidRecipeIndexes)
107106
);
108107
return false;
109108
}
@@ -118,11 +117,10 @@ public static boolean validateSlots(
118117
.toList();
119118
if (!invalidInventorySlotIndexes.isEmpty()) {
120119
LOGGER.error(
121-
"Transfer handler has invalid source slots for the inventory stacks for the recipe, " +
122-
"the slots are not included in the list of inventory slots or recipe slots. " +
123-
StringUtil.intsToString(invalidInventorySlotIndexes) +
124-
"\n inventory slots: " + StringUtil.intsToString(inventorySlotIndexes) +
125-
"\n crafting slots: " + StringUtil.intsToString(craftingSlotIndexes)
120+
"Transfer request has invalid source slots for the inventory stacks for the recipe, the slots are not included in the list of inventory slots or recipe slots. {}\n inventory slots: {}\n crafting slots: {}",
121+
StringUtil.intsToString(invalidInventorySlotIndexes),
122+
StringUtil.intsToString(inventorySlotIndexes),
123+
StringUtil.intsToString(craftingSlotIndexes)
126124
);
127125
return false;
128126
}
@@ -135,9 +133,8 @@ public static boolean validateSlots(
135133
.collect(Collectors.toSet());
136134
if (!overlappingSlots.isEmpty()) {
137135
LOGGER.error(
138-
"Transfer handler has invalid slots, " +
139-
"inventorySlots and craftingSlots should not share any slot, but both have: " +
140-
StringUtil.intsToString(overlappingSlots)
136+
"Transfer request has invalid slots, inventorySlots and craftingSlots should not share any slot, but both have: {}",
137+
StringUtil.intsToString(overlappingSlots)
141138
);
142139
return false;
143140
}
@@ -155,14 +152,31 @@ public static boolean validateSlots(
155152
.toList();
156153
if (!invalidPickupSlots.isEmpty()) {
157154
LOGGER.error(
158-
"Transfer handler has invalid slots, " +
159-
"the player is unable to pickup from them: " +
160-
StringUtil.intsToString(invalidPickupSlots)
155+
"Transfer request has invalid slots, the player is unable to pickup from them: {}",
156+
StringUtil.intsToString(invalidPickupSlots)
161157
);
162158
return false;
163159
}
164160
}
165161

162+
// check that all slots are real (not output slots)
163+
{
164+
List<Integer> invalidFakeSlots = Stream.concat(
165+
craftingSlots.stream(),
166+
inventorySlots.stream()
167+
)
168+
.filter(Slot::isFake)
169+
.map(slot -> slot.index)
170+
.toList();
171+
if (!invalidFakeSlots.isEmpty()) {
172+
LOGGER.error(
173+
"Transfer request has invalid slots, they are fake slots (recipe outputs): {}",
174+
StringUtil.intsToString(invalidFakeSlots)
175+
);
176+
return false;
177+
}
178+
}
179+
166180
return true;
167181
}
168182

Library/src/main/java/mezz/jei/library/transfer/BasicRecipeTransferHandler.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,8 @@ public IRecipeTransferError transferRecipe(C container, R recipe, IRecipeSlotsVi
119119
return handlerHelper.createUserErrorForMissingSlots(message, transferOperations.missingItems);
120120
}
121121

122-
{
123-
if (!RecipeTransferUtil.validateSlots(player, transferOperations.results, craftingSlots, inventorySlots)) {
124-
return handlerHelper.createInternalError();
125-
}
122+
if (!RecipeTransferUtil.validateSlots(player, transferOperations.results, craftingSlots, inventorySlots)) {
123+
return handlerHelper.createInternalError();
126124
}
127125

128126
if (doTransfer) {
@@ -145,7 +143,25 @@ public static <C extends AbstractContainerMenu, R> boolean validateTransferInfo(
145143
C container,
146144
List<Slot> craftingSlots,
147145
List<Slot> inventorySlots
148-
) {
146+
) {
147+
for (Slot slot : craftingSlots) {
148+
if (slot.isFake()) {
149+
LOGGER.error("Recipe Transfer helper {} does not work for container {}. " +
150+
"The Recipe Transfer Helper references crafting slot index [{}] but it is a fake (output) slot, which is not allowed.",
151+
transferInfo.getClass(), container.getClass(), slot.index
152+
);
153+
return false;
154+
}
155+
}
156+
for (Slot slot : inventorySlots) {
157+
if (slot.isFake()) {
158+
LOGGER.error("Recipe Transfer helper {} does not work for container {}. " +
159+
"The Recipe Transfer Helper references inventory slot index [{}] but it is a fake (output) slot, which is not allowed.",
160+
transferInfo.getClass(), container.getClass(), slot.index
161+
);
162+
return false;
163+
}
164+
}
149165
Collection<Integer> craftingSlotIndexes = slotIndexes(craftingSlots);
150166
Collection<Integer> inventorySlotIndexes = slotIndexes(inventorySlots);
151167
Collection<Integer> containerSlotIndexes = slotIndexes(container.slots);

0 commit comments

Comments
 (0)