diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index 664b125..af2445d 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -31,6 +31,7 @@ import moe.yushi.authlibinjector.transform.ConstantURLTransformUnit; import moe.yushi.authlibinjector.transform.DumpClassListener; import moe.yushi.authlibinjector.transform.SkinWhitelistTransformUnit; import moe.yushi.authlibinjector.transform.YggdrasilKeyTransformUnit; +import moe.yushi.authlibinjector.transform.support.CitizensTransformer; import moe.yushi.authlibinjector.util.Logging; public final class AuthlibInjector { @@ -296,6 +297,7 @@ public final class AuthlibInjector { } transformer.units.add(new ConstantURLTransformUnit(urlProcessor)); + transformer.units.add(new CitizensTransformer()); transformer.units.add(new SkinWhitelistTransformUnit(config.getSkinDomains().toArray(new String[0]))); diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/CitizensTransformer.java b/src/main/java/moe/yushi/authlibinjector/transform/support/CitizensTransformer.java new file mode 100644 index 0000000..acdc26a --- /dev/null +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/CitizensTransformer.java @@ -0,0 +1,64 @@ +package moe.yushi.authlibinjector.transform.support; + +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ASM6; +import static org.objectweb.asm.Opcodes.F_SAME; +import static org.objectweb.asm.Opcodes.GETFIELD; +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; +import static org.objectweb.asm.Opcodes.RETURN; + +import java.util.Optional; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import moe.yushi.authlibinjector.transform.TransformUnit; + +/** + * Support for Citizens2 + * + * In , + * the profile-url that Citizens use became configurable. This class is used to make Citizens ignore + * the config property and use authlib-injector's url. + */ +public class CitizensTransformer implements TransformUnit { + + @Override + public Optional transform(ClassLoader classLoader, String className, ClassVisitor writer, Runnable modifiedCallback) { + if ("net.citizensnpcs.Settings$Setting".equals(className)) { + return Optional.of(new ClassVisitor(ASM6, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + if (("loadFromKey".equals(name) || "setAtKey".equals(name)) + && "(Lnet/citizensnpcs/api/util/DataKey;)V".equals(descriptor)) { + return new MethodVisitor(ASM6, super.visitMethod(access, name, descriptor, signature, exceptions)) { + @Override + public void visitCode() { + super.visitCode(); + super.visitLdcInsn("general.authlib.profile-url"); + super.visitVarInsn(ALOAD, 0); + super.visitFieldInsn(GETFIELD, "net/citizensnpcs/Settings$Setting", "path", "Ljava/lang/String;"); + super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label lbl = new Label(); + super.visitJumpInsn(IFEQ, lbl); + super.visitInsn(RETURN); + super.visitLabel(lbl); + super.visitFrame(F_SAME, 0, null, 0, null); + modifiedCallback.run(); + } + }; + } + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + }); + } + return Optional.empty(); + } + + @Override + public String toString() { + return "Citizens2 Support"; + } +}