mirror of
https://github.com/unmojang/authlib-injector.git
synced 2025-10-02 15:51:31 -04:00
Use invokedynamic
This commit is contained in:
parent
a94528bb68
commit
1003212d38
@ -228,10 +228,9 @@ public class AuthlibLogInterceptor implements TransformUnit {
|
|||||||
@Override
|
@Override
|
||||||
public void visitCode() {
|
public void visitCode() {
|
||||||
super.visitCode();
|
super.visitCode();
|
||||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, AuthlibLogInterceptor.class, "onClassLoading");
|
|
||||||
super.visitLdcInsn(Type.getType("L" + className.replace('.', '/') + ";"));
|
super.visitLdcInsn(Type.getType("L" + className.replace('.', '/') + ";"));
|
||||||
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false);
|
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false);
|
||||||
callback.invoke();
|
CallbackSupport.invoke(ctx, mv, AuthlibLogInterceptor.class, "onClassLoading");
|
||||||
ctx.markModified();
|
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;
|
package moe.yushi.authlibinjector.transform;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
import static org.objectweb.asm.Opcodes.H_INVOKESTATIC;
|
||||||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Handle;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import moe.yushi.authlibinjector.transform.TransformUnit.TransformContext;
|
import moe.yushi.authlibinjector.transform.TransformUnit.TransformContext;
|
||||||
|
|
||||||
public class CallbackInvocation {
|
public class CallbackSupport {
|
||||||
|
|
||||||
private static Method findCallbackMethod(Class<?> owner, String methodName) {
|
private static Method findCallbackMethod(Class<?> owner, String methodName) {
|
||||||
for (Method method : owner.getDeclaredMethods()) {
|
for (Method method : owner.getDeclaredMethods()) {
|
||||||
@ -41,32 +41,18 @@ public class CallbackInvocation {
|
|||||||
throw new IllegalArgumentException("No such method: " + methodName);
|
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.requireMinimumClassVersion(50);
|
||||||
ctx.upgradeClassVersion(51);
|
ctx.upgradeClassVersion(51);
|
||||||
|
|
||||||
String descriptor = Type.getMethodDescriptor(findCallbackMethod(owner, methodName));
|
String descriptor = Type.getMethodDescriptor(findCallbackMethod(owner, methodName));
|
||||||
|
mv.visitInvokeDynamicInsn(methodName, descriptor, BOOTSTRAP_METHOD, owner.getName());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -48,9 +48,8 @@ public class MainArgumentsTransformer implements TransformUnit {
|
|||||||
super.visitCode();
|
super.visitCode();
|
||||||
ctx.markModified();
|
ctx.markModified();
|
||||||
|
|
||||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MainArgumentsTransformer.class, "processMainArguments");
|
|
||||||
super.visitVarInsn(ALOAD, 0);
|
super.visitVarInsn(ALOAD, 0);
|
||||||
callback.invoke();
|
CallbackSupport.invoke(ctx, mv, MainArgumentsTransformer.class, "processMainArguments");
|
||||||
super.visitVarInsn(ASTORE, 0);
|
super.visitVarInsn(ASTORE, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,7 @@ public class YggdrasilKeyTransformUnit implements TransformUnit {
|
|||||||
mv.visitInsn(IRETURN);
|
mv.visitInsn(IRETURN);
|
||||||
mv.visitLabel(l0);
|
mv.visitLabel(l0);
|
||||||
mv.visitFrame(F_SAME, 0, null, 0, null);
|
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.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
|
||||||
mv.visitVarInsn(ASTORE, 2);
|
mv.visitVarInsn(ASTORE, 2);
|
||||||
Label l1 = new Label();
|
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.DUP;
|
||||||
import static org.objectweb.asm.Opcodes.GETFIELD;
|
import static org.objectweb.asm.Opcodes.GETFIELD;
|
||||||
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
||||||
import static org.objectweb.asm.Opcodes.SWAP;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -34,8 +33,8 @@ import org.objectweb.asm.ClassVisitor;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import moe.yushi.authlibinjector.AuthlibInjector;
|
import moe.yushi.authlibinjector.AuthlibInjector;
|
||||||
import moe.yushi.authlibinjector.transform.CallbackInvocation;
|
|
||||||
import moe.yushi.authlibinjector.transform.CallbackMethod;
|
import moe.yushi.authlibinjector.transform.CallbackMethod;
|
||||||
|
import moe.yushi.authlibinjector.transform.CallbackSupport;
|
||||||
import moe.yushi.authlibinjector.transform.MainArgumentsTransformer;
|
import moe.yushi.authlibinjector.transform.MainArgumentsTransformer;
|
||||||
import moe.yushi.authlibinjector.transform.TransformUnit;
|
import moe.yushi.authlibinjector.transform.TransformUnit;
|
||||||
import moe.yushi.authlibinjector.util.Logging;
|
import moe.yushi.authlibinjector.util.Logging;
|
||||||
@ -123,9 +122,7 @@ public class MC52974_1710Workaround {
|
|||||||
if (opcode == ARETURN) {
|
if (opcode == ARETURN) {
|
||||||
ctx.markModified();
|
ctx.markModified();
|
||||||
super.visitInsn(DUP);
|
super.visitInsn(DUP);
|
||||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MC52974_1710Workaround.class, "markGameProfile");
|
CallbackSupport.invoke(ctx, mv, MC52974_1710Workaround.class, "markGameProfile");
|
||||||
super.visitInsn(SWAP);
|
|
||||||
callback.invoke();
|
|
||||||
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
||||||
}
|
}
|
||||||
super.visitInsn(opcode);
|
super.visitInsn(opcode);
|
||||||
@ -161,8 +158,6 @@ public class MC52974_1710Workaround {
|
|||||||
? "gb".equals(owner) && "b".equals(name) && "Lcom/mojang/authlib/GameProfile;".equals(descriptor)
|
? "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))) {
|
: "net/minecraft/network/play/server/S0CPacketSpawnPlayer".equals(owner) && "field_148955_b".equals(name) && "Lcom/mojang/authlib/GameProfile;".equals(descriptor))) {
|
||||||
ctx.markModified();
|
ctx.markModified();
|
||||||
CallbackInvocation callback = CallbackInvocation.push(ctx, mv, MC52974_1710Workaround.class, "accessGameProfile");
|
|
||||||
super.visitInsn(SWAP);
|
|
||||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||||
if (isNotchName) {
|
if (isNotchName) {
|
||||||
super.visitMethodInsn(INVOKESTATIC, "net/minecraft/server/MinecraftServer", "I", "()Lnet/minecraft/server/MinecraftServer;", false);
|
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.visitMethodInsn(INVOKESTATIC, "net/minecraft/server/MinecraftServer", "func_71276_C", "()Lnet/minecraft/server/MinecraftServer;", false);
|
||||||
}
|
}
|
||||||
super.visitLdcInsn(isNotchName ? 1 : 0);
|
super.visitLdcInsn(isNotchName ? 1 : 0);
|
||||||
callback.invoke();
|
CallbackSupport.invoke(ctx, mv, MC52974_1710Workaround.class, "accessGameProfile");
|
||||||
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
super.visitTypeInsn(CHECKCAST, "com/mojang/authlib/GameProfile");
|
||||||
} else {
|
} else {
|
||||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user