diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index 76024ce..e54e87f 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -65,6 +65,7 @@ import moe.yushi.authlibinjector.transform.support.PaperUsernameCheckTransformer import moe.yushi.authlibinjector.transform.support.ProxyParameterWorkaround; import moe.yushi.authlibinjector.transform.support.SkinWhitelistTransformUnit; import moe.yushi.authlibinjector.transform.support.UsernameCharacterCheckTransformer; +import moe.yushi.authlibinjector.transform.support.VelocityIdentifiedKeyImplTransformUnit; import moe.yushi.authlibinjector.transform.support.YggdrasilKeyTransformUnit; import moe.yushi.authlibinjector.yggdrasil.CustomYggdrasilAPIProvider; import moe.yushi.authlibinjector.yggdrasil.MojangYggdrasilAPIProvider; @@ -291,6 +292,7 @@ public final class AuthlibInjector { transformer.units.add(new YggdrasilKeyTransformUnit()); config.getDecodedPublickey().ifPresent(YggdrasilKeyTransformUnit.PUBLIC_KEYS::add); + transformer.units.add(new VelocityIdentifiedKeyImplTransformUnit()); return transformer; } diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/VelocityProfileKeyTransformUnit.java b/src/main/java/moe/yushi/authlibinjector/transform/support/VelocityProfileKeyTransformUnit.java new file mode 100644 index 0000000..ee4dff8 --- /dev/null +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/VelocityProfileKeyTransformUnit.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2022 Haowei Wen 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 . + */ +package moe.yushi.authlibinjector.transform.support; + +import static org.objectweb.asm.Opcodes.ARETURN; +import static org.objectweb.asm.Opcodes.ASM9; +import static org.objectweb.asm.Opcodes.GETSTATIC; +import java.util.Optional; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import moe.yushi.authlibinjector.transform.TransformContext; +import moe.yushi.authlibinjector.transform.TransformUnit; + +/** + * Hacks Velocity to bypass profile key signature validation. + * See https://github.com/PaperMC/Velocity/commit/1a3fba4250553702d9dcd05731d04347bfc24c9f . + */ +public class VelocityProfileKeyTransformUnit implements TransformUnit { + + @Override + public Optional transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) { + if ("com.velocitypowered.proxy.crypto.IdentifiedKeyImpl".equals(className)) { + return Optional.of(new ClassVisitor(ASM9, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + if ("validateData".equals(name) && "(Ljava/util/UUID;)Ljava/lang/Boolean;".equals(descriptor)) { + ctx.markModified(); + + MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); + mv.visitCode(); + mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;"); + mv.visitInsn(ARETURN); + mv.visitMaxs(-1, -1); + mv.visitEnd(); + + return null; + } else { + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + } + }); + } else { + return Optional.empty(); + } + } + + @Override + public String toString() { + return "Velocity Profile Key Transformer"; + } +}