From bcc1b04e6bf9db60db7d5bf8284a615977c18d4f Mon Sep 17 00:00:00 2001 From: octarine-noise Date: Sat, 2 Mar 2019 12:00:28 +0100 Subject: [PATCH] Optifine dev wrapper must be written in Java --- .../OptifineTransformerDevWrapper.java | 65 +++++++++++++++++++ .../optifine/OptifineTweakerDevWrapper.java | 28 ++++++++ .../optifine/OptifineTweakerDevWrapper.kt | 38 ----------- 3 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 src/main/java/optifine/OptifineTransformerDevWrapper.java create mode 100644 src/main/java/optifine/OptifineTweakerDevWrapper.java delete mode 100644 src/main/kotlin/optifine/OptifineTweakerDevWrapper.kt diff --git a/src/main/java/optifine/OptifineTransformerDevWrapper.java b/src/main/java/optifine/OptifineTransformerDevWrapper.java new file mode 100644 index 0000000..5ab9374 --- /dev/null +++ b/src/main/java/optifine/OptifineTransformerDevWrapper.java @@ -0,0 +1,65 @@ +package optifine; + +import net.minecraft.launchwrapper.IClassTransformer; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class OptifineTransformerDevWrapper implements IClassTransformer { + + public static String OPTIFINE_CLASSNAME = "optifine/OptiFineClassTransformer.class"; + private ZipFile ofZip = null; + + public OptifineTransformerDevWrapper() { + Stream loaderSources = Arrays.stream(((URLClassLoader) getClass().getClassLoader()).getURLs()); + Optional optifineURL = loaderSources.filter(this::isOptifineJar).findFirst(); + optifineURL.ifPresent(url -> ofZip = getZip(url)); + } + + private ZipFile getZip(URL url) { + try { + return new ZipFile(new File(url.toURI())); + } catch (Exception e) { + return null; + } + } + + private boolean isOptifineJar(URL url) { + ZipFile zip = getZip(url); + return zip != null && zip.getEntry(OPTIFINE_CLASSNAME) != null; + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (ofZip == null) return basicClass; + ZipEntry replacement = ofZip.getEntry(name.replace(".", "/") + ".class"); + if (replacement == null) return basicClass; + + try { + return readAll(ofZip.getInputStream(replacement)); + } catch (IOException e) { + return basicClass; + } + } + + private byte[] readAll(InputStream is) throws IOException { + byte[] buf = new byte[4096]; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int len; + do { + len = is.read(buf, 0, 4096); + if (len > 0) bos.write(buf, 0, len); + } while (len > -1); + is.close(); + return bos.toByteArray(); + } +} diff --git a/src/main/java/optifine/OptifineTweakerDevWrapper.java b/src/main/java/optifine/OptifineTweakerDevWrapper.java new file mode 100644 index 0000000..65025cd --- /dev/null +++ b/src/main/java/optifine/OptifineTweakerDevWrapper.java @@ -0,0 +1,28 @@ +package optifine; + +import net.minecraft.launchwrapper.ITweaker; +import net.minecraft.launchwrapper.LaunchClassLoader; + +import java.io.File; +import java.util.List; + +public class OptifineTweakerDevWrapper implements ITweaker { + @Override + public void acceptOptions(List args, File gameDir, File assetsDir, String profile) { + } + + @Override + public void injectIntoClassLoader(LaunchClassLoader classLoader) { + classLoader.registerTransformer("optifine.OptifineTransformerDevWrapper"); + } + + @Override + public String getLaunchTarget() { + return "net.minecraft.client.main.Main"; + } + + @Override + public String[] getLaunchArguments() { + return new String[0]; + } +} diff --git a/src/main/kotlin/optifine/OptifineTweakerDevWrapper.kt b/src/main/kotlin/optifine/OptifineTweakerDevWrapper.kt deleted file mode 100644 index 897f6a9..0000000 --- a/src/main/kotlin/optifine/OptifineTweakerDevWrapper.kt +++ /dev/null @@ -1,38 +0,0 @@ -package optifine - -import mods.octarinecore.tryDefault -import net.minecraft.launchwrapper.IClassTransformer -import net.minecraft.launchwrapper.ITweaker -import net.minecraft.launchwrapper.LaunchClassLoader -import java.io.File -import java.net.URLClassLoader -import java.util.zip.ZipFile - -class OptifineTweakerDevWrapper : ITweaker { - override fun acceptOptions(p0: MutableList?, p1: File?, p2: File?, p3: String?) { } - override fun getLaunchArguments(): Array? = Array(0) {""} - override fun getLaunchTarget() = "net.minecraft.client.main.Main" - override fun injectIntoClassLoader(classLoader: LaunchClassLoader) { - classLoader.registerTransformer("optifine.OptifineTransformerDevWrapper") - } -} - -/** - * Replacement for OptiFine's class transformer. Implements the pre-1.8.x-H5 way of operation. - * - * This class is only used in development to debug cross-mod issues with Optifine, and - * is not part of the release! - */ -class OptifineTransformerDevWrapper : IClassTransformer { - - val ofZip = (this.javaClass.classLoader as? URLClassLoader)?.urLs?.find { - val zipFile = tryDefault(null) { ZipFile(File(it.toURI())) } - zipFile?.getEntry("optifine/OptiFineClassTransformer.class") != null - }?.let { ZipFile(File(it.toURI())) } - - /** - * Load replacement classes from the OptiFine Jar. - */ - override fun transform(name: String?, transformedName: String?, classData: ByteArray?) = - ofZip?.getEntry(name?.replace(".", "/") + ".class")?.let { ofZip.getInputStream(it).readBytes() } ?: classData -}