From dc343ce1bfdd56c47b09f965e1b7c4b8ed135789 Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 25 Nov 2021 17:20:59 +0100 Subject: [PATCH] Some breaking stuff before 1.18 --- .../libjf/interfaces/LazySupplier.java | 30 +++++++++++++ .../manipulation/api/UserResourceEvents.java | 45 ++++++++++++++----- .../manipulation/impl/ResourcePackHook.java | 13 ++++-- .../impl/ResourcePackHookPatch.java | 8 ++-- .../manipulation/test/TestEntrypoint.java | 4 +- .../libjf/unsafe/asm/patch/MethodPatch.java | 3 +- .../patch/method/MethodReplacementPatch.java | 3 +- .../modification/MethodModificationPatch.java | 2 +- 8 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 libjf-base/src/main/java/io/gitlab/jfronny/libjf/interfaces/LazySupplier.java diff --git a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/interfaces/LazySupplier.java b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/interfaces/LazySupplier.java new file mode 100644 index 0000000..caf9982 --- /dev/null +++ b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/interfaces/LazySupplier.java @@ -0,0 +1,30 @@ +package io.gitlab.jfronny.libjf.interfaces; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; +import java.util.function.Supplier; + +public class LazySupplier implements Supplier { + private final Supplier supplier; + private T cache = null; + public LazySupplier(@NotNull T value) { + this.supplier = () -> { + throw new RuntimeException("Supplier should have never been called"); + }; + cache = value; + } + public LazySupplier(@NotNull Supplier supplier) { + this.supplier = supplier; + } + + @Override @Contract(pure = true) @NotNull public T get() { + if (cache == null) cache = supplier.get(); + return cache; + } + + @Contract(pure = true) @NotNull public LazySupplier andThen(@NotNull Function, T> after) { + return new LazySupplier<>(() -> after.apply(this)); + } +} diff --git a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java index d210515..a38ec0c 100644 --- a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java +++ b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java @@ -1,6 +1,7 @@ package io.gitlab.jfronny.libjf.data.manipulation.api; import io.gitlab.jfronny.libjf.data.manipulation.impl.ResourcePackHook; +import io.gitlab.jfronny.libjf.interfaces.LazySupplier; import io.gitlab.jfronny.libjf.interfaces.ThrowingRunnable; import io.gitlab.jfronny.libjf.interfaces.ThrowingSupplier; import net.fabricmc.fabric.api.event.Event; @@ -13,7 +14,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.function.Predicate; +import java.util.function.Supplier; +@SuppressWarnings("unused") public class UserResourceEvents { public static TVal disable(ThrowingSupplier then) throws TEx { try { @@ -36,49 +39,67 @@ public class UserResourceEvents { public static final Event CONTAINS = EventFactory.createArrayBacked(Contains.class, (listeners) -> (type, id, previous, pack) -> { + LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly for (Contains listener : listeners) { - previous = listener.contains(type, id, previous, pack); + lazy = lazy.andThen(supplier -> listener.contains(type, id, supplier, pack)); } - return previous; + return lazy.get(); }); public static final Event FIND_RESOURCE = EventFactory.createArrayBacked(FindResource.class, (listeners) -> ((type, namespace, prefix, maxDepth, pathFilter, previous, pack) -> { + LazySupplier> lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly for (FindResource listener : listeners) { - previous = listener.findResources(type, namespace, prefix, maxDepth, pathFilter, previous, pack); + lazy = lazy.andThen(supplier -> listener.findResources(type, namespace, prefix, maxDepth, pathFilter, supplier, pack)); } - return previous; + return lazy.get(); })); public static final Event OPEN = EventFactory.createArrayBacked(Open.class, (listeners) -> ((type, id, previous, pack) -> { + LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly for (Open listener : listeners) { - previous = listener.open(type, id, previous, pack); + lazy = lazy.andThen(supplier -> { + try { + return listener.open(type, id, supplier, pack); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + }); } - return previous; + return lazy.get(); })); public static final Event OPEN_ROOT = EventFactory.createArrayBacked(OpenRoot.class, (listeners) -> ((fileName, previous, pack) -> { + LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly for (OpenRoot listener : listeners) { - previous = listener.openRoot(fileName, previous, pack); + lazy = lazy.andThen(supplier -> { + try { + return listener.openRoot(fileName, supplier, pack); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + }); } - return previous; + return lazy.get(); })); public interface Contains { - boolean contains(ResourceType type, Identifier id, boolean previous, ResourcePack pack); + boolean contains(ResourceType type, Identifier id, Supplier previous, ResourcePack pack); } public interface FindResource { - Collection findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate pathFilter, Collection previous, ResourcePack pack); + Collection findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate pathFilter, Supplier> previous, ResourcePack pack); } public interface Open { - InputStream open(ResourceType type, Identifier id, InputStream previous, ResourcePack pack) throws IOException; + InputStream open(ResourceType type, Identifier id, Supplier previous, ResourcePack pack) throws IOException; } public interface OpenRoot { - InputStream openRoot(String fileName, InputStream previous, ResourcePack pack) throws IOException; + InputStream openRoot(String fileName, Supplier previous, ResourcePack pack) throws IOException; } } diff --git a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHook.java b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHook.java index 965781f..b03d653 100644 --- a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHook.java +++ b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHook.java @@ -2,9 +2,11 @@ package io.gitlab.jfronny.libjf.data.manipulation.impl; import io.gitlab.jfronny.libjf.ResourcePath; import io.gitlab.jfronny.libjf.data.manipulation.api.UserResourceEvents; +import io.gitlab.jfronny.libjf.interfaces.LazySupplier; import net.minecraft.resource.ResourcePack; import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.ApiStatus; import java.io.FileNotFoundException; import java.io.IOException; @@ -15,23 +17,26 @@ import java.util.Map; import java.util.function.Predicate; @SuppressWarnings("unused") +@ApiStatus.Internal public class ResourcePackHook { private static final Map disabled = new HashMap<>(); + @ApiStatus.Internal public static void setDisabled(boolean disabled) { ResourcePackHook.disabled.put(Thread.currentThread().getId(), disabled); } + @ApiStatus.Internal public static boolean isDisabled() { return disabled.getOrDefault(Thread.currentThread().getId(), false); } public static boolean hookContains(boolean value, ResourcePack pack, ResourceType type, Identifier id) { - return isDisabled() ? value : UserResourceEvents.CONTAINS.invoker().contains(type, id, value, pack); + return isDisabled() ? value : UserResourceEvents.CONTAINS.invoker().contains(type, id, new LazySupplier<>(value), pack); } public static InputStream hookOpen(InputStream value, ResourcePack pack, ResourceType type, Identifier id) throws IOException { if (isDisabled()) return value; - InputStream is = UserResourceEvents.OPEN.invoker().open(type, id, value, pack); + InputStream is = UserResourceEvents.OPEN.invoker().open(type, id, new LazySupplier<>(value), pack); if (is == null) throw new FileNotFoundException(new ResourcePath(type, id).getName() + "CN"); return is; @@ -46,12 +51,12 @@ public class ResourcePackHook { } } public static Collection hookFindResources(Collection value, ResourcePack pack, ResourceType type, String namespace, String prefix, int maxDepth, Predicate pathFilter) { - return isDisabled() ? value : UserResourceEvents.FIND_RESOURCE.invoker().findResources(type, namespace, prefix, maxDepth, pathFilter, value, pack); + return isDisabled() ? value : UserResourceEvents.FIND_RESOURCE.invoker().findResources(type, namespace, prefix, maxDepth, pathFilter, new LazySupplier<>(value), pack); } public static InputStream hookOpenRoot(InputStream value, ResourcePack pack, String fileName) throws IOException { if (isDisabled()) return value; InputStream is = value; - is = UserResourceEvents.OPEN_ROOT.invoker().openRoot(fileName, is, pack); + is = UserResourceEvents.OPEN_ROOT.invoker().openRoot(fileName, new LazySupplier<>(is), pack); if (is == null) throw new FileNotFoundException(fileName); return is; diff --git a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHookPatch.java b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHookPatch.java index 4596605..137c929 100644 --- a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHookPatch.java +++ b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHookPatch.java @@ -27,21 +27,21 @@ public class ResourcePackHookPatch implements AsmConfig { // https://maven.fabricmc.net/docs/yarn-21w38a+build.9/net/minecraft/resource/ResourcePack.html return Set.of(new InterfaceImplTargetPatch(TARGET_CLASS_INTERMEDIARY, new MethodModificationPatch(TARGET_CLASS_INTERMEDIARY, Set.of( // open root - new MethodModificationPatch.MethodDescriptorPatch("method_14410", "(Ljava/lang/String;)Ljava/io/InputStream;", method -> { + new MethodModificationPatch.MethodDescriptorPatch("method_14410", "(Ljava/lang/String;)Ljava/io/InputStream;", (method, klazz) -> { catchEx(method, "hookOpenRootEx", new String[]{"java/lang/String"}); hookReturn(method, "hookOpenRoot", "Ljava/io/InputStream;", new String[]{"java/lang/String"}); }), // open - new MethodModificationPatch.MethodDescriptorPatch("method_14405", "(Lnet/minecraft/class_3264;Lnet/minecraft/class_2960;)Ljava/io/InputStream;", method -> { + new MethodModificationPatch.MethodDescriptorPatch("method_14405", "(Lnet/minecraft/class_3264;Lnet/minecraft/class_2960;)Ljava/io/InputStream;", (method, klazz) -> { catchEx(method, "hookOpenEx", new String[]{"net/minecraft/class_3264", "net/minecraft/class_2960"}); hookReturn(method, "hookOpen", "Ljava/io/InputStream;", new String[]{"net/minecraft/class_3264", "net/minecraft/class_2960"}); }), // find resource - new MethodModificationPatch.MethodDescriptorPatch("method_14408", "(Lnet/minecraft/class_3264;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;", method -> { + new MethodModificationPatch.MethodDescriptorPatch("method_14408", "(Lnet/minecraft/class_3264;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;", (method, klazz) -> { hookReturn(method, "hookFindResources", "Ljava/util/Collection;", new String[]{"net/minecraft/class_3264", "java/lang/String", "java/lang/String", "I", "java/util/function/Predicate"}); }), // contains - new MethodModificationPatch.MethodDescriptorPatch("method_14411", "(Lnet/minecraft/class_3264;Lnet/minecraft/class_2960;)Z", method -> { + new MethodModificationPatch.MethodDescriptorPatch("method_14411", "(Lnet/minecraft/class_3264;Lnet/minecraft/class_2960;)Z", (method, klazz) -> { hookReturn(method, "hookContains", "Z", new String[]{"net/minecraft/class_3264", "net/minecraft/class_2960"}); }) )))); diff --git a/libjf-data-manipulation-v0/src/testmod/java/io/gitlab/jfronny/libjf/data/manipulation/test/TestEntrypoint.java b/libjf-data-manipulation-v0/src/testmod/java/io/gitlab/jfronny/libjf/data/manipulation/test/TestEntrypoint.java index 11e994f..021adfb 100644 --- a/libjf-data-manipulation-v0/src/testmod/java/io/gitlab/jfronny/libjf/data/manipulation/test/TestEntrypoint.java +++ b/libjf-data-manipulation-v0/src/testmod/java/io/gitlab/jfronny/libjf/data/manipulation/test/TestEntrypoint.java @@ -15,13 +15,13 @@ public class TestEntrypoint implements ModInitializer { if (pack instanceof DirectoryResourcePack) { LibJf.LOGGER.info(pack.getName() + " opened " + type.name() + "/" + id.toString()); } - return previous; + return previous.get(); }); UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> { if (pack instanceof DirectoryResourcePack) { return false; } - return previous; + return previous.get(); }); RecipeUtil.removeRecipeFor(Items.DIAMOND_SWORD); } diff --git a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/MethodPatch.java b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/MethodPatch.java index f37e773..58aa80a 100644 --- a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/MethodPatch.java +++ b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/MethodPatch.java @@ -1,7 +1,8 @@ package io.gitlab.jfronny.libjf.unsafe.asm.patch; +import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; public interface MethodPatch { - void apply(MethodNode method); + void apply(MethodNode method, ClassNode klazz); } diff --git a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/method/MethodReplacementPatch.java b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/method/MethodReplacementPatch.java index 5284b8b..4c36534 100644 --- a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/method/MethodReplacementPatch.java +++ b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/method/MethodReplacementPatch.java @@ -2,6 +2,7 @@ package io.gitlab.jfronny.libjf.unsafe.asm.patch.method; import io.gitlab.jfronny.libjf.unsafe.asm.patch.MethodPatch; import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.MethodNode; @@ -12,7 +13,7 @@ public class MethodReplacementPatch implements MethodPatch { } @Override - public void apply(MethodNode method) { + public void apply(MethodNode method, ClassNode klazz) { method.instructions.clear(); InsnList clone = new InsnList(); for (AbstractInsnNode instruction : instructions) { diff --git a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/modification/MethodModificationPatch.java b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/modification/MethodModificationPatch.java index f7e7a26..02df710 100644 --- a/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/modification/MethodModificationPatch.java +++ b/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/patch/modification/MethodModificationPatch.java @@ -31,7 +31,7 @@ public class MethodModificationPatch implements Patch { for (MethodNode method : klazz.methods) { if (patches.containsKey(method.name)) { if (AsmTransformer.INSTANCE.debugLogsEnabled()) LibJf.LOGGER.info("Patching " + method.name); - patches.get(method.name).apply(method); + patches.get(method.name).apply(method, klazz); } } }