mirror of
https://github.com/yushijinhun/authlib-injector.git
synced 2024-06-02 16:48:54 +02:00
Use invokedynamic
This commit is contained in:
parent
a94528bb68
commit
1003212d38
|
@ -228,10 +228,9 @@ public class AuthlibLogInterceptor implements TransformUnit {
|
|||
@Override
|
||||
public void visitCode() {
|
||||
super.visitCode();
|
||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, AuthlibLogInterceptor.class, "onClassLoading");
|
||||
super.visitLdcInsn(Type.getType("L" + className.replace('.', '/') + ";"));
|
||||
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false);
|
||||
callback.invoke();
|
||||
CallbackSupport.invoke(ctx, mv, AuthlibLogInterceptor.class, "onClassLoading");
|
||||
ctx.markModified();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Haowei Wen <yushijinhun@gmail.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
public final class CallbackEntryPoint {
|
||||
private CallbackEntryPoint() {
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(Lookup lookup, String name, MethodType type, String owner) throws ReflectiveOperationException {
|
||||
return new ConstantCallSite(
|
||||
lookup.findStatic(
|
||||
ClassLoader.getSystemClassLoader().loadClass(owner),
|
||||
name,
|
||||
type));
|
||||
}
|
||||
}
|
|
@ -16,18 +16,18 @@
|
|||
*/
|
||||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
||||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
||||
import static org.objectweb.asm.Opcodes.H_INVOKESTATIC;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import moe.yushi.authlibinjector.transform.TransformUnit.TransformContext;
|
||||
|
||||
public class CallbackInvocation {
|
||||
public class CallbackSupport {
|
||||
|
||||
private static Method findCallbackMethod(Class<?> owner, String methodName) {
|
||||
for (Method method : owner.getDeclaredMethods()) {
|
||||
|
@ -41,32 +41,18 @@ public class CallbackInvocation {
|
|||
throw new IllegalArgumentException("No such method: " + methodName);
|
||||
}
|
||||
|
||||
public static CallbackInvocation push(TransformContext ctx, MethodVisitor mv, Class<?> owner, String methodName) {
|
||||
private static final Handle BOOTSTRAP_METHOD = new Handle(
|
||||
H_INVOKESTATIC,
|
||||
Type.getInternalName(CallbackEntryPoint.class),
|
||||
"bootstrap",
|
||||
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;)Ljava/lang/invoke/CallSite;",
|
||||
false);
|
||||
|
||||
public static void invoke(TransformContext ctx, MethodVisitor mv, Class<?> owner, String methodName) {
|
||||
ctx.requireMinimumClassVersion(50);
|
||||
ctx.upgradeClassVersion(51);
|
||||
|
||||
String descriptor = Type.getMethodDescriptor(findCallbackMethod(owner, methodName));
|
||||
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "publicLookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false);
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/ClassLoader", "getSystemClassLoader", "()Ljava/lang/ClassLoader;", false);
|
||||
mv.visitLdcInsn(owner.getName());
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassLoader", "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", false);
|
||||
mv.visitLdcInsn(methodName);
|
||||
mv.visitLdcInsn(Type.getMethodType(descriptor));
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false);
|
||||
|
||||
return new CallbackInvocation(mv, descriptor);
|
||||
}
|
||||
|
||||
private MethodVisitor mv;
|
||||
private String descriptor;
|
||||
|
||||
private CallbackInvocation(MethodVisitor mv, String descriptor) {
|
||||
this.mv = mv;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public void invoke() {
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", descriptor, false);
|
||||
mv.visitInvokeDynamicInsn(methodName, descriptor, BOOTSTRAP_METHOD, owner.getName());
|
||||
}
|
||||
}
|
|
@ -48,9 +48,8 @@ public class MainArgumentsTransformer implements TransformUnit {
|
|||
super.visitCode();
|
||||
ctx.markModified();
|
||||
|
||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MainArgumentsTransformer.class, "processMainArguments");
|
||||
super.visitVarInsn(ALOAD, 0);
|
||||
callback.invoke();
|
||||
CallbackSupport.invoke(ctx, mv, MainArgumentsTransformer.class, "processMainArguments");
|
||||
super.visitVarInsn(ASTORE, 0);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -76,7 +76,7 @@ public class YggdrasilKeyTransformUnit implements TransformUnit {
|
|||
mv.visitInsn(IRETURN);
|
||||
mv.visitLabel(l0);
|
||||
mv.visitFrame(F_SAME, 0, null, 0, null);
|
||||
CallbackInvocation.push(ctx, mv, YggdrasilKeyTransformUnit.class, "getPublicKeys").invoke();
|
||||
CallbackSupport.invoke(ctx, mv, YggdrasilKeyTransformUnit.class, "getPublicKeys");
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
|
||||
mv.visitVarInsn(ASTORE, 2);
|
||||
Label l1 = new Label();
|
||||
|
|
|
@ -22,7 +22,6 @@ import static org.objectweb.asm.Opcodes.CHECKCAST;
|
|||
import static org.objectweb.asm.Opcodes.DUP;
|
||||
import static org.objectweb.asm.Opcodes.GETFIELD;
|
||||
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
||||
import static org.objectweb.asm.Opcodes.SWAP;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -34,8 +33,8 @@ import org.objectweb.asm.ClassVisitor;
|
|||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import moe.yushi.authlibinjector.AuthlibInjector;
|
||||
import moe.yushi.authlibinjector.transform.CallbackInvocation;
|
||||
import moe.yushi.authlibinjector.transform.CallbackMethod;
|
||||
import moe.yushi.authlibinjector.transform.CallbackSupport;
|
||||
import moe.yushi.authlibinjector.transform.MainArgumentsTransformer;
|
||||
import moe.yushi.authlibinjector.transform.TransformUnit;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
@ -123,9 +122,7 @@ public class MC52974_1710Workaround {
|
|||
if (opcode == ARETURN) {
|
||||
ctx.markModified();
|
||||
super.visitInsn(DUP);
|
||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MC52974_1710Workaround.class, "markGameProfile");
|
||||
super.visitInsn(SWAP);
|
||||
callback.invoke();
|
||||
CallbackSupport.invoke(ctx, mv, MC52974_1710Workaround.class, "markGameProfile");
|
||||
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
||||
}
|
||||
super.visitInsn(opcode);
|
||||
|
@ -161,8 +158,6 @@ public class MC52974_1710Workaround {
|
|||
? "gb".equals(owner) && "b".equals(name) && "Lcom/mojang/authlib/GameProfile;".equals(descriptor)
|
||||
: "net/minecraft/network/play/server/S0CPacketSpawnPlayer".equals(owner) && "field_148955_b".equals(name) && "Lcom/mojang/authlib/GameProfile;".equals(descriptor))) {
|
||||
ctx.markModified();
|
||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MC52974_1710Workaround.class, "accessGameProfile");
|
||||
super.visitInsn(SWAP);
|
||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||
if (isNotchName) {
|
||||
super.visitMethodInsn(INVOKESTATIC, "net/minecraft/server/MinecraftServer", "I", "()Lnet/minecraft/server/MinecraftServer;", false);
|
||||
|
@ -170,7 +165,7 @@ public class MC52974_1710Workaround {
|
|||
super.visitMethodInsn(INVOKESTATIC, "net/minecraft/server/MinecraftServer", "func_71276_C", "()Lnet/minecraft/server/MinecraftServer;", false);
|
||||
}
|
||||
super.visitLdcInsn(isNotchName ? 1 : 0);
|
||||
callback.invoke();
|
||||
CallbackSupport.invoke(ctx, mv, MC52974_1710Workaround.class, "accessGameProfile");
|
||||
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
||||
} else {
|
||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||
|
|
Loading…
Reference in a new issue