优化修改映射的体验
This commit is contained in:
parent
552c53400c
commit
61e73aa81a
|
|
@ -149,6 +149,12 @@ public class ProviderSelectScreen extends Screen {
|
|||
.build();
|
||||
this.addRenderableWidget(addMap);
|
||||
|
||||
// 删除映射(按中文值精确匹配删除)按钮
|
||||
Button delByCn = Button.builder(Component.literal("删除映射"), b -> deleteMappingByCnFromUI())
|
||||
.bounds(centerX + 240, navY + 30, 60, 20)
|
||||
.build();
|
||||
this.addRenderableWidget(delByCn);
|
||||
|
||||
// 关闭按钮
|
||||
Button close = Button.builder(Component.translatable("gui.cancel"), b -> onClose())
|
||||
.bounds(centerX - 40, navY + 30, 80, 20)
|
||||
|
|
@ -353,4 +359,22 @@ public class ProviderSelectScreen extends Screen {
|
|||
if (player != null) player.sendSystemMessage(Component.literal("写入映射失败"));
|
||||
}
|
||||
}
|
||||
|
||||
// 使用中文值精确匹配删除映射
|
||||
private void deleteMappingByCnFromUI() {
|
||||
String val = cnInput == null ? "" : cnInput.getValue().trim();
|
||||
var player = Minecraft.getInstance().player;
|
||||
if (val.isEmpty()) {
|
||||
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称后再删除映射"));
|
||||
return;
|
||||
}
|
||||
int removed = com.extendedae_plus.util.ExtendedAEPatternUploadUtil.removeMappingsByCnValue(val);
|
||||
if (removed > 0) {
|
||||
if (player != null) player.sendSystemMessage(Component.literal("已删除 " + removed + " 条映射,中文= " + val));
|
||||
applyFilter();
|
||||
needsRefresh = true;
|
||||
} else {
|
||||
if (player != null) player.sendSystemMessage(Component.literal("未找到中文为 '" + val + "' 的映射"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,17 +33,17 @@ public abstract class EncodePatternTransferHandlerMixin {
|
|||
// 仅记录处理配方(非 3x3 合成)
|
||||
if (EncodingHelper.isSupportedCraftingRecipe(recipe)) return;
|
||||
name = ExtendedAEPatternUploadUtil.mapRecipeTypeToSearchKey(recipe);
|
||||
} else if (recipeBase instanceof com.gregtechceu.gtceu.api.recipe.GTRecipe gtRecipe) {
|
||||
// GTCEu 专用:从 GTRecipeType 提取注册ID并映射为中文或path
|
||||
name = ExtendedAEPatternUploadUtil.mapGTCEuRecipeToSearchKey(gtRecipe);
|
||||
} else if (recipeBase != null &&
|
||||
"com.gregtechceu.gtceu.api.recipe.GTRecipe".equals(recipeBase.getClass().getName())) {
|
||||
// 反射路径:GTCEu 专用,从 GTRecipeType 提取注册ID并映射为中文或path
|
||||
name = ExtendedAEPatternUploadUtil.mapGTCEuRecipeToSearchKey(recipeBase);
|
||||
} else if ("com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeWrapper".equals(recipeBase.getClass().getName())) {
|
||||
// 通过反射处理 GTCEu JEI 包装类,避免硬依赖
|
||||
try {
|
||||
var field = recipeBase.getClass().getField("recipe"); // public final GTRecipe recipe;
|
||||
Object inner = field.get(recipeBase);
|
||||
if (inner instanceof com.gregtechceu.gtceu.api.recipe.GTRecipe gtRecipeInner) {
|
||||
name = ExtendedAEPatternUploadUtil.mapGTCEuRecipeToSearchKey(gtRecipeInner);
|
||||
}
|
||||
// 反射路径:将内部 GTRecipe 以 Object 传入
|
||||
name = ExtendedAEPatternUploadUtil.mapGTCEuRecipeToSearchKey(inner);
|
||||
} catch (Throwable ignored) {
|
||||
// 反射失败则继续走通用回退
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,69 @@ public class ExtendedAEPatternUploadUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按中文值精确匹配删除映射(支持别名与完整ID)。
|
||||
* 返回删除的条目数量。
|
||||
*/
|
||||
public static synchronized int removeMappingsByCnValue(String cnValue) {
|
||||
if (cnValue == null) return 0;
|
||||
String target = cnValue.trim();
|
||||
if (target.isEmpty()) return 0;
|
||||
try {
|
||||
Path cfgDir = FMLPaths.CONFIGDIR.get();
|
||||
Path cfgPath = cfgDir.resolve(CONFIG_RELATIVE);
|
||||
if (!Files.exists(cfgPath)) {
|
||||
return 0;
|
||||
}
|
||||
String json = Files.readString(cfgPath);
|
||||
JsonObject obj = GSON.fromJson(json, JsonObject.class);
|
||||
if (obj == null) return 0;
|
||||
|
||||
java.util.List<String> toRemove = new java.util.ArrayList<>();
|
||||
for (java.util.Map.Entry<String, JsonElement> e : obj.entrySet()) {
|
||||
JsonElement v = e.getValue();
|
||||
if (v != null && v.isJsonPrimitive()) {
|
||||
String name = v.getAsString();
|
||||
if (target.equals(name)) {
|
||||
toRemove.add(e.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toRemove.isEmpty()) return 0;
|
||||
|
||||
// 从 JSON 中移除
|
||||
for (String k : toRemove) {
|
||||
obj.remove(k);
|
||||
}
|
||||
Files.createDirectories(cfgPath.getParent());
|
||||
Files.writeString(cfgPath, GSON.toJson(obj));
|
||||
|
||||
// 同步移除内存映射
|
||||
for (String k : toRemove) {
|
||||
if (k.contains(":")) {
|
||||
try {
|
||||
ResourceLocation rl = new ResourceLocation(k);
|
||||
// 仅当值匹配才移除(双重保险)
|
||||
String cur = CUSTOM_NAMES.get(rl);
|
||||
if (target.equals(cur)) {
|
||||
CUSTOM_NAMES.remove(rl);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
} else {
|
||||
// 别名按小写存放
|
||||
String lower = k.toLowerCase();
|
||||
String cur = CUSTOM_ALIASES.get(lower);
|
||||
if (target.equals(cur)) {
|
||||
CUSTOM_ALIASES.remove(lower);
|
||||
}
|
||||
}
|
||||
}
|
||||
return toRemove.size();
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static String mapRecipeTypeToCn(Recipe<?> recipe) {
|
||||
if (recipe == null) return null;
|
||||
RecipeType<?> type = recipe.getType();
|
||||
|
|
@ -255,6 +318,35 @@ public class ExtendedAEPatternUploadUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅使用反射的 GTCEu GTRecipe -> 搜索关键字(避免在运行时直接引用 GTCEu 类)。
|
||||
* 逻辑与 {@link #mapGTCEuRecipeToSearchKey(com.gregtechceu.gtceu.api.recipe.GTRecipe)} 等价。
|
||||
*/
|
||||
public static String mapGTCEuRecipeToSearchKey(Object gtRecipeObj) {
|
||||
if (gtRecipeObj == null) return null;
|
||||
try {
|
||||
// 通过反射调用 getType(),其 toString() 应返回 registryName,即 namespace:path
|
||||
java.lang.reflect.Method mGetType = gtRecipeObj.getClass().getMethod("getType");
|
||||
Object typeObj = mGetType.invoke(gtRecipeObj);
|
||||
String idStr = String.valueOf(typeObj);
|
||||
if (idStr == null || idStr.isBlank()) return null;
|
||||
ResourceLocation rl = new ResourceLocation(idStr);
|
||||
// 1) 别名优先(使用 path 作为最终搜索关键字)
|
||||
String path = rl.getPath();
|
||||
if (path != null) {
|
||||
String alias = CUSTOM_ALIASES.get(path.toLowerCase());
|
||||
if (alias != null && !alias.isBlank()) return alias;
|
||||
}
|
||||
// 2) 再查完整ID映射
|
||||
String custom = CUSTOM_NAMES.get(rl);
|
||||
if (custom != null && !custom.isBlank()) return custom;
|
||||
// 3) 默认返回 path 作为搜索关键字
|
||||
return (path != null && !path.isBlank()) ? path : idStr;
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当 JEI 传入的 recipeBase 不是原版 Recipe<?> 时,根据类的包名/类名推导一个尽量可用的搜索关键字。
|
||||
* 例如:"moe.gregtech.recipe.SomeAssemblerRecipe" -> "gtceu assembler"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user