diff --git a/README.md b/README.md index 177dd43..c727e5c 100644 --- a/README.md +++ b/README.md @@ -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 选项, 则该功能默认启用. diff --git a/src/main/java/moe/yushi/authlibinjector/util/Logging.java b/src/main/java/moe/yushi/authlibinjector/util/Logging.java index 3851a9f..5adb35f 100644 --- a/src/main/java/moe/yushi/authlibinjector/util/Logging.java +++ b/src/main/java/moe/yushi/authlibinjector/util/Logging.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Haowei Wen and contributors + * Copyright (C) 2021 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 @@ -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); + } + } } }