feat:合成界面shift取消添加书签功能适配旧版本

This commit is contained in:
C-H716 2026-04-28 18:10:38 +08:00
parent f77e9dc6a4
commit b11af174f8
2 changed files with 40 additions and 17 deletions

View File

@ -281,6 +281,9 @@ public final class JeiRuntimeProxy {
/** /**
* 内部方法将指定类型的原料添加到 JEI 书签列表 * 内部方法将指定类型的原料添加到 JEI 书签列表
* 兼容新旧版本 JEI
* - 新版本 (>= 19.27.0.336)使用 BookmarkFactory.create()
* - 旧版本 (<= 19.27.0.335)使用 IngredientBookmark.create()
* @param ingredientType 原料类型 ITEM_STACKFLUID_STACK * @param ingredientType 原料类型 ITEM_STACKFLUID_STACK
* @param ingredient 原料对象 ItemStackFluidStack * @param ingredient 原料对象 ItemStackFluidStack
*/ */
@ -307,16 +310,44 @@ public final class JeiRuntimeProxy {
Object typedOpt = createTyped.invoke(manager, ingredientType, ingredient); Object typedOpt = createTyped.invoke(manager, ingredientType, ingredient);
if (typedOpt instanceof Optional<?> opt && opt.isPresent()) { if (typedOpt instanceof Optional<?> opt && opt.isPresent()) {
Object typed = opt.get(); Object typed = opt.get();
// BookmarkList 获取 bookmarkFactory 字段 Object bookmark = null;
Field factoryField = list.getClass().getDeclaredField("bookmarkFactory");
factoryField.setAccessible(true); // 新版本 JEI >= JEI 19.27.0.336使用 BookmarkFactory 创建书签
Object factory = factoryField.get(list); try {
// 调用 bookmarkFactory.create() 创建书签对象 Field factoryField = list.getClass().getDeclaredField("bookmarkFactory");
Method create = factory.getClass().getMethod("create", Class.forName("mezz.jei.api.ingredients.ITypedIngredient")); factoryField.setAccessible(true);
Object bookmark = create.invoke(factory, typed); Object factory = factoryField.get(list);
Method create = factory.getClass().getMethod("create", Class.forName("mezz.jei.api.ingredients.ITypedIngredient"));
bookmark = create.invoke(factory, typed);
} catch (NoSuchFieldException e) {
// 旧版本 <= JEI 19.27.0.335使用 IngredientBookmark.create() 静态方法创建书签
Class<?> ingredientBookmarkCls = Class.forName("mezz.jei.gui.bookmarks.IngredientBookmark");
Method create = ingredientBookmarkCls.getMethod("create", Class.forName("mezz.jei.api.ingredients.ITypedIngredient"), Class.forName("mezz.jei.api.runtime.IIngredientManager"));
bookmark = create.invoke(null, typed, manager);
}
// 将书签添加到列表 // 将书签添加到列表
Class<?> ibCls = Class.forName("mezz.jei.gui.bookmarks.IBookmark"); if (bookmark != null) {
list.getClass().getMethod("add", ibCls).invoke(list, bookmark); // 获取 bookmark 的实际类IngredientBookmark
Class<?> bookmarkClass = bookmark.getClass();
// 查找 add 方法
// 新旧版本兼容遍历所有方法找到参数类型兼容的 add 方法
// 新版本add(IBookmark) 旧版本add(IBookmark) add(IngredientBookmark)
Method addMethod = null;
for (Method m : list.getClass().getMethods()) {
if (m.getName().equals("add") && m.getParameterCount() == 1) {
Class<?> paramType = m.getParameterTypes()[0];
// 检查参数类型是否是 bookmark 的父类或接口
if (paramType.isAssignableFrom(bookmarkClass)) {
addMethod = m;
break;
}
}
}
if (addMethod != null) {
addMethod.invoke(list, bookmark);
}
}
} }
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }

View File

@ -89,14 +89,6 @@ versionRange = "*"
ordering = "AFTER" ordering = "AFTER"
side = "BOTH" side = "BOTH"
# Require JEI (version >= 19.27.0.336) for bookmark integration
[[dependencies.${ mod_id }]]
modId = "jei"
type = "optional"
versionRange = "[19.27.0.336,)"
ordering = "NONE"
side = "CLIENT"
# Features are specific properties of the game environment, that you may want to declare you require. This example declares # Features are specific properties of the game environment, that you may want to declare you require. This example declares
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
# stop your mod loading on the server for example. # stop your mod loading on the server for example.