9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 01:49:30 +00:00

perf(bukkit): 优化配方相关反射逻辑

This commit is contained in:
jhqwqmc
2025-08-07 14:40:52 +08:00
parent 381e2b11cb
commit 81fd77d67b
3 changed files with 240 additions and 48 deletions

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.item.recipe;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.papermc.paper.potion.PotionMix;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
@@ -144,11 +145,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
.map(Optional::get)
.toList();
if (VersionHelper.isOrAbove1_21_2()) {
CoreReflections.field$ShapedRecipe$placementInfo.set(shapedRecipe, null);
CoreReflections.methodHandle$ShapedRecipe$placementInfoSetter.invokeExact(shapedRecipe, (Object) null);
}
List<Object> ingredients = getIngredientsFromShapedRecipe(shapedRecipe);
modifyIngredients(ingredients, actualIngredients);
} catch (ReflectiveOperationException e) {
} catch (Throwable e) {
CraftEngine.instance().logger().warn("Failed to inject shaped recipe", e);
}
}
@@ -158,16 +159,16 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
List<Object> ingredients = new ArrayList<>();
try {
if (VersionHelper.isOrAbove1_20_3()) {
Object pattern = CoreReflections.field$1_20_3$ShapedRecipe$pattern.get(recipe);
Object pattern = CoreReflections.methodHandle$1_20_3$ShapedRecipe$patternGetter.invokeExact(recipe);
if (VersionHelper.isOrAbove1_21_2()) {
List<Optional<Object>> optionals = (List<Optional<Object>>) CoreReflections.field$ShapedRecipePattern$ingredients1_21_2.get(pattern);
List<Optional<Object>> optionals = (List<Optional<Object>>) CoreReflections.methodHandle$ShapedRecipePattern$ingredients1_21_2Getter.invokeExact(pattern);
for (Optional<Object> optional : optionals) {
optional.ifPresent(ingredients::add);
}
} else {
List<Object> objectList = (List<Object>) CoreReflections.field$ShapedRecipePattern$ingredients1_20_3.get(pattern);
List<Object> objectList = (List<Object>) CoreReflections.methodHandle$ShapedRecipePattern$ingredients1_20_3Getter.invokeExact(pattern);
for (Object object : objectList) {
Object[] values = (Object[]) CoreReflections.field$Ingredient$values.get(object);
Object[] values = (Object[]) CoreReflections.methodHandle$Ingredient$valuesGetter.invokeExact(object);
// is empty or not
if (values.length != 0) {
ingredients.add(object);
@@ -175,15 +176,15 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
}
}
} else {
List<Object> objectList = (List<Object>) CoreReflections.field$1_20_1$ShapedRecipe$recipeItems.get(recipe);
List<Object> objectList = (List<Object>) CoreReflections.methodHandle$1_20_1$ShapedRecipe$recipeItemsGetter.invokeExact(recipe);
for (Object object : objectList) {
Object[] values = (Object[]) CoreReflections.field$Ingredient$values.get(object);
Object[] values = (Object[]) CoreReflections.methodHandle$Ingredient$valuesGetter.invokeExact(object);
if (values.length != 0) {
ingredients.add(object);
}
}
}
} catch (ReflectiveOperationException e) {
} catch (Throwable e) {
CraftEngine.instance().logger().warn("Failed to get ingredients from shaped recipe", e);
}
return ingredients;
@@ -193,12 +194,12 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
try {
List<Ingredient<ItemStack>> actualIngredients = recipe.ingredientsInUse();
if (VersionHelper.isOrAbove1_21_2()) {
CoreReflections.field$ShapelessRecipe$placementInfo.set(shapelessRecipe, null);
CoreReflections.methodHandle$ShapelessRecipe$placementInfoSetter.invokeExact(shapelessRecipe, (Object) null);
}
@SuppressWarnings("unchecked")
List<Object> ingredients = (List<Object>) CoreReflections.field$ShapelessRecipe$ingredients.get(shapelessRecipe);
List<Object> ingredients = (List<Object>) CoreReflections.methodHandle$ShapelessRecipe$ingredientsGetter.invokeExact(shapelessRecipe);
modifyIngredients(ingredients, actualIngredients);
} catch (ReflectiveOperationException e) {
} catch (Throwable e) {
CraftEngine.instance().logger().warn("Failed to inject shapeless recipe", e);
}
}
@@ -208,12 +209,12 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
Ingredient<ItemStack> actualIngredient = recipe.ingredient();
Object ingredient;
if (VersionHelper.isOrAbove1_21_2()) {
ingredient = CoreReflections.field$SingleItemRecipe$input.get(cookingRecipe);
ingredient = CoreReflections.methodHandle$SingleItemRecipe$inputGetter.invokeExact(cookingRecipe);
} else {
ingredient = CoreReflections.field$AbstractCookingRecipe$input.get(cookingRecipe);
ingredient = CoreReflections.methodHandle$AbstractCookingRecipe$inputGetter.invokeExact(cookingRecipe);
}
modifyIngredients(List.of(ingredient), List.of(actualIngredient));
} catch (ReflectiveOperationException e) {
} catch (Throwable e) {
CraftEngine.instance().logger().warn("Failed to inject cooking recipe", e);
}
}
@@ -235,7 +236,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
return itemStacks;
}
private static void modifyIngredients(List<Object> fakeIngredients, List<Ingredient<ItemStack>> actualIngredients) throws ReflectiveOperationException {
private static void modifyIngredients(List<Object> fakeIngredients, List<Ingredient<ItemStack>> actualIngredients) throws Throwable {
if (fakeIngredients.size() != actualIngredients.size()) {
throw new IllegalArgumentException("Ingredient count mismatch");
}
@@ -244,15 +245,15 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
Ingredient<ItemStack> actualIngredient = actualIngredients.get(i);
List<Object> items = getIngredientLooks(actualIngredient.items());
if (VersionHelper.isOrAbove1_21_4()) {
CoreReflections.field$Ingredient$itemStacks1_21_4.set(ingredient, new HashSet<>(items));
CoreReflections.methodHandle$Ingredient$itemStacksSetter.invokeExact(ingredient, (Set<Object>) new ObjectOpenHashSet<>(items));
} else if (VersionHelper.isOrAbove1_21_2()) {
CoreReflections.field$Ingredient$itemStacks1_21_2.set(ingredient, items);
CoreReflections.methodHandle$Ingredient$itemStacksSetter.invokeExact(ingredient, (List<Object>) items);
} else {
Object itemStackArray = Array.newInstance(CoreReflections.clazz$ItemStack, items.size());
for (int j = 0; j < items.size(); j++) {
Array.set(itemStackArray, j, items.get(j));
}
CoreReflections.field$Ingredient$itemStacks1_20_1.set(ingredient, itemStackArray);
CoreReflections.methodHandle$Ingredient$itemStacksSetter.invokeExact(ingredient, (Object) itemStackArray);
}
MODIFIED_INGREDIENTS.add(ingredient);
}
@@ -308,9 +309,9 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
if (!Config.enableRecipeSystem()) return;
if (VersionHelper.isOrAbove1_21_2()) {
try {
this.stolenFeatureFlagSet = CoreReflections.field$RecipeManager$featureflagset.get(minecraftRecipeManager());
CoreReflections.field$RecipeManager$featureflagset.set(minecraftRecipeManager(), null);
} catch (ReflectiveOperationException e) {
this.stolenFeatureFlagSet = CoreReflections.methodHandle$RecipeManager$featureflagsetGetter.invokeExact(minecraftRecipeManager());
CoreReflections.methodHandle$RecipeManager$featureflagsetSetter.invokeExact(minecraftRecipeManager(), (Object) null);
} catch (Throwable e) {
this.plugin.logger().warn("Failed to steal feature flag set", e);
}
}
@@ -398,7 +399,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
this.replacedDatapackRecipes.clear();
try {
this.lastDatapackRecipes = scanResources();
} catch (ReflectiveOperationException e) {
} catch (Throwable e) {
this.plugin.logger().warn("Failed to load datapack recipes", e);
}
}
@@ -409,19 +410,19 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
}
@SuppressWarnings("unchecked")
private Map<Key, Recipe<ItemStack>> scanResources() throws ReflectiveOperationException {
Object fileToIdConverter = CoreReflections.method$FileToIdConverter$json.invoke(null, VersionHelper.isOrAbove1_21() ? "recipe" : "recipes");
private Map<Key, Recipe<ItemStack>> scanResources() throws Throwable {
Object fileToIdConverter = CoreReflections.methodHandle$FileToIdConverter$json.invokeExact((String) (VersionHelper.isOrAbove1_21() ? "recipe" : "recipes"));
Object minecraftServer = FastNMS.INSTANCE.method$MinecraftServer$getServer();
Object packRepository = CoreReflections.method$MinecraftServer$getPackRepository.invoke(minecraftServer);
List<Object> selected = (List<Object>) CoreReflections.field$PackRepository$selected.get(packRepository);
Object packRepository = CoreReflections.methodHandle$MinecraftServer$getPackRepository.invokeExact(minecraftServer);
List<Object> selected = (List<Object>) CoreReflections.methodHandle$PackRepository$selectedGetter.invokeExact(packRepository);
List<Object> packResources = new ArrayList<>();
for (Object pack : selected) {
packResources.add(CoreReflections.method$Pack$open.invoke(pack));
packResources.add(CoreReflections.methodHandle$Pack$open.invokeExact(pack));
}
Map<Key, Recipe<ItemStack>> recipes = new HashMap<>();
boolean hasDisabledAny = !Config.disabledVanillaRecipes().isEmpty();
try (AutoCloseable resourceManager = (AutoCloseable) CoreReflections.constructor$MultiPackResourceManager.newInstance(CoreReflections.instance$PackType$SERVER_DATA, packResources)) {
Map<Object, Object> scannedResources = (Map<Object, Object>) CoreReflections.method$FileToIdConverter$listMatchingResources.invoke(fileToIdConverter, resourceManager);
try (AutoCloseable resourceManager = (AutoCloseable) CoreReflections.methodHandle$MultiPackResourceManagerConstructor.invokeExact(CoreReflections.instance$PackType$SERVER_DATA, packResources)) {
Map<Object, Object> scannedResources = (Map<Object, Object>) CoreReflections.methodHandle$FileToIdConverter$listMatchingResources.invokeExact(fileToIdConverter, resourceManager);
for (Map.Entry<Object, Object> entry : scannedResources.entrySet()) {
Key id = extractKeyFromResourceLocation(entry.getKey().toString());
if (Config.disableAllVanillaRecipes()) {
@@ -432,7 +433,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
this.recipesToUnregister.add(new Pair<>(id, false));
continue;
}
Reader reader = (Reader) CoreReflections.method$Resource$openAsReader.invoke(entry.getValue());
Reader reader = (Reader) CoreReflections.methodHandle$Resource$openAsReader.invokeExact(entry.getValue());
JsonObject jsonObject = JsonParser.parseReader(reader).getAsJsonObject();
Key serializerType = Key.of(jsonObject.get("type").getAsString());
RecipeSerializer<ItemStack, ? extends Recipe<ItemStack>> serializer = (RecipeSerializer<ItemStack, ? extends Recipe<ItemStack>>) BuiltInRegistries.RECIPE_SERIALIZER.getValue(serializerType);
@@ -446,7 +447,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
this.plugin.logger().warn("Failed to load data pack recipe " + id + ". Json: " + jsonObject, e);
}
}
} catch (Exception e) {
} catch (Throwable e) {
this.plugin.logger().warn("Unknown error occurred when loading data pack recipes", e);
}
return recipes;
@@ -480,32 +481,32 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
try {
// give flags back on 1.21.2+
if (VersionHelper.isOrAbove1_21_2() && this.stolenFeatureFlagSet != null) {
CoreReflections.field$RecipeManager$featureflagset.set(minecraftRecipeManager(), this.stolenFeatureFlagSet);
CoreReflections.methodHandle$RecipeManager$featureflagsetSetter.invokeExact(minecraftRecipeManager(), (Object) this.stolenFeatureFlagSet);
this.stolenFeatureFlagSet = null;
}
// refresh recipes
if (VersionHelper.isOrAbove1_21_2()) {
CoreReflections.method$RecipeManager$finalizeRecipeLoading.invoke(minecraftRecipeManager());
CoreReflections.methodHandle$RecipeManager$finalizeRecipeLoading.invokeExact(minecraftRecipeManager());
}
// send to players
CoreReflections.method$DedicatedPlayerList$reloadRecipes.invoke(CraftBukkitReflections.field$CraftServer$playerList.get(Bukkit.getServer()));
CoreReflections.methodHandle$DedicatedPlayerList$reloadRecipes.invokeExact(CraftBukkitReflections.methodHandle$CraftServer$playerListGetter.invokeExact(Bukkit.getServer()));
// now we need to remove the fake `exact` choices
if (VersionHelper.isOrAbove1_21_4()) {
for (Object ingredient : MODIFIED_INGREDIENTS) {
CoreReflections.field$Ingredient$itemStacks1_21_4.set(ingredient, null);
CoreReflections.methodHandle$Ingredient$itemStacksSetter.invokeExact(ingredient, (Set<Object>) null);
}
} else if (VersionHelper.isOrAbove1_21_2()) {
for (Object ingredient : MODIFIED_INGREDIENTS) {
CoreReflections.field$Ingredient$itemStacks1_21_2.set(ingredient, null);
CoreReflections.methodHandle$Ingredient$itemStacksSetter.invokeExact(ingredient, (List<Object>) null);
}
}
// clear cache
MODIFIED_INGREDIENTS.clear();
} catch (Exception e) {
} catch (Throwable e) {
this.plugin.logger().warn("Failed to run delayed recipe tasks", e);
}
}

View File

@@ -1,10 +1,12 @@
package net.momirealms.craftengine.bukkit.plugin.reflection.bukkit;
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.BukkitReflectionUtils;
import net.momirealms.craftengine.core.util.ReflectionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.NamespacedKey;
import org.bukkit.Server;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.HumanEntity;
@@ -12,6 +14,8 @@ import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -201,6 +205,17 @@ public final class CraftBukkitReflections {
ReflectionUtils.getDeclaredField(clazz$CraftServer, CoreReflections.clazz$DedicatedPlayerList, 0)
);
public static final MethodHandle methodHandle$CraftServer$playerListGetter;
static {
try {
methodHandle$CraftServer$playerListGetter = ReflectionUtils.unreflectGetter(field$CraftServer$playerList)
.asType(MethodType.methodType(Object.class, Server.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize methodHandle$CraftServer$playerList", e);
}
}
public static final Class<?> clazz$CraftInventoryCrafting = requireNonNull(
ReflectionUtils.getClazz(BukkitReflectionUtils.assembleCBClass("inventory.CraftInventoryCrafting"))
);

View File

@@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.util.ReflectionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import java.io.BufferedReader;
import java.io.Reader;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
@@ -97,6 +98,17 @@ public final class CoreReflections {
public static final Method method$FileToIdConverter$json = requireNonNull(
ReflectionUtils.getStaticMethod(clazz$FileToIdConverter, clazz$FileToIdConverter, String.class)
);
public static final MethodHandle methodHandle$FileToIdConverter$json;
static {
try {
methodHandle$FileToIdConverter$json = ReflectionUtils.unreflectMethod(method$FileToIdConverter$json)
.asType(MethodType.methodType(Object.class, String.class));
} catch (Throwable t) {
throw new ReflectionInitException("Failed to initialize methodHandle$FileToIdConverter$json", t);
}
}
public static final Class<?> clazz$RegistryOps = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
@@ -1900,17 +1912,42 @@ public final class CoreReflections {
)
);
// 1.20.1-1.21.1
public static final Field field$Ingredient$itemStacks1_20_1 =
ReflectionUtils.getDeclaredField(clazz$Ingredient, clazz$ItemStack.arrayType(), 0);
public static final Field field$Ingredient$itemStacks = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$Ingredient,
VersionHelper.isOrAbove1_21_4() ? Set.class : VersionHelper.isOrAbove1_21_2() ? List.class : clazz$ItemStack.arrayType(),
VersionHelper.isOrAbove1_21_4() ? 0 : VersionHelper.isOrAbove1_21_2() ? 1 : 0
)
);
// 1.21.2-1.21.3
public static final Field field$Ingredient$itemStacks1_21_2 =
ReflectionUtils.getDeclaredField(clazz$Ingredient, List.class, 1);
public static final MethodHandle methodHandle$RecipeManager$finalizeRecipeLoading;
public static final MethodHandle methodHandle$RecipeManager$featureflagsetGetter;
public static final MethodHandle methodHandle$RecipeManager$featureflagsetSetter;
public static final MethodHandle methodHandle$Ingredient$itemStacksSetter;
// 1.21.4 paper
public static final Field field$Ingredient$itemStacks1_21_4 =
ReflectionUtils.getDeclaredField(clazz$Ingredient, Set.class, 0);
static {
try {
if (method$RecipeManager$finalizeRecipeLoading != null) {
methodHandle$RecipeManager$finalizeRecipeLoading = ReflectionUtils.unreflectMethod(method$RecipeManager$finalizeRecipeLoading)
.asType(MethodType.methodType(void.class, Object.class));
} else {
methodHandle$RecipeManager$finalizeRecipeLoading = null;
}
if (field$RecipeManager$featureflagset != null) {
methodHandle$RecipeManager$featureflagsetGetter = ReflectionUtils.unreflectGetter(field$RecipeManager$featureflagset)
.asType(MethodType.methodType(Object.class, Object.class));
methodHandle$RecipeManager$featureflagsetSetter = ReflectionUtils.unreflectSetter(field$RecipeManager$featureflagset)
.asType(MethodType.methodType(void.class, Object.class, Object.class));
} else {
methodHandle$RecipeManager$featureflagsetGetter = null;
methodHandle$RecipeManager$featureflagsetSetter = null;
}
methodHandle$Ingredient$itemStacksSetter = ReflectionUtils.unreflectSetter(field$Ingredient$itemStacks)
.asType(MethodType.methodType(void.class, Object.class, VersionHelper.isOrAbove1_21_4() ? Set.class : VersionHelper.isOrAbove1_21_2() ? List.class : Object.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize CoreReflections", e);
}
}
// Since 1.21.2, exact has been removed
public static final Field field$Ingredient$exact =
@@ -1928,7 +1965,7 @@ public final class CoreReflections {
ReflectionUtils.getClazz(BukkitReflectionUtils.assembleMCClass("world.item.crafting.ShapedRecipePattern"));
// 1.20.1-1.20.2
public static final Field field$1_20_1$ShapedRecipe$recipeItems=
public static final Field field$1_20_1$ShapedRecipe$recipeItems =
ReflectionUtils.getDeclaredField(clazz$ShapedRecipe, clazz$NonNullList, 0);
// 1.20.3+
@@ -1992,6 +2029,70 @@ public final class CoreReflections {
Optional.ofNullable(ReflectionUtils.getDeclaredField(clazz$ShapelessRecipe, List.class, 0))
.orElse(ReflectionUtils.getDeclaredField(clazz$ShapelessRecipe, clazz$NonNullList, 0));
public static final MethodHandle methodHandle$1_20_1$ShapedRecipe$recipeItemsGetter;
public static final MethodHandle methodHandle$1_20_3$ShapedRecipe$patternGetter;
public static final MethodHandle methodHandle$ShapedRecipePattern$ingredients1_20_3Getter;
public static final MethodHandle methodHandle$ShapedRecipePattern$ingredients1_21_2Getter;
public static final MethodHandle methodHandle$Ingredient$valuesGetter;
public static final MethodHandle methodHandle$ShapelessRecipe$placementInfoSetter;
public static final MethodHandle methodHandle$ShapedRecipe$placementInfoSetter;
public static final MethodHandle methodHandle$ShapelessRecipe$ingredientsGetter;
static {
try {
if (field$1_20_1$ShapedRecipe$recipeItems != null) {
methodHandle$1_20_1$ShapedRecipe$recipeItemsGetter = ReflectionUtils.unreflectGetter(field$1_20_1$ShapedRecipe$recipeItems)
.asType(MethodType.methodType(List.class, Object.class));
} else {
methodHandle$1_20_1$ShapedRecipe$recipeItemsGetter = null;
}
if (field$1_20_3$ShapedRecipe$pattern != null) {
methodHandle$1_20_3$ShapedRecipe$patternGetter = ReflectionUtils.unreflectGetter(field$1_20_3$ShapedRecipe$pattern)
.asType(MethodType.methodType(Object.class, Object.class));
} else {
methodHandle$1_20_3$ShapedRecipe$patternGetter = null;
}
if (field$ShapedRecipePattern$ingredients1_20_3 != null) {
methodHandle$ShapedRecipePattern$ingredients1_20_3Getter = ReflectionUtils.unreflectGetter(field$ShapedRecipePattern$ingredients1_20_3)
.asType(MethodType.methodType(List.class, Object.class));
} else {
methodHandle$ShapedRecipePattern$ingredients1_20_3Getter = null;
}
if (field$ShapedRecipePattern$ingredients1_21_2 != null) {
methodHandle$ShapedRecipePattern$ingredients1_21_2Getter = ReflectionUtils.unreflectGetter(field$ShapedRecipePattern$ingredients1_21_2)
.asType(MethodType.methodType(List.class, Object.class));
} else {
methodHandle$ShapedRecipePattern$ingredients1_21_2Getter = null;
}
if (field$Ingredient$values != null) {
methodHandle$Ingredient$valuesGetter = ReflectionUtils.unreflectGetter(field$Ingredient$values)
.asType(MethodType.methodType(Object[].class, Object.class));
} else {
methodHandle$Ingredient$valuesGetter = null;
}
if (field$ShapelessRecipe$placementInfo != null) {
methodHandle$ShapelessRecipe$placementInfoSetter = ReflectionUtils.unreflectSetter(field$ShapelessRecipe$placementInfo)
.asType(MethodType.methodType(void.class, Object.class, Object.class));
} else {
methodHandle$ShapelessRecipe$placementInfoSetter = null;
}
if (field$ShapedRecipe$placementInfo != null) {
methodHandle$ShapedRecipe$placementInfoSetter = ReflectionUtils.unreflectSetter(field$ShapedRecipe$placementInfo)
.asType(MethodType.methodType(void.class, Object.class, Object.class));
} else {
methodHandle$ShapedRecipe$placementInfoSetter = null;
}
if (field$ShapelessRecipe$ingredients != null) {
methodHandle$ShapelessRecipe$ingredientsGetter = ReflectionUtils.unreflectGetter(field$ShapelessRecipe$ingredients)
.asType(MethodType.methodType(List.class, Object.class));
} else {
methodHandle$ShapelessRecipe$ingredientsGetter = null;
}
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize CoreReflections", e);
}
}
// require ResourceLocation for 1.20.1-1.21.1
// require ResourceKey for 1.21.2+
public static final Method method$RecipeManager$byKey;
@@ -2093,6 +2194,28 @@ public final class CoreReflections {
.map(it -> ReflectionUtils.getDeclaredField(it, clazz$Ingredient, 0))
.orElse(null);
public static final MethodHandle methodHandle$AbstractCookingRecipe$inputGetter;
public static final MethodHandle methodHandle$SingleItemRecipe$inputGetter;
static {
try {
if (field$AbstractCookingRecipe$input != null) {
methodHandle$AbstractCookingRecipe$inputGetter = ReflectionUtils.unreflectGetter(field$AbstractCookingRecipe$input)
.asType(MethodType.methodType(Object.class, Object.class));
} else {
methodHandle$AbstractCookingRecipe$inputGetter = null;
}
if (field$SingleItemRecipe$input != null) {
methodHandle$SingleItemRecipe$inputGetter = ReflectionUtils.unreflectGetter(field$SingleItemRecipe$input)
.asType(MethodType.methodType(Object.class, Object.class));
} else {
methodHandle$SingleItemRecipe$inputGetter = null;
}
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize methodHandle$SingleItemRecipe$inputGetter", e);
}
}
public static final Field field$AbstractFurnaceBlockEntity$quickCheck = requireNonNull(
ReflectionUtils.getDeclaredField(clazz$AbstractFurnaceBlockEntity, clazz$RecipeManager$CachedCheck, 0)
);
@@ -3019,6 +3142,17 @@ public final class CoreReflections {
ReflectionUtils.getMethod(clazz$Resource, BufferedReader.class)
);
public static final MethodHandle methodHandle$Resource$openAsReader;
static {
try {
methodHandle$Resource$openAsReader = ReflectionUtils.unreflectMethod(method$Resource$openAsReader)
.asType(MethodType.methodType(Reader.class, Object.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to init methodHandle$Resource$openAsReader", e);
}
}
public static final Class<?> clazz$MultiPackResourceManager = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.packs.resources.ResourceManager",
@@ -3063,6 +3197,20 @@ public final class CoreReflections {
ReflectionUtils.getInstanceDeclaredField(clazz$PackRepository, List.class, 0)
);
public static final MethodHandle methodHandle$MinecraftServer$getPackRepository;
public static final MethodHandle methodHandle$PackRepository$selectedGetter;
static {
try {
methodHandle$MinecraftServer$getPackRepository = ReflectionUtils.unreflectMethod(method$MinecraftServer$getPackRepository)
.asType(MethodType.methodType(Object.class, Object.class));
methodHandle$PackRepository$selectedGetter = ReflectionUtils.unreflectGetter(field$PackRepository$selected)
.asType(MethodType.methodType(List.class, Object.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize reflection for methodHandle$MinecraftServer$getPackRepository", e);
}
}
public static final Class<?> clazz$Pack = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.packs.repository.ResourcePackLoader",
@@ -3109,6 +3257,23 @@ public final class CoreReflections {
ReflectionUtils.getMethod(clazz$DedicatedPlayerList, new String[] {"reloadRecipeData", "reloadRecipes"})
);
public static final MethodHandle methodHandle$DedicatedPlayerList$reloadRecipes;
public static final MethodHandle methodHandle$Pack$open;
public static final MethodHandle methodHandle$MultiPackResourceManagerConstructor;
static {
try {
methodHandle$DedicatedPlayerList$reloadRecipes = ReflectionUtils.unreflectMethod(method$DedicatedPlayerList$reloadRecipes)
.asType(MethodType.methodType(void.class, Object.class));
methodHandle$Pack$open = ReflectionUtils.unreflectMethod(method$Pack$open)
.asType(MethodType.methodType(Object.class, Object.class));
methodHandle$MultiPackResourceManagerConstructor = ReflectionUtils.unreflectConstructor(constructor$MultiPackResourceManager)
.asType(MethodType.methodType(AutoCloseable.class, Object.class, List.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to init methodHandle$DedicatedPlayerList$reloadRecipes", e);
}
}
public static final Method method$ServerChunkCache$getGenerator = requireNonNull(
ReflectionUtils.getMethod(clazz$ServerChunkCache, clazz$ChunkGenerator)
);
@@ -3315,6 +3480,17 @@ public final class CoreReflections {
ReflectionUtils.getMethod(clazz$FileToIdConverter, Map.class, new String[]{"listMatchingResources", "a"}, clazz$ResourceManager)
);
public static final MethodHandle methodHandle$FileToIdConverter$listMatchingResources;
static {
try {
methodHandle$FileToIdConverter$listMatchingResources = ReflectionUtils.unreflectMethod(method$FileToIdConverter$listMatchingResources)
.asType(MethodType.methodType(Map.class, Object.class, AutoCloseable.class));
} catch (Exception e) {
throw new ReflectionInitException("Failed to initialize methodHandle$FileToIdConverter$listMatchingResources", e);
}
}
public static final Method method$RegistryOps$create = requireNonNull(
ReflectionUtils.getStaticMethod(clazz$RegistryOps, clazz$RegistryOps, DynamicOps.class, clazz$HolderLookup$Provider)
);