JEI写样板添加是否启用替换控制,配方书签上传失败回退逻辑

This commit is contained in:
GaLi 2026-03-03 11:37:26 +08:00
parent a4748c4415
commit 249dbaa791
5 changed files with 127 additions and 19 deletions

View File

@ -46,6 +46,8 @@ public final class CtrlQPatternKeyHandler {
int keyCode = event.getKeyCode(); int keyCode = event.getKeyCode();
int scanCode = event.getScanCode(); int scanCode = event.getScanCode();
boolean isAllowSubstitutes = Screen.hasShiftDown();
boolean isFluidSubstitutes = Screen.hasAltDown();
if (!ModKeybindings.CREATE_PATTERN_KEY.matches(keyCode, scanCode)) { if (!ModKeybindings.CREATE_PATTERN_KEY.matches(keyCode, scanCode)) {
return; return;
} }
@ -56,7 +58,7 @@ public final class CtrlQPatternKeyHandler {
Optional<?> recipeBookmark = JeiRuntimeProxy.getRecipeBookmarkUnderMouse(); Optional<?> recipeBookmark = JeiRuntimeProxy.getRecipeBookmarkUnderMouse();
if (recipeBookmark.isPresent()) { if (recipeBookmark.isPresent()) {
handleRecipeBookmark(recipeBookmark.get()); handleRecipeBookmark(recipeBookmark.get(), isAllowSubstitutes, isFluidSubstitutes);
event.setCanceled(true); event.setCanceled(true);
return; return;
} }
@ -91,16 +93,18 @@ public final class CtrlQPatternKeyHandler {
selected.getRecipeId(), selected.getRecipeId(),
selected.isCraftingRecipe(), selected.isCraftingRecipe(),
selectedIngredients, selectedIngredients,
selectedOutputs selectedOutputs,
isAllowSubstitutes,
isFluidSubstitutes
)); ));
event.setCanceled(true); event.setCanceled(true);
} }
private static void handleRecipeBookmark(Object recipeBookmark) { private static void handleRecipeBookmark(Object recipeBookmark, boolean isAllowSubstitutes, boolean isFluidSubstitutes) {
if (isCraftingRecipe(recipeBookmark)) { if (isCraftingRecipe(recipeBookmark)) {
handleCraftingRecipeBookmark(recipeBookmark); handleCraftingRecipeBookmark(recipeBookmark, isAllowSubstitutes, isFluidSubstitutes);
} else { } else {
handleProcessingRecipeBookmark(recipeBookmark); handleProcessingRecipeBookmark(recipeBookmark, isAllowSubstitutes, isFluidSubstitutes);
} }
} }
@ -119,7 +123,7 @@ public final class CtrlQPatternKeyHandler {
} }
} }
private static void handleCraftingRecipeBookmark(Object recipeBookmark) { private static void handleCraftingRecipeBookmark(Object recipeBookmark, boolean isAllowSubstitutes, boolean isFluidSubstitutes) {
try { try {
ResourceLocation recipeId = getRecipeId(recipeBookmark); ResourceLocation recipeId = getRecipeId(recipeBookmark);
if (recipeId == null) { if (recipeId == null) {
@ -158,13 +162,15 @@ public final class CtrlQPatternKeyHandler {
recipeId, recipeId,
matching.isCraftingRecipe(), matching.isCraftingRecipe(),
selectedIngredients, selectedIngredients,
selectedOutputs selectedOutputs,
isAllowSubstitutes,
isFluidSubstitutes
)); ));
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
} }
private static void handleProcessingRecipeBookmark(Object recipeBookmark) { private static void handleProcessingRecipeBookmark(Object recipeBookmark, boolean isAllowSubstitutes, boolean isFluidSubstitutes) {
try { try {
ResourceLocation recipeId = getRecipeId(recipeBookmark); ResourceLocation recipeId = getRecipeId(recipeBookmark);
if (recipeId == null) { if (recipeId == null) {
@ -212,7 +218,9 @@ public final class CtrlQPatternKeyHandler {
matching.isCraftingRecipe(), matching.isCraftingRecipe(),
selectedIngredients, selectedIngredients,
selectedOutputs, selectedOutputs,
true true,
isAllowSubstitutes,
isFluidSubstitutes
)); ));
PacketDistributor.sendToServer(RequestProvidersListC2SPacket.INSTANCE); PacketDistributor.sendToServer(RequestProvidersListC2SPacket.INSTANCE);
} catch (Throwable ignored) { } catch (Throwable ignored) {

View File

@ -41,13 +41,24 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
buf.writeBoolean(pkt.isCraftingPattern); buf.writeBoolean(pkt.isCraftingPattern);
ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.selectedIngredients); ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.selectedIngredients);
ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.outputs); ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.outputs);
buf.writeBoolean(pkt.isAllowSubstitutes);
buf.writeBoolean(pkt.isFluidSubstitutes);
}, },
buf -> { buf -> {
ResourceLocation recipeId = buf.readResourceLocation(); ResourceLocation recipeId = buf.readResourceLocation();
boolean isCraftingPattern = buf.readBoolean(); boolean isCraftingPattern = buf.readBoolean();
List<ItemStack> ingredients = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf); List<ItemStack> ingredients = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf);
List<ItemStack> outputs = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf); List<ItemStack> outputs = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf);
return new CreateAndUploadPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs); boolean isAllowSubstitutes = buf.readBoolean();
boolean isFluidSubstitutes = buf.readBoolean();
return new CreateAndUploadPatternC2SPacket(
recipeId,
isCraftingPattern,
ingredients,
outputs,
isAllowSubstitutes,
isFluidSubstitutes
);
} }
); );
@ -55,17 +66,32 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
private final boolean isCraftingPattern; private final boolean isCraftingPattern;
private final List<ItemStack> selectedIngredients; private final List<ItemStack> selectedIngredients;
private final List<ItemStack> outputs; private final List<ItemStack> outputs;
private final boolean isAllowSubstitutes;
private final boolean isFluidSubstitutes;
public CreateAndUploadPatternC2SPacket( public CreateAndUploadPatternC2SPacket(
ResourceLocation recipeId, ResourceLocation recipeId,
boolean isCraftingPattern, boolean isCraftingPattern,
List<ItemStack> selectedIngredients, List<ItemStack> selectedIngredients,
List<ItemStack> outputs List<ItemStack> outputs
) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, true, false);
}
public CreateAndUploadPatternC2SPacket(
ResourceLocation recipeId,
boolean isCraftingPattern,
List<ItemStack> selectedIngredients,
List<ItemStack> outputs,
boolean isAllowSubstitutes,
boolean isFluidSubstitutes
) { ) {
this.recipeId = recipeId; this.recipeId = recipeId;
this.isCraftingPattern = isCraftingPattern; this.isCraftingPattern = isCraftingPattern;
this.selectedIngredients = selectedIngredients; this.selectedIngredients = selectedIngredients;
this.outputs = outputs; this.outputs = outputs;
this.isAllowSubstitutes = isAllowSubstitutes;
this.isFluidSubstitutes = isFluidSubstitutes;
} }
public static void handle(final CreateAndUploadPatternC2SPacket msg, final IPayloadContext ctx) { public static void handle(final CreateAndUploadPatternC2SPacket msg, final IPayloadContext ctx) {
@ -92,7 +118,15 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
return; return;
} }
ItemStack pattern = createPattern(recipeHolder, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs, player); ItemStack pattern = createPattern(
recipeHolder,
msg.isCraftingPattern,
msg.selectedIngredients,
msg.outputs,
msg.isAllowSubstitutes,
msg.isFluidSubstitutes,
player
);
if (pattern.isEmpty()) { if (pattern.isEmpty()) {
refundBlankPattern(player, grid); refundBlankPattern(player, grid);
player.displayClientMessage(Component.translatable("message.extendedae_plus.pattern_creation_failed"), false); player.displayClientMessage(Component.translatable("message.extendedae_plus.pattern_creation_failed"), false);
@ -101,7 +135,9 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
boolean uploaded = ExtendedAEPatternUploadUtil.uploadPatternToMatrix(player, pattern, grid); boolean uploaded = ExtendedAEPatternUploadUtil.uploadPatternToMatrix(player, pattern, grid);
if (!uploaded) { if (!uploaded) {
refundBlankPattern(player, grid); if(!player.getInventory().add(pattern)){
player.drop(pattern.copy(),false);
}
} }
}); });
} }
@ -144,6 +180,8 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
boolean isCrafting, boolean isCrafting,
List<ItemStack> selectedIngredients, List<ItemStack> selectedIngredients,
List<ItemStack> selectedOutputs, List<ItemStack> selectedOutputs,
boolean isAllowSubstitutes,
boolean isFluidSubstitutes,
ServerPlayer player ServerPlayer player
) { ) {
try { try {
@ -172,8 +210,8 @@ public class CreateAndUploadPatternC2SPacket implements CustomPacketPayload {
craftingHolder, craftingHolder,
inputs, inputs,
output, output,
true, isAllowSubstitutes,
false isFluidSubstitutes
); );
CustomData.update(DataComponents.CUSTOM_DATA, encodedPattern, tag -> tag.putString("encodePlayer", player.getGameProfile().getName())); CustomData.update(DataComponents.CUSTOM_DATA, encodedPattern, tag -> tag.putString("encodePlayer", player.getGameProfile().getName()));
return encodedPattern; return encodedPattern;

View File

@ -42,6 +42,8 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
buf.writeBoolean(pkt.isCraftingPattern); buf.writeBoolean(pkt.isCraftingPattern);
ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.selectedIngredients); ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.selectedIngredients);
ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.outputs); ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, pkt.outputs);
buf.writeBoolean(pkt.isAllowSubstitutes);
buf.writeBoolean(pkt.isFluidSubstitutes);
buf.writeBoolean(pkt.openProviderSelector); buf.writeBoolean(pkt.openProviderSelector);
}, },
buf -> { buf -> {
@ -50,8 +52,18 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
List<ItemStack> ingredients = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf); List<ItemStack> ingredients = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf);
List<ItemStack> outputs = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf); List<ItemStack> outputs = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf);
boolean isAllowSubstitutes = buf.readBoolean();
boolean isFluidSubstitutes = buf.readBoolean();
boolean openProviderSelector = buf.readableBytes() > 0 && buf.readBoolean(); boolean openProviderSelector = buf.readableBytes() > 0 && buf.readBoolean();
return new CreateCtrlQPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs, openProviderSelector); return new CreateCtrlQPatternC2SPacket(
recipeId,
isCraftingPattern,
ingredients,
outputs,
openProviderSelector,
isAllowSubstitutes,
isFluidSubstitutes
);
} }
); );
@ -60,6 +72,8 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
private final List<ItemStack> selectedIngredients; private final List<ItemStack> selectedIngredients;
private final List<ItemStack> outputs; private final List<ItemStack> outputs;
private final boolean openProviderSelector; private final boolean openProviderSelector;
private final boolean isAllowSubstitutes;
private final boolean isFluidSubstitutes;
public CreateCtrlQPatternC2SPacket( public CreateCtrlQPatternC2SPacket(
ResourceLocation recipeId, ResourceLocation recipeId,
@ -67,7 +81,7 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
List<ItemStack> selectedIngredients, List<ItemStack> selectedIngredients,
List<ItemStack> outputs List<ItemStack> outputs
) { ) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, false); this(recipeId, isCraftingPattern, selectedIngredients, outputs, false, true, false);
} }
public CreateCtrlQPatternC2SPacket( public CreateCtrlQPatternC2SPacket(
@ -76,12 +90,37 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
List<ItemStack> selectedIngredients, List<ItemStack> selectedIngredients,
List<ItemStack> outputs, List<ItemStack> outputs,
boolean openProviderSelector boolean openProviderSelector
) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, openProviderSelector, true, false);
}
public CreateCtrlQPatternC2SPacket(
ResourceLocation recipeId,
boolean isCraftingPattern,
List<ItemStack> selectedIngredients,
List<ItemStack> outputs,
boolean isAllowSubstitutes,
boolean isFluidSubstitutes
) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, false, isAllowSubstitutes, isFluidSubstitutes);
}
public CreateCtrlQPatternC2SPacket(
ResourceLocation recipeId,
boolean isCraftingPattern,
List<ItemStack> selectedIngredients,
List<ItemStack> outputs,
boolean openProviderSelector,
boolean isAllowSubstitutes,
boolean isFluidSubstitutes
) { ) {
this.recipeId = recipeId; this.recipeId = recipeId;
this.isCraftingPattern = isCraftingPattern; this.isCraftingPattern = isCraftingPattern;
this.selectedIngredients = selectedIngredients; this.selectedIngredients = selectedIngredients;
this.outputs = outputs; this.outputs = outputs;
this.openProviderSelector = openProviderSelector; this.openProviderSelector = openProviderSelector;
this.isAllowSubstitutes = isAllowSubstitutes;
this.isFluidSubstitutes = isFluidSubstitutes;
} }
public static void handle(final CreateCtrlQPatternC2SPacket msg, final IPayloadContext ctx) { public static void handle(final CreateCtrlQPatternC2SPacket msg, final IPayloadContext ctx) {
@ -102,7 +141,15 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
return; return;
} }
ItemStack pattern = createPattern(recipeHolder, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs, player); ItemStack pattern = createPattern(
recipeHolder,
msg.isCraftingPattern,
msg.selectedIngredients,
msg.outputs,
msg.isAllowSubstitutes,
msg.isFluidSubstitutes,
player
);
if (pattern.isEmpty()) { if (pattern.isEmpty()) {
player.getInventory().add(AEItems.BLANK_PATTERN.stack()); player.getInventory().add(AEItems.BLANK_PATTERN.stack());
player.displayClientMessage(Component.translatable("message.extendedae_plus.pattern_creation_failed"), false); player.displayClientMessage(Component.translatable("message.extendedae_plus.pattern_creation_failed"), false);
@ -188,6 +235,8 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
boolean isCrafting, boolean isCrafting,
List<ItemStack> selectedIngredients, List<ItemStack> selectedIngredients,
List<ItemStack> selectedOutputs, List<ItemStack> selectedOutputs,
boolean isAllowSubstitutes,
boolean isFluidSubstitutes,
ServerPlayer player ServerPlayer player
) { ) {
try { try {
@ -216,8 +265,8 @@ public class CreateCtrlQPatternC2SPacket implements CustomPacketPayload {
craftingHolder, craftingHolder,
inputs, inputs,
output, output,
true, isAllowSubstitutes,
false isFluidSubstitutes
); );
CustomData.update(DataComponents.CUSTOM_DATA, encodedPattern, tag -> tag.putString("encodePlayer", player.getGameProfile().getName())); CustomData.update(DataComponents.CUSTOM_DATA, encodedPattern, tag -> tag.putString("encodePlayer", player.getGameProfile().getName()));
return encodedPattern; return encodedPattern;

View File

@ -36,6 +36,7 @@ public class UploadEncodedPatternToProviderC2SPacket implements CustomPacketPayl
if (CtrlQPendingUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId)) { if (CtrlQPendingUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId)) {
return; return;
} }
CtrlQPendingUploadUtil.returnPendingCtrlQPatternToInventory(player);
} }
if (!(player.containerMenu instanceof PatternEncodingTermMenu menu)) return; if (!(player.containerMenu instanceof PatternEncodingTermMenu menu)) return;

View File

@ -71,6 +71,18 @@ public final class CtrlQPendingUploadUtil {
return true; return true;
} }
public static boolean returnPendingCtrlQPatternToInventory(ServerPlayer player){
if (player == null) return false;
ItemStack pending = getPendingCtrlQPattern(player);
if(pending.isEmpty()) return false;
clearPendingCtrlQUpload(player);
if (!(player.getInventory().add(pending))) {
player.drop(pending.copy(),false);
}
return true;
}
public static List<PatternContainer> listAvailableProvidersFromPlayerNetwork(ServerPlayer player) { public static List<PatternContainer> listAvailableProvidersFromPlayerNetwork(ServerPlayer player) {
return listAvailableProvidersFromGrid(findPlayerGrid(player)); return listAvailableProvidersFromGrid(findPlayerGrid(player));
} }