供应器搜索结果唯一时直接上传样板

This commit is contained in:
GaLi 2026-03-25 14:18:29 +08:00
parent 66de0dea40
commit 439eea7bfe
4 changed files with 74 additions and 18 deletions

View File

@ -66,6 +66,9 @@ public class ProviderSelectScreen extends Screen {
private String query = "";
private boolean needsRefresh = false;
private int page = 0;
private boolean autoUploadRequestedFromProcessingName = false;
private boolean autoUploadAttempted = false;
private int lastExactMatchCount = 0;
public ProviderSelectScreen(Screen parent, List<Long> ids, List<Component> names, List<Integer> emptySlots) {
super(Component.translatable("extendedae_plus.screen.choose_provider.title"));
@ -78,6 +81,7 @@ public class ProviderSelectScreen extends Screen {
String recent = ExtendedAEPatternUploadUtil.lastProcessingName;
if (recent != null && !recent.isBlank()) {
this.query = recent;
this.autoUploadRequestedFromProcessingName = true;
// 用后即清空避免污染下次
ExtendedAEPatternUploadUtil.lastProcessingName = null;
}
@ -154,12 +158,14 @@ public class ProviderSelectScreen extends Screen {
}
private void onChoose(int idx) {
this.onChoose(idx, false);
}
private void onChoose(int idx, boolean showStatusMessage) {
if (idx < 0 || idx >= this.fIds.size()) return;
long providerId = this.fIds.get(idx);
var conn = Minecraft.getInstance().getConnection();
if (conn != null) {
conn.send(new UploadEncodedPatternToProviderC2SPacket(providerId));
}
String providerName = this.fNames.get(idx);
PacketDistributor.sendToServer(new UploadEncodedPatternToProviderC2SPacket(providerId, showStatusMessage, providerName));
this.onClose();
}
@ -194,6 +200,7 @@ public class ProviderSelectScreen extends Screen {
this.fNames.clear();
this.fTotalSlots.clear();
this.fCount.clear();
this.lastExactMatchCount = 0;
String q = this.query == null ? "" : this.query.trim();
for (int i = 0; i < this.gIds.size(); i++) {
String name = this.gNames.get(i);
@ -202,6 +209,7 @@ public class ProviderSelectScreen extends Screen {
this.fNames.add(name);
this.fTotalSlots.add(this.gTotalSlots.get(i));
this.fCount.add(this.gCount.get(i));
this.lastExactMatchCount++;
}
}
@ -244,6 +252,17 @@ public class ProviderSelectScreen extends Screen {
this.fCount.addAll(sortedCount);
}
private void tryAutoUploadIfUniqueMatch() {
if (!this.autoUploadRequestedFromProcessingName || this.autoUploadAttempted) {
return;
}
this.autoUploadAttempted = true;
if (this.query == null || this.query.isBlank() || this.lastExactMatchCount != 1 || this.fIds.size() != 1) {
return;
}
this.onChoose(0, true);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.searchBox != null && this.searchBox.keyPressed(keyCode, scanCode, modifiers)) {
@ -350,6 +369,8 @@ public class ProviderSelectScreen extends Screen {
.bounds(centerX - 40, navY + 30, 80, 20)
.build();
this.addRenderableWidget(close);
this.tryAutoUploadIfUniqueMatch();
}
@Override

View File

@ -5,6 +5,7 @@ import com.extendedae_plus.util.uploadPattern.CtrlQPendingUploadUtil;
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
@ -18,40 +19,70 @@ public class UploadEncodedPatternToProviderC2SPacket implements CustomPacketPayl
ResourceLocation.fromNamespaceAndPath(com.extendedae_plus.ExtendedAEPlus.MODID, "upload_pattern_to_provider"));
public static final StreamCodec<FriendlyByteBuf, UploadEncodedPatternToProviderC2SPacket> STREAM_CODEC = StreamCodec.of(
(buf, pkt) -> buf.writeLong(pkt.providerId),
buf -> new UploadEncodedPatternToProviderC2SPacket(buf.readLong())
(buf, pkt) -> {
buf.writeLong(pkt.providerId);
buf.writeBoolean(pkt.showStatusMessage);
buf.writeUtf(pkt.providerName, 256);
},
buf -> new UploadEncodedPatternToProviderC2SPacket(buf.readLong(), buf.readBoolean(), buf.readUtf(256))
);
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 handle(final UploadEncodedPatternToProviderC2SPacket msg, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (!(ctx.player() instanceof ServerPlayer player)) return;
boolean uploaded = false;
// 优先处理 Ctrl+Q pending 上传
if (CtrlQPendingUploadUtil.hasPendingCtrlQPattern(player)) {
if (CtrlQPendingUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId)) {
return;
uploaded = CtrlQPendingUploadUtil.uploadPendingCtrlQPattern(player, msg.providerId);
if (!uploaded) {
CtrlQPendingUploadUtil.returnPendingCtrlQPatternToInventory(player);
}
CtrlQPendingUploadUtil.returnPendingCtrlQPatternToInventory(player);
sendAutoUploadStatus(player, msg, uploaded);
return;
}
if (!(player.containerMenu instanceof PatternEncodingTermMenu menu)) return;
// 支持两种模式
// 1) providerId >= 0: 访问终端 byId 模式
// 2) providerId < 0: 索引模式由列表回退路径生成index = -1 - providerId
if (msg.providerId >= 0) {
ExtendedAEPatternUploadUtil.uploadFromEncodingMenuToProvider(player, menu, msg.providerId);
} else {
int index = (int) (-1L - msg.providerId);
ExtendedAEPatternUploadUtil.uploadFromEncodingMenuToProviderByIndex(player, menu, index);
if (player.containerMenu instanceof PatternEncodingTermMenu menu) {
// 支持两种模式
// 1) providerId >= 0: 访问终端 byId 模式
// 2) providerId < 0: 索引模式由列表回退路径生成index = -1 - providerId
if (msg.providerId >= 0) {
uploaded = ExtendedAEPatternUploadUtil.uploadFromEncodingMenuToProvider(player, menu, msg.providerId);
} else {
int index = (int) (-1L - msg.providerId);
uploaded = ExtendedAEPatternUploadUtil.uploadFromEncodingMenuToProviderByIndex(player, menu, index);
}
}
sendAutoUploadStatus(player, msg, uploaded);
});
}
private static void sendAutoUploadStatus(ServerPlayer player, UploadEncodedPatternToProviderC2SPacket msg, boolean uploaded) {
if (player == null || !msg.showStatusMessage) {
return;
}
String providerDisplayName = 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
));
}
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;

View File

@ -199,6 +199,8 @@
"extendedae_plus.message.mapping.delete_cn_required": "Please enter the Chinese name to delete.",
"extendedae_plus.message.mapping.delete_success": "Deleted %d mapping(s) for \"%s\".",
"extendedae_plus.message.mapping.delete_not_found": "No mapping found for \"%s\".",
"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.message.upload.no_pattern": "No encoded pattern found.",
"extendedae_plus.message.network.invalid": "Unable to access AE network.",

View File

@ -198,6 +198,8 @@
"extendedae_plus.message.mapping.delete_cn_required": "请输入要删除的中文名称。",
"extendedae_plus.message.mapping.delete_success": "已删除 \"%s\" 的映射,共 %d 条。",
"extendedae_plus.message.mapping.delete_not_found": "未找到 \"%s\" 的映射。",
"extendedae_plus.screen.upload.auto_upload_success": "已自动上传到唯一匹配的样板供应器:%s",
"extendedae_plus.screen.upload.auto_upload_failed": "自动上传到样板供应器失败:%s",
"extendedae_plus.message.upload.no_pattern": "未找到已编码样板。",
"extendedae_plus.message.network.invalid": "无法访问 AE 网络。",