From f611017e65d5a8d2190fa7a111fca17d453b2292 Mon Sep 17 00:00:00 2001 From: FalsePattern Date: Sat, 18 Nov 2023 14:46:58 +0100 Subject: [PATCH] Add OptiFine transformer hook --- README.MD | 1 + gradle.properties | 2 +- .../lib/internal/asm/FPTransformer.java | 5 ++ .../OptiFineTransformerHooksImpl.java | 73 +++++++++++++++++++ .../WrappedOptiFineClassTransformer.java | 38 ++++++++++ .../optifine/OptiFineTransformerHooks.java | 39 ++++++++++ 6 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/falsepattern/lib/internal/impl/optifine/OptiFineTransformerHooksImpl.java create mode 100644 src/main/java/com/falsepattern/lib/internal/impl/optifine/WrappedOptiFineClassTransformer.java create mode 100644 src/main/java/com/falsepattern/lib/optifine/OptiFineTransformerHooks.java diff --git a/README.MD b/README.MD index 81fd46c..79cc27f 100644 --- a/README.MD +++ b/README.MD @@ -9,6 +9,7 @@ A library for 1.7.10 with lots of useful stuff, licensed under the LGPLv3 licens | [dependencies](src/main/java/com/falsepattern/lib/dependencies) | Runtime dependency loader which uses Maven (DEPRECATED, see [The new data-driven dependency format](src/main/resources/DEPENDENCIES.md) | | [mapping](src/main/java/com/falsepattern/lib/mapping) | Notch-SRG-MCP name mapping helper code | | [mixin](src/main/java/com/falsepattern/lib/mixin) | Mixin loader plugin boilerplate code | +| [optifine](src/main/java/com/falsepattern/lib/optifine) | Tools for messing with OptiFine | | [text](src/main/java/com/falsepattern/lib/text) | Better Chat and GUI text processing | | [toasts](src/main/java/com/falsepattern/lib/toasts) | The toast system from newer versions, with some extras | | [util](src/main/java/com/falsepattern/lib/util) | Additional utilities that do not fit the above categories, see below for more information | diff --git a/gradle.properties b/gradle.properties index cda3efa..aa5ce11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ apiPackage = # Packages separated by semicolons # ExampleValue: apiPackages = foo;bar;baz # ... foo;bar;baz -> com.myname.mymodid.foo;com.myname.mymodid.bar;com.myname.mymodid.baz -apiPackages = asm;compat;config;dependencies;mapping;mixin;text;toasts;util +apiPackages = asm;compat;config;dependencies;mapping;mixin;optifine;text;toasts;util # Same as apiPackages, but does not pull in inner packages apiPackagesNoRecurse = . diff --git a/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java index 7d737a8..6e6fd68 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java @@ -29,6 +29,7 @@ import com.falsepattern.lib.internal.asm.transformers.ConfigOrderTransformer; import com.falsepattern.lib.internal.asm.transformers.GasStationValidatorTransformer; import com.falsepattern.lib.internal.asm.transformers.IMixinPluginTransformer; import com.falsepattern.lib.internal.asm.transformers.ITypeDiscovererTransformer; +import com.falsepattern.lib.internal.impl.optifine.OptiFineTransformerHooksImpl; import lombok.Getter; import lombok.experimental.Accessors; import org.apache.logging.log4j.LogManager; @@ -48,6 +49,10 @@ public class FPTransformer implements SmartTransformer { @Getter private final Logger logger = LOG; + static { + OptiFineTransformerHooksImpl.init(); + } + public FPTransformer() { transformers = Arrays.asList(new IMixinPluginTransformer(), new ITypeDiscovererTransformer(), diff --git a/src/main/java/com/falsepattern/lib/internal/impl/optifine/OptiFineTransformerHooksImpl.java b/src/main/java/com/falsepattern/lib/internal/impl/optifine/OptiFineTransformerHooksImpl.java new file mode 100644 index 0000000..5358a2d --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/impl/optifine/OptiFineTransformerHooksImpl.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022-2023 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.lib.internal.impl.optifine; + +import com.falsepattern.lib.internal.Share; +import lombok.val; + +import net.minecraft.launchwrapper.IClassTransformer; +import net.minecraft.launchwrapper.Launch; +import net.minecraft.launchwrapper.LaunchClassLoader; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class OptiFineTransformerHooksImpl { + private static final Set disabledPatches = new HashSet<>(); + public static void init() { + Field tField; + try { + tField = LaunchClassLoader.class.getDeclaredField("transformers"); + } catch (NoSuchFieldException e) { + Share.LOG.error("Could not retrieve transformers field", e); + return; + } + tField.setAccessible(true); + List transformers; + try { + transformers = (List)tField.get(Launch.classLoader); + } catch (IllegalAccessException e) { + Share.LOG.error("Could not retrieve transformers list", e); + return; + } + for (int i = 0; i < transformers.size(); i++) { + val transformer = transformers.get(i); + System.out.println(transformer.getClass().getName()); + if (transformer.getClass().getName().equals("optifine.OptiFineClassTransformer")) { + Share.LOG.info("Attaching OptiFine ASM transformer hooks"); + transformers.set(i, new WrappedOptiFineClassTransformer(transformer)); + } + } + } + + public static void disableOptiFinePatch(String patchName) { + disabledPatches.add(patchName); + } + + public static boolean isDisabled(String className) { + return disabledPatches.contains(className); + } +} diff --git a/src/main/java/com/falsepattern/lib/internal/impl/optifine/WrappedOptiFineClassTransformer.java b/src/main/java/com/falsepattern/lib/internal/impl/optifine/WrappedOptiFineClassTransformer.java new file mode 100644 index 0000000..272b5ca --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/impl/optifine/WrappedOptiFineClassTransformer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022-2023 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.lib.internal.impl.optifine; + +import lombok.RequiredArgsConstructor; + +import net.minecraft.launchwrapper.IClassTransformer; + +@RequiredArgsConstructor +public class WrappedOptiFineClassTransformer implements IClassTransformer { + private final IClassTransformer optiFineTransformer; + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (OptiFineTransformerHooksImpl.isDisabled(name)) { + return basicClass; + } + return optiFineTransformer.transform(name, transformedName, basicClass); + } +} diff --git a/src/main/java/com/falsepattern/lib/optifine/OptiFineTransformerHooks.java b/src/main/java/com/falsepattern/lib/optifine/OptiFineTransformerHooks.java new file mode 100644 index 0000000..e370536 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/optifine/OptiFineTransformerHooks.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022-2023 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.lib.optifine; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.impl.optifine.OptiFineTransformerHooksImpl; + +/** + * A utility for manipulating OptiFine's patches. + * If you have a mod that injects code that would otherwise conflict with OptiFine, and you have provably tested that + * removing certain OptiFine patches from the jar does NOT break anything, you may use this class to disable them + * without having to do jar file edits. + */ +@StableAPI(since = "1.0.0") +public class OptiFineTransformerHooks { + @StableAPI.Expose + public static void disableOptiFinePatch(String patchName) { + OptiFineTransformerHooksImpl.disableOptiFinePatch(patchName); + } +}