From 8ea696e5343bc52bae3f40c441e0549a6225f447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ampflower=20=F0=9F=8C=BA?= Date: Sat, 28 Sep 2024 00:56:13 -0700 Subject: [PATCH] Add Reflector for 1.20.5-1.20.6 --- gradle.properties | 2 +- libs.versions.toml | 4 +- src/main/java/tfar/fastbench/MixinHooks.java | 14 ++- .../quickbench/internal/Reflector.java | 104 ++++++++++++++++++ src/main/resources/fabric.mod.json | 2 +- 5 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/main/java/tfar/fastbench/quickbench/internal/Reflector.java diff --git a/gradle.properties b/gradle.properties index 60d73ab..ac034bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Mod Properties -projectVersion=4.3.1 +projectVersion=4.3.2 maven_group=gay.ampflower.mod curseforgeId=914551 diff --git a/libs.versions.toml b/libs.versions.toml index 61aa5b9..43500f2 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -2,8 +2,8 @@ # Minecraft minecraft_version = "1.20.4" -minecraft_required = "1.20.3-" -minecraft_compatible = "1.20.3,1.20.4" +minecraft_required = "~1.20.3-" +minecraft_compatible = "1.20.3,1.20.4,1.20.5,1.20.6" fabric_loader = "0.15.+" diff --git a/src/main/java/tfar/fastbench/MixinHooks.java b/src/main/java/tfar/fastbench/MixinHooks.java index 2325707..501c389 100644 --- a/src/main/java/tfar/fastbench/MixinHooks.java +++ b/src/main/java/tfar/fastbench/MixinHooks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Ampflower + * Copyright (c) 2022-2024 Ampflower * Copyright (c) 2020-2021 Tfarcenim * Copyright (c) 2018-2021 Brennan Ward * @@ -26,6 +26,7 @@ package tfar.fastbench; +import net.minecraft.core.RegistryAccess; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -40,10 +41,15 @@ import net.minecraft.world.level.Level; import tfar.fastbench.interfaces.CraftingInventoryDuck; import tfar.fastbench.mixin.ContainerAccessor; +import tfar.fastbench.quickbench.internal.Reflector; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; import java.util.Collections; public class MixinHooks { + private static final MethodHandle recipe$assemble = Reflector.virtual(Recipe.class, "method_8116", + MethodType.methodType(ItemStack.class, Container.class, RegistryAccess.class)); public static boolean hascachedrecipe = false; @@ -58,7 +64,11 @@ public static void slotChangedCraftingGrid(Level level, CraftingContainer inv, R if (recipe == null || !recipe.value().matches(inv, level)) recipe = findRecipe(inv, level); if (recipe != null) { - itemstack = recipe.value().assemble(inv, level.registryAccess()); + try { + itemstack = (ItemStack) recipe$assemble.invoke(recipe.value(), inv, level.registryAccess()); + } catch (Throwable t) { + throw new AssertionError(t); + } } result.setItem(0, itemstack); diff --git a/src/main/java/tfar/fastbench/quickbench/internal/Reflector.java b/src/main/java/tfar/fastbench/quickbench/internal/Reflector.java new file mode 100644 index 0000000..6e96d3a --- /dev/null +++ b/src/main/java/tfar/fastbench/quickbench/internal/Reflector.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Ampflower + * + * This software is subject to the terms of either the MIT or CC0-1.0 Licenses. + * If a copy was not distributed with this file, you can obtain one at + * https://github.com/Modflower/QuickBench/blob/trunk/LICENSE-MIT + * https://github.com/Modflower/QuickBench/blob/trunk/LICENSE-CC0 + * + * Sources: + * - https://github.com/Modflower/QuickBench + * + * SPDX-License-Identifier: MIT OR CC0-1.0 + * + * Additional details are outlined in LICENSE.md, which you can obtain at + * https://github.com/Modflower/QuickBench/blob/trunk/LICENSE.md + */ + +package tfar.fastbench.quickbench.internal; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.MappingResolver; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * @author Ampflower + * @since 4.3.2 + **/ +public final class Reflector { + private static final String namespace = "intermediary"; + + private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); + private static final MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); + private static final boolean production = namespace.equals(resolver.getCurrentRuntimeNamespace()); + + private static String unmap(Class clazz) { + if (clazz.isPrimitive()) { + return clazz.descriptorString(); + } + return 'L' + unmapClassName(clazz).replace('.', '/') + ';'; + } + + private static String unmapClassName(Class clazz) { + return resolver.unmapClassName(namespace, clazz.getName()); + } + + private static boolean virtual(Method method, String reference, MethodType signature) { + if (!signature(method, signature)) { + return false; + } + if (production) { + return reference.equals(method.getName()); + } + + final var parameters = method.getParameterTypes(); + final var unmap = new String[method.getParameterCount()]; + for (int i = 0; i < unmap.length; i++) { + unmap[i] = unmap(parameters[i]); + } + + return resolver.mapMethodName(namespace, + unmapClassName(method.getDeclaringClass()), + reference, + '(' + String.join("", unmap) + ')' + unmap(method.getReturnType())) + .equals(method.getName()); + } + + private static boolean signature(Method method, MethodType signature) { + if (signature.parameterCount() != method.getParameterCount()) { + return false; + } + if (!signature.returnType().equals(method.getReturnType())) { + return false; + } + final var parameters = method.getParameterTypes(); + for (int i = 0; i < signature.parameterCount(); i++) { + if (!parameters[i].isAssignableFrom(signature.parameterType(i))) { + return false; + } + } + return true; + } + + public static MethodHandle virtual(Class clazz, String reference, MethodType signature) { + try { + for (final var method : clazz.getMethods()) { + if (Modifier.isStatic(method.getModifiers())) { + continue; + } + if (!virtual(method, reference, signature)) { + continue; + } + return lookup.unreflect(method); + } + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } + throw new AssertionError(clazz + " has no such method: " + reference + signature); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 7f74bba..701f5b4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,7 +26,7 @@ ], "depends": { "fabricloader": ">=0.15.11", - "minecraft": ">=${minecraftRequired}" + "minecraft": "${minecraftRequired}" }, "custom": { "modmenu": {