Merge branch 'develop' into social-interactions

This commit is contained in:
Haowei Wen 2021-06-12 00:09:05 +08:00
commit 90c4a649f6
No known key found for this signature in database
GPG key ID: 5BC167F73EA558E4
15 changed files with 111 additions and 46 deletions

View file

@ -30,6 +30,15 @@ gradle
## 参数
```
-Dauthlibinjector.noLogFile
不要将日志输出到文件.
默认情况下, authlib-injector 会将日志输出到控制台以及当前目录下的 authlib-injector.log 文件.
开启此选项后, 日志仅会输出到控制台.
需要注意的是, authlib-injector 的日志是不会输出到 Minecraft 服务端/客户端的日志文件中的.
每次启动时,日志文件都会被清空. 如果有多个进程使用同一个日志文件, 则只有最早启动的会成功打开日志文件.
-Dauthlibinjector.mojangNamespace={default|enabled|disabled}
设置是否启用 Mojang 命名空间 (@mojang 后缀).
若验证服务器未设置 feature.no_mojang_namespace 选项, 则该功能默认启用.

View file

@ -1,5 +1,5 @@
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'com.github.johnrengelman.shadow' version '6.1.0'
id 'com.palantir.git-version' version '0.12.3'
id 'java'
}
@ -9,8 +9,8 @@ repositories {
}
dependencies {
implementation 'org.ow2.asm:asm:8.0.1'
testImplementation 'junit:junit:4.13'
implementation 'org.ow2.asm:asm:9.1'
testImplementation 'junit:junit:4.13.2'
}
sourceCompatibility = 8

View file

@ -1,4 +1,4 @@
Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
Copyright (C) 2021 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

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -21,7 +21,7 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ARETURN;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.DUP;
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
@ -35,7 +35,7 @@ class CallbackMetafactoryTransformer implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext context) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -18,7 +18,7 @@ package moe.yushi.authlibinjector.transform;
import static moe.yushi.authlibinjector.util.Logging.log;
import static moe.yushi.authlibinjector.util.Logging.Level.DEBUG;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import java.util.Optional;
import org.objectweb.asm.ClassVisitor;
@ -34,7 +34,7 @@ class ClassVersionTransformUnit implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext context) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
int major = version & 0xffff;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -16,7 +16,7 @@
*/
package moe.yushi.authlibinjector.transform;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import java.util.Optional;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
@ -25,11 +25,11 @@ public abstract class LdcTransformUnit implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, desc, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitLdcInsn(Object cst) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -19,7 +19,7 @@ package moe.yushi.authlibinjector.transform.support;
import static moe.yushi.authlibinjector.util.Logging.log;
import static moe.yushi.authlibinjector.util.Logging.Level.INFO;
import static moe.yushi.authlibinjector.util.Logging.Level.WARNING;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
@ -221,12 +221,12 @@ public class AuthlibLogInterceptor implements TransformUnit {
return Optional.empty();
}
}
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if ("<clinit>".equals(name)) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitCode() {
super.visitCode();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -17,7 +17,7 @@
package moe.yushi.authlibinjector.transform.support;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.F_SAME;
import static org.objectweb.asm.Opcodes.GETFIELD;
import static org.objectweb.asm.Opcodes.IFEQ;
@ -45,12 +45,12 @@ public class CitizensTransformer implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
if ("net.citizensnpcs.Settings$Setting".equals(className)) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, 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(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitCode() {
super.visitCode();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -19,7 +19,7 @@ package moe.yushi.authlibinjector.transform.support;
import static java.util.Collections.unmodifiableSet;
import static moe.yushi.authlibinjector.util.Logging.log;
import static moe.yushi.authlibinjector.util.Logging.Level.INFO;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.ISTORE;
import java.util.Arrays;
import java.util.HashSet;
@ -60,11 +60,11 @@ public class MC52974Workaround implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
if ("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService".equals(className)) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if ("fillGameProfile".equals(name) && "(Lcom/mojang/authlib/GameProfile;Z)Lcom/mojang/authlib/GameProfile;".equals(descriptor)) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitCode() {
super.visitCode();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -20,7 +20,7 @@ import static moe.yushi.authlibinjector.util.Logging.log;
import static moe.yushi.authlibinjector.util.Logging.Level.INFO;
import static moe.yushi.authlibinjector.util.Logging.Level.WARNING;
import static org.objectweb.asm.Opcodes.ARETURN;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.CHECKCAST;
import static org.objectweb.asm.Opcodes.DUP;
import static org.objectweb.asm.Opcodes.GETFIELD;
@ -107,14 +107,14 @@ public class MC52974_1710Workaround {
private static class SessionTransformer implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
return detectNotchName(className, "bbs", "net.minecraft.util.Session", isNotchName -> new ClassVisitor(ASM7, writer) {
return detectNotchName(className, "bbs", "net.minecraft.util.Session", isNotchName -> new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if (isNotchName
? "e".equals(name) && "()Lcom/mojang/authlib/GameProfile;".equals(descriptor)
: "func_148256_e".equals(name) && "()Lcom/mojang/authlib/GameProfile;".equals(descriptor)) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitInsn(int opcode) {
if (opcode == ARETURN) {
@ -141,14 +141,14 @@ public class MC52974_1710Workaround {
private static class S0CPacketSpawnPlayerTransformer implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
return detectNotchName(className, "gb", "net.minecraft.network.play.server.S0CPacketSpawnPlayer", isNotchName -> new ClassVisitor(ASM7, writer) {
return detectNotchName(className, "gb", "net.minecraft.network.play.server.S0CPacketSpawnPlayer", isNotchName -> new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if (isNotchName
? "b".equals(name) && "(Let;)V".equals(descriptor)
: "func_148840_b".equals(name) && "(Lnet/minecraft/network/PacketBuffer;)V".equals(descriptor)) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
super.visitFieldInsn(opcode, owner, name, descriptor);

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -20,7 +20,7 @@ import static java.util.stream.Collectors.joining;
import static moe.yushi.authlibinjector.util.Logging.log;
import static moe.yushi.authlibinjector.util.Logging.Level.DEBUG;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.ASTORE;
import java.util.List;
import java.util.Optional;
@ -40,11 +40,11 @@ public class MainArgumentsTransformer implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
if ("net.minecraft.client.main.Main".equals(className)) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if ("main".equals(name) && "([Ljava/lang/String;)V".equals(descriptor)) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, descriptor, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
@Override
public void visitCode() {
super.visitCode();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -17,7 +17,7 @@
package moe.yushi.authlibinjector.transform.support;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.IRETURN;
import java.net.URI;
import java.net.URISyntaxException;
@ -50,6 +50,11 @@ public class SkinWhitelistTransformUnit implements TransformUnit {
".mojang.com"
};
private static final String[] DEFAULT_BLACKLISTED_DOMAINS = {
"education.minecraft.net",
"bugs.mojang.com"
};
private static final List<String> WHITELISTED_DOMAINS = new CopyOnWriteArrayList<>();
public static List<String> getWhitelistedDomains() {
@ -65,6 +70,12 @@ public class SkinWhitelistTransformUnit implements TransformUnit {
throw new IllegalArgumentException("Invalid URL '" + url + "'");
}
for (String pattern : DEFAULT_BLACKLISTED_DOMAINS) {
if (domainMatches(pattern, domain)) {
return false;
}
}
for (String pattern : DEFAULT_WHITELISTED_DOMAINS) {
if (domainMatches(pattern, domain)) {
return true;
@ -81,11 +92,12 @@ public class SkinWhitelistTransformUnit implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
if ("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService".equals(className)) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if ("isWhitelistedDomain".equals(name) && "(Ljava/lang/String;)Z".equals(desc)) {
if (("isWhitelistedDomain".equals(name) || "isAllowedTextureDomain".equals(name)) &&
"(Ljava/lang/String;)Z".equals(desc)) {
ctx.markModified();
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
mv.visitCode();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -16,7 +16,7 @@
*/
package moe.yushi.authlibinjector.transform.support;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ASM9;
import static org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import java.lang.invoke.MethodHandle;
@ -52,10 +52,10 @@ public class YggdrasilKeyTransformUnit implements TransformUnit {
@Override
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext ctx) {
if ("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService".equals(className)) {
return Optional.of(new ClassVisitor(ASM7, writer) {
return Optional.of(new ClassVisitor(ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(ASM7, super.visitMethod(access, name, desc, signature, exceptions)) {
return new MethodVisitor(ASM9, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
if (opcode == INVOKEVIRTUAL

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Haowei Wen <yushijinhun@gmail.com> and contributors
* Copyright (C) 2021 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
@ -16,15 +16,50 @@
*/
package moe.yushi.authlibinjector.util;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import static moe.yushi.authlibinjector.util.Logging.Level.INFO;
import static moe.yushi.authlibinjector.util.Logging.Level.WARNING;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import moe.yushi.authlibinjector.Config;
public final class Logging {
private Logging() {}
private static final PrintStream out = System.err;
private static final FileChannel logfile = openLogFile();
private static FileChannel openLogFile() {
if (System.getProperty("authlibinjector.noLogFile") != null) {
log(INFO, "Logging to file is disabled");
return null;
}
Path logfilePath = Paths.get("authlib-injector.log").toAbsolutePath();
try {
FileChannel channel = FileChannel.open(logfilePath, CREATE, WRITE);
if (channel.tryLock() == null) {
log(WARNING, "Couldn't lock log file [" + logfilePath + "]");
return null;
}
channel.truncate(0);
String logHeader = "Logging started at " + Instant.now() + System.lineSeparator();
channel.write(Charset.defaultCharset().encode(logHeader));
log(INFO, "Logging file: " + logfilePath);
return channel;
} catch (IOException e) {
log(WARNING, "Couldn't open log file [" + logfilePath + "]");
return null;
}
}
public static enum Level {
DEBUG, INFO, WARNING, ERROR;
@ -50,5 +85,14 @@ public final class Logging {
// remove control characters to prevent messing up the console
log = log.replaceAll("[\\p{Cc}&&[^\r\n\t]]", "");
out.println(log);
if (logfile != null) {
try {
logfile.write(Charset.defaultCharset().encode(log + System.lineSeparator()));
logfile.force(true);
} catch (IOException ex) {
out.println("[authlib-injector] [ERROR] Error writing to log file: " + ex);
}
}
}
}