diff --git a/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java b/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java index 5f7ae5f..c846dcd 100644 --- a/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java +++ b/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java @@ -78,6 +78,10 @@ public class ProviderSelectScreen extends Screen { // 缓存 Component JSON 解析 private static final Map componentCache = new HashMap<>(); private String lastLanguage = ""; // 当前语言版本 + private boolean autoUploadRequestedFromProcessingName = false; + private boolean autoUploadAttempted = false; + private int lastExactMatchCount = 0; + private boolean lastFilterUsedFallback = false; public ProviderSelectScreen(Screen parent, List ids, List names, List emptySlots) { super(Component.translatable("extendedae_plus.screen.choose_provider.title")); @@ -90,6 +94,7 @@ public class ProviderSelectScreen extends Screen { String recent = RecipeTypeNameConfig.lastProcessingName; if (recent != null && !recent.isBlank()) { this.query = recent; + this.autoUploadRequestedFromProcessingName = true; // 用后即清空,避免污染下次 RecipeTypeNameConfig.lastProcessingName = null; } @@ -200,6 +205,7 @@ public class ProviderSelectScreen extends Screen { this.addRenderableWidget(delByCn); refreshButtons(); // 初始化完成后刷新按钮状态 + tryAutoUploadIfUniqueMatch(); } private void changePage(int delta) { @@ -273,9 +279,14 @@ public class ProviderSelectScreen extends Screen { } private void onChoose(int idx) { + onChoose(idx, false); + } + + private void onChoose(int idx, boolean showStatusMessage) { if (idx < 0 || idx >= fIds.size()) return; long providerId = fIds.get(idx); - ModNetwork.CHANNEL.sendToServer(new UploadEncodedPatternToProviderC2SPacket(providerId)); + String providerName = fNames.get(idx); + ModNetwork.CHANNEL.sendToServer(new UploadEncodedPatternToProviderC2SPacket(providerId, showStatusMessage, providerName)); this.onClose(); } @@ -323,6 +334,8 @@ public class ProviderSelectScreen extends Screen { fNames.clear(); fTotalSlots.clear(); fCount.clear(); + lastExactMatchCount = 0; + lastFilterUsedFallback = false; String q = query == null ? "" : query.trim(); String qLower = q.toLowerCase(Locale.ROOT); @@ -333,10 +346,12 @@ public class ProviderSelectScreen extends Screen { fNames.add(name); fTotalSlots.add(gTotalSlots.get(i)); fCount.add(gCount.get(i)); + lastExactMatchCount++; } } // 若查询不为空但没有任何匹配,则回退为显示全部,避免“空列表”误导用户 if (!q.isEmpty() && fIds.isEmpty()) { + lastFilterUsedFallback = true; for (int i = 0; i < gIds.size(); i++) { fIds.add(gIds.get(i)); fNames.add(gNames.get(i)); @@ -385,6 +400,17 @@ public class ProviderSelectScreen extends Screen { fCount.addAll(sortedCount); } + private void tryAutoUploadIfUniqueMatch() { + if (!autoUploadRequestedFromProcessingName || autoUploadAttempted) { + return; + } + autoUploadAttempted = true; + if (query == null || query.isBlank() || lastFilterUsedFallback || lastExactMatchCount != 1 || fIds.size() != 1) { + return; + } + onChoose(0, true); + } + // 优先使用 JEC 的拼音匹配,否则回退到大小写不敏感子串匹配 private static Boolean JEC_AVAILABLE = null; private static java.lang.reflect.Method JEC_CONTAINS = null; diff --git a/src/main/java/com/extendedae_plus/network/UploadEncodedPatternToProviderC2SPacket.java b/src/main/java/com/extendedae_plus/network/UploadEncodedPatternToProviderC2SPacket.java index 406a32a..82c0f24 100644 --- a/src/main/java/com/extendedae_plus/network/UploadEncodedPatternToProviderC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/UploadEncodedPatternToProviderC2SPacket.java @@ -3,6 +3,7 @@ package com.extendedae_plus.network; import appeng.menu.me.items.PatternEncodingTermMenu; import com.extendedae_plus.util.uploadPattern.ProviderUploadUtil; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.network.NetworkEvent; @@ -13,17 +14,27 @@ import java.util.function.Supplier; */ public class UploadEncodedPatternToProviderC2SPacket { private final long providerId; + private final boolean showStatusMessage; + private final String providerName; public UploadEncodedPatternToProviderC2SPacket(long providerId) { + this(providerId, false, ""); + } + + public UploadEncodedPatternToProviderC2SPacket(long providerId, boolean showStatusMessage, String providerName) { this.providerId = providerId; + this.showStatusMessage = showStatusMessage; + this.providerName = providerName == null ? "" : providerName; } public static void encode(UploadEncodedPatternToProviderC2SPacket msg, FriendlyByteBuf buf) { buf.writeLong(msg.providerId); + buf.writeBoolean(msg.showStatusMessage); + buf.writeUtf(msg.providerName, 256); } public static UploadEncodedPatternToProviderC2SPacket decode(FriendlyByteBuf buf) { - return new UploadEncodedPatternToProviderC2SPacket(buf.readLong()); + return new UploadEncodedPatternToProviderC2SPacket(buf.readLong(), buf.readBoolean(), buf.readUtf(256)); } public static void handle(UploadEncodedPatternToProviderC2SPacket msg, Supplier ctxSupplier) { @@ -32,23 +43,43 @@ public class UploadEncodedPatternToProviderC2SPacket { ServerPlayer player = ctx.getSender(); if (player == null) return; + boolean uploaded = false; + if (ProviderUploadUtil.hasPendingCtrlQPattern(player)) { - if (ProviderUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId)) { - return; + uploaded = ProviderUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId); + if (!uploaded) { + ProviderUploadUtil.returnPendingCtrlQPatternToInventory(player); } - ProviderUploadUtil.returnPendingCtrlQPatternToInventory(player); + sendAutoUploadStatus(player, msg, uploaded); return; } if (player.containerMenu instanceof PatternEncodingTermMenu menu) { if (msg.providerId >= 0) { - ProviderUploadUtil.uploadFromEncodingMenuToProvider(player, menu, msg.providerId); + uploaded = ProviderUploadUtil.uploadFromEncodingMenuToProvider(player, menu, msg.providerId); } else { int index = (int) (-1L - msg.providerId); - ProviderUploadUtil.uploadFromEncodingMenuToProviderByIndex(player, menu, index); + uploaded = ProviderUploadUtil.uploadFromEncodingMenuToProviderByIndex(player, menu, index); } } + + sendAutoUploadStatus(player, msg, uploaded); }); ctx.setPacketHandled(true); } + + private static void sendAutoUploadStatus(ServerPlayer player, UploadEncodedPatternToProviderC2SPacket msg, boolean uploaded) { + if (player == null || !msg.showStatusMessage) { + return; + } + String providerDisplayName = msg.providerName == null || msg.providerName.isBlank() + ? "#" + msg.providerId + : msg.providerName; + player.sendSystemMessage(Component.translatable( + uploaded + ? "extendedae_plus.screen.upload.auto_upload_success" + : "extendedae_plus.screen.upload.auto_upload_failed", + providerDisplayName + )); + } } diff --git a/src/main/resources/assets/extendedae_plus/lang/en_us.json b/src/main/resources/assets/extendedae_plus/lang/en_us.json index eb383fa..0314fba 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -125,6 +125,8 @@ "extendedae_plus.screen.upload.select_provider_first":"Please click the button on the left to select a pattern provider first", "extendedae_plus.screen.upload.invalid_pattern": "Invalid Pattern", "extendedae_plus.screen.upload.no_network_support": "ExtendedAE network support not found (may be missing or incompatible version)", + "extendedae_plus.screen.upload.auto_upload_success": "Automatically uploaded to the only matching pattern provider: %s", + "extendedae_plus.screen.upload.auto_upload_failed": "Automatic upload to the pattern provider failed: %s", "extendedae_plus.screen.open_provider_ui": "Open the target container UI of this provider", "extendedae_plus.button.choose_provider": "Upload Pattern", diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json index 2711f37..e0f3717 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -124,6 +124,8 @@ "extendedae_plus.screen.upload.select_provider_first": "请先点击左侧按钮选择一个样板供应器", "extendedae_plus.screen.upload.invalid_pattern": "无效样板", "extendedae_plus.screen.upload.no_network_support": "未找到 ExtendedAE 网络支持(可能未安装或版本不兼容)", + "extendedae_plus.screen.upload.auto_upload_success": "已自动上传到唯一匹配的样板供应器:%s", + "extendedae_plus.screen.upload.auto_upload_failed": "自动上传到样板供应器失败:%s", "extendedae_plus.screen.open_provider_ui": "打开该供应器目标容器的界面", "extendedae_plus.button.choose_provider":"上传样板", diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_tw.json b/src/main/resources/assets/extendedae_plus/lang/zh_tw.json index f659b8e..cbaaa9e 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_tw.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_tw.json @@ -120,11 +120,13 @@ "extendedae_plus.screen.upload.mapping_deleted": "已刪除 %d 條對映,名稱 = %s", "extendedae_plus.screen.upload.mapping_not_found": "未找到名稱為 '%s' 的對映", "extendedae_plus.screen.upload.name": "對映名", - "extendedae_plus.screen.upload.select_provider_first": "請先點選左側按鈕選擇一個樣板供應器", - "extendedae_plus.screen.upload.invalid_pattern": "無效樣板", - "extendedae_plus.screen.upload.no_network_support": "未找到 ExtendedAE 網路支援(可能未安裝或版本不相容)", - - "extendedae_plus.screen.open_provider_ui": "開啟該供應器目標容器的介面", + "extendedae_plus.screen.upload.select_provider_first": "請先點選左側按鈕選擇一個樣板供應器", + "extendedae_plus.screen.upload.invalid_pattern": "無效樣板", + "extendedae_plus.screen.upload.no_network_support": "未找到 ExtendedAE 網路支援(可能未安裝或版本不相容)", + "extendedae_plus.screen.upload.auto_upload_success": "已自動上傳到唯一匹配的樣板供應器:%s", + "extendedae_plus.screen.upload.auto_upload_failed": "自動上傳到樣板供應器失敗:%s", + + "extendedae_plus.screen.open_provider_ui": "開啟該供應器目標容器的介面", "extendedae_plus.button.choose_provider": "上傳樣板", "extendedae_plus.pattern.hovertext.player": "由 %s 編碼",