Upload via GUI (138 Dateien)
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package de.aeromc.capes;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
/**
|
||||
* Baut YggdrasilMinecraftSessionService beim Laden um: vor jedem "return" der
|
||||
* Textur-Methode wird das Ergebnis an den Nachschlage-Dienst gereicht, der den
|
||||
* AeroMC-Umhang einsetzt.
|
||||
*
|
||||
* authlib 5+ (Minecraft 1.20.2 … 26.x):
|
||||
* MinecraftProfileTextures unpackTextures(Property)
|
||||
* authlib 1–4 (Minecraft 1.8 … 1.20.1):
|
||||
* Map<Type, MinecraftProfileTexture> getTextures(GameProfile, boolean)
|
||||
*
|
||||
* Eingefügt wird nur geradliniger Code ohne Sprünge – die vorhandenen
|
||||
* Stack-Map-Frames bleiben gültig, es muss nichts neu berechnet werden.
|
||||
*/
|
||||
final class Umbau implements ClassFileTransformer {
|
||||
static final String ZIEL = "com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService";
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader loader, String name, Class<?> umdefiniert, ProtectionDomain pd, byte[] klasse) {
|
||||
if (!ZIEL.equals(name) || umdefiniert != null) return null;
|
||||
try {
|
||||
ClassReader leser = new ClassReader(klasse);
|
||||
ClassWriter schreiber = new ClassWriter(leser, ClassWriter.COMPUTE_MAXS);
|
||||
final int[] umgebaut = {0};
|
||||
leser.accept(new ClassVisitor(Opcodes.ASM9, schreiber) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int zugriff, String mname, String desc, String sig, String[] ausn) {
|
||||
MethodVisitor mv = super.visitMethod(zugriff, mname, desc, sig, ausn);
|
||||
if ((zugriff & Opcodes.ACC_STATIC) != 0) return mv;
|
||||
String rueckgabe = null;
|
||||
if ("unpackTextures".equals(mname) && desc.startsWith("(Lcom/mojang/authlib/properties/Property;)L")) {
|
||||
rueckgabe = desc.substring(desc.indexOf(")L") + 2, desc.length() - 1);
|
||||
} else if ("getTextures".equals(mname) && desc.equals("(Lcom/mojang/authlib/GameProfile;Z)Ljava/util/Map;")) {
|
||||
rueckgabe = "java/util/Map";
|
||||
}
|
||||
if (rueckgabe == null) return mv;
|
||||
umgebaut[0]++;
|
||||
final String typ = rueckgabe;
|
||||
return new MethodVisitor(Opcodes.ASM9, mv) {
|
||||
@Override
|
||||
public void visitInsn(int op) {
|
||||
if (op == Opcodes.ARETURN) {
|
||||
// Stapel: [ergebnis] -> [dienst, ergebnis, argument] -> apply -> [neu]
|
||||
super.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "getProperties", "()Ljava/util/Properties;", false);
|
||||
super.visitLdcInsn(Agent.SCHLUESSEL);
|
||||
super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Properties", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
|
||||
super.visitTypeInsn(Opcodes.CHECKCAST, "java/util/function/BiFunction");
|
||||
super.visitInsn(Opcodes.DUP_X2);
|
||||
super.visitInsn(Opcodes.POP);
|
||||
super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/function/BiFunction", "apply",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
|
||||
super.visitTypeInsn(Opcodes.CHECKCAST, typ);
|
||||
}
|
||||
super.visitInsn(op);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
if (umgebaut[0] == 0) return null;
|
||||
System.out.println("[AeroMC] authlib fuer Umhaenge vorbereitet (" + umgebaut[0] + " Methode)");
|
||||
return schreiber.toByteArray();
|
||||
} catch (Throwable t) {
|
||||
System.out.println("[AeroMC] authlib konnte nicht angepasst werden: " + t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user