Skip to content

Commit

Permalink
[backport] Prevent recipe transfers from touching output slots (#3720)
Browse files Browse the repository at this point in the history
cherry-picked from the commit 99ff43b
  • Loading branch information
Crispy-fried-chicken authored Aug 31, 2024
1 parent 60045a8 commit 328f5d9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ public static boolean validateSlots(
.toList();
if (!invalidRecipeIndexes.isEmpty()) {
LOGGER.error(
"Transfer handler has invalid slots for the destination of the recipe, " +
"the slots are not included in the list of crafting slots. " +
StringUtil.intsToString(invalidRecipeIndexes)
"Transfer request has invalid slots for the destination of the recipe, the slots are not included in the list of crafting slots. {}",
StringUtil.intsToString(invalidRecipeIndexes)
);
return false;
}
Expand All @@ -118,11 +117,10 @@ public static boolean validateSlots(
.toList();
if (!invalidInventorySlotIndexes.isEmpty()) {
LOGGER.error(
"Transfer handler 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. " +
StringUtil.intsToString(invalidInventorySlotIndexes) +
"\n inventory slots: " + StringUtil.intsToString(inventorySlotIndexes) +
"\n crafting slots: " + StringUtil.intsToString(craftingSlotIndexes)
"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: {}",
StringUtil.intsToString(invalidInventorySlotIndexes),
StringUtil.intsToString(inventorySlotIndexes),
StringUtil.intsToString(craftingSlotIndexes)
);
return false;
}
Expand All @@ -135,9 +133,8 @@ public static boolean validateSlots(
.collect(Collectors.toSet());
if (!overlappingSlots.isEmpty()) {
LOGGER.error(
"Transfer handler has invalid slots, " +
"inventorySlots and craftingSlots should not share any slot, but both have: " +
StringUtil.intsToString(overlappingSlots)
"Transfer request has invalid slots, inventorySlots and craftingSlots should not share any slot, but both have: {}",
StringUtil.intsToString(overlappingSlots)
);
return false;
}
Expand All @@ -155,14 +152,31 @@ public static boolean validateSlots(
.toList();
if (!invalidPickupSlots.isEmpty()) {
LOGGER.error(
"Transfer handler has invalid slots, " +
"the player is unable to pickup from them: " +
StringUtil.intsToString(invalidPickupSlots)
"Transfer request has invalid slots, the player is unable to pickup from them: {}",
StringUtil.intsToString(invalidPickupSlots)
);
return false;
}
}

// check that all slots are real (not output slots)
{
List<Integer> invalidFakeSlots = Stream.concat(
craftingSlots.stream(),
inventorySlots.stream()
)
.filter(Slot::isFake)
.map(slot -> slot.index)
.toList();
if (!invalidFakeSlots.isEmpty()) {
LOGGER.error(
"Transfer request has invalid slots, they are fake slots (recipe outputs): {}",
StringUtil.intsToString(invalidFakeSlots)
);
return false;
}
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,8 @@ public IRecipeTransferError transferRecipe(C container, R recipe, IRecipeSlotsVi
return handlerHelper.createUserErrorForMissingSlots(message, transferOperations.missingItems);
}

{
if (!RecipeTransferUtil.validateSlots(player, transferOperations.results, craftingSlots, inventorySlots)) {
return handlerHelper.createInternalError();
}
if (!RecipeTransferUtil.validateSlots(player, transferOperations.results, craftingSlots, inventorySlots)) {
return handlerHelper.createInternalError();
}

if (doTransfer) {
Expand All @@ -145,7 +143,25 @@ public static <C extends AbstractContainerMenu, R> boolean validateTransferInfo(
C container,
List<Slot> craftingSlots,
List<Slot> inventorySlots
) {
) {
for (Slot slot : craftingSlots) {
if (slot.isFake()) {
LOGGER.error("Recipe Transfer helper {} does not work for container {}. " +
"The Recipe Transfer Helper references crafting slot index [{}] but it is a fake (output) slot, which is not allowed.",
transferInfo.getClass(), container.getClass(), slot.index
);
return false;
}
}
for (Slot slot : inventorySlots) {
if (slot.isFake()) {
LOGGER.error("Recipe Transfer helper {} does not work for container {}. " +
"The Recipe Transfer Helper references inventory slot index [{}] but it is a fake (output) slot, which is not allowed.",
transferInfo.getClass(), container.getClass(), slot.index
);
return false;
}
}
Collection<Integer> craftingSlotIndexes = slotIndexes(craftingSlots);
Collection<Integer> inventorySlotIndexes = slotIndexes(inventorySlots);
Collection<Integer> containerSlotIndexes = slotIndexes(container.slots);
Expand Down

0 comments on commit 328f5d9

Please sign in to comment.