81 lines
3.2 KiB
Java
81 lines
3.2 KiB
Java
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.InputStream;
|
|
import java.nio.file.Files;
|
|
import java.util.Enumeration;
|
|
import java.util.jar.Attributes;
|
|
import java.util.jar.JarEntry;
|
|
import java.util.jar.JarFile;
|
|
import java.util.jar.JarOutputStream;
|
|
import java.util.jar.Manifest;
|
|
|
|
import org.objectweb.asm.ClassReader;
|
|
import org.objectweb.asm.ClassWriter;
|
|
import org.objectweb.asm.commons.ClassRemapper;
|
|
import org.objectweb.asm.commons.Remapper;
|
|
|
|
/**
|
|
* Baut die Agent-Datei: eigene Klassen + ASM, dabei org/objectweb/asm nach
|
|
* de/aeromc/capes/asm umbenannt. So kann das ASM von Fabric/Forge (das auf
|
|
* demselben Klassenpfad liegt) nie mit unserem verwechselt werden.
|
|
*
|
|
* Aufruf: java Shade <ziel.jar> <klassenordner> <asm.jar>
|
|
*/
|
|
public class Shade {
|
|
static final Remapper UMBENENNEN = new Remapper() {
|
|
@Override
|
|
public String map(String name) {
|
|
return name.startsWith("org/objectweb/asm/") ? "de/aeromc/capes/asm/" + name.substring(18) : name;
|
|
}
|
|
};
|
|
|
|
static byte[] umbenennen(byte[] klasse) {
|
|
ClassReader r = new ClassReader(klasse);
|
|
ClassWriter w = new ClassWriter(0);
|
|
r.accept(new ClassRemapper(w, UMBENENNEN), 0);
|
|
return w.toByteArray();
|
|
}
|
|
|
|
static byte[] lies(InputStream in) throws Exception {
|
|
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
|
byte[] p = new byte[8192];
|
|
int n;
|
|
while ((n = in.read(p)) > 0) b.write(p, 0, n);
|
|
return b.toByteArray();
|
|
}
|
|
|
|
public static void main(String[] a) throws Exception {
|
|
Manifest mf = new Manifest();
|
|
Attributes at = mf.getMainAttributes();
|
|
at.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
|
at.putValue("Premain-Class", "de.aeromc.capes.Agent");
|
|
at.putValue("Agent-Class", "de.aeromc.capes.Agent");
|
|
at.putValue("Can-Retransform-Classes", "false");
|
|
at.putValue("Implementation-Title", "AeroMC Umhang-Agent");
|
|
try (JarOutputStream out = new JarOutputStream(new FileOutputStream(a[0]), mf)) {
|
|
// eigene Klassen
|
|
File basis = new File(a[1]);
|
|
for (File f : Files.walk(basis.toPath()).map(p -> p.toFile()).filter(f -> f.getName().endsWith(".class")).toArray(File[]::new)) {
|
|
String name = basis.toPath().relativize(f.toPath()).toString().replace('\\', '/');
|
|
out.putNextEntry(new JarEntry(name));
|
|
out.write(umbenennen(Files.readAllBytes(f.toPath())));
|
|
out.closeEntry();
|
|
}
|
|
// ASM (umbenannt), ohne Modul-Infos und Signaturen
|
|
try (JarFile asm = new JarFile(a[2])) {
|
|
Enumeration<JarEntry> e = asm.entries();
|
|
while (e.hasMoreElements()) {
|
|
JarEntry je = e.nextElement();
|
|
String n = je.getName();
|
|
if (!n.startsWith("org/objectweb/asm/") || !n.endsWith(".class")) continue;
|
|
byte[] neu = umbenennen(lies(asm.getInputStream(je)));
|
|
out.putNextEntry(new JarEntry("de/aeromc/capes/asm/" + n.substring(18)));
|
|
out.write(neu);
|
|
out.closeEntry();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|