Optifine dev wrapper must be written in Java

This commit is contained in:
octarine-noise
2019-03-02 12:00:28 +01:00
parent cbee4916ed
commit bcc1b04e6b
3 changed files with 93 additions and 38 deletions

View File

@@ -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<URL> loaderSources = Arrays.stream(((URLClassLoader) getClass().getClassLoader()).getURLs());
Optional<URL> 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();
}
}

View File

@@ -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<String> 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];
}
}

View File

@@ -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<String>?, p1: File?, p2: File?, p3: String?) { }
override fun getLaunchArguments(): Array<out String>? = Array<String>(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
}