diff --git a/build.gradle b/build.gradle index fa431934e..5df72be60 100644 --- a/build.gradle +++ b/build.gradle @@ -181,15 +181,16 @@ project(':forge') { nativesDirectory: extractNatives.output ] properties = [ - 'org.lwjgl.util.Debug': 'true', - 'org.lwjgl.util.DebugLoader': 'true', +// 'org.lwjgl.util.Debug': 'true', +// 'org.lwjgl.util.DebugLoader': 'true', 'org.lwjgl.system.SharedLibraryExtractDirectory': 'lwjgl_dll', 'mc.version': MC_VERSION, 'mcp.version': MCP_VERSION, 'forge.version': project.version.substring(MC_VERSION.length() + 1), 'forge.spec': SPEC_VERSION, 'forge.group': project.group, - 'fmllauncher.version': SPEC_VERSION + 'fmllauncher.version': SPEC_VERSION, + 'terminal.ansi': 'true' ] } forge_server = { @@ -276,12 +277,13 @@ project(':forge') { installer 'net.minecraftforge:coremods:0.2.+' installer 'com.electronwill.night-config:core:3.4.2' installer 'com.electronwill.night-config:toml:3.4.2' - installer 'org.jline:jline:3.5.1' + installer 'org.jline:jline:3.9.0' installer 'org.apache.maven:maven-artifact:3.6.0' installer 'net.jodah:typetools:0.6.0' installer 'java3d:vecmath:1.5.2' installer 'org.apache.logging.log4j:log4j-api:2.11.1' installer 'org.apache.logging.log4j:log4j-core:2.11.1' + installer 'net.minecrell:terminalconsoleappender:1.1.+' fmllauncherImplementation 'com.google.guava:guava:21.0' fmllauncherImplementation 'com.google.code.gson:gson:2.8.0' testImplementation "org.junit.jupiter:junit-jupiter-api:5.0.0" diff --git a/src/main/java/net/minecraftforge/fml/LaunchTesting.java b/src/main/java/net/minecraftforge/fml/LaunchTesting.java index 120b4037a..7bafaf863 100644 --- a/src/main/java/net/minecraftforge/fml/LaunchTesting.java +++ b/src/main/java/net/minecraftforge/fml/LaunchTesting.java @@ -67,6 +67,8 @@ public class LaunchTesting "--assetsDir", assets, "--userProperties", "{}" }, String.class); + } else { + launchArgs = ObjectArrays.concat(launchArgs, args, String.class); } Launcher.main(launchArgs); Thread.sleep(10000); diff --git a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java b/src/main/java/net/minecraftforge/server/console/TerminalHandler.java index 5473861a1..bdf2f1c46 100644 --- a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java +++ b/src/main/java/net/minecraftforge/server/console/TerminalHandler.java @@ -19,9 +19,8 @@ package net.minecraftforge.server.console; -import net.minecraftforge.server.terminalconsole.TerminalConsoleAppender; - import net.minecraft.server.dedicated.DedicatedServer; +import net.minecrell.terminalconsole.TerminalConsoleAppender; import org.jline.reader.EndOfFileException; import org.jline.reader.LineReader; import org.jline.reader.LineReaderBuilder; diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java b/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java deleted file mode 100644 index 78347e3ea..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * TerminalConsoleAppender - * Copyright (c) 2017 Minecrell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package net.minecraftforge.server.terminalconsole; - -import javax.annotation.Nullable; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.apache.logging.log4j.core.pattern.ConverterKeys; -import org.apache.logging.log4j.core.pattern.HighlightConverter; -import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; -import org.apache.logging.log4j.core.pattern.PatternConverter; -import org.apache.logging.log4j.core.pattern.PatternFormatter; -import org.apache.logging.log4j.core.pattern.PatternParser; -import org.apache.logging.log4j.util.PerformanceSensitive; - -import java.util.List; - -/** - * A simplified version of {@link HighlightConverter} that uses - * {@link TerminalConsoleAppender} to detect if Ansi escape codes can be used - * to highlight errors and warnings in the console. - * - *

If configured, it will mark all logged errors with a red color and all - * warnings with a yellow color. It can be only used together with - * {@link TerminalConsoleAppender}.

- * - *

{@link TerminalConsoleAppender#ANSI_OVERRIDE_PROPERTY} may be used - * to force the use of ANSI colors even in unsupported environments.

- * - *

Example usage: {@code %highlightError{%level: %message}}

- */ -@Plugin(name = "highlightError", category = PatternConverter.CATEGORY) -@ConverterKeys({ "highlightError" }) -@PerformanceSensitive("allocation") -public class HighlightErrorConverter extends LogEventPatternConverter -{ - private static final String ANSI_RESET = "\u001B[39;0m"; - private static final String ANSI_ERROR = "\u001B[31;1m"; - private static final String ANSI_WARN = "\u001B[33;1m"; - - private final List formatters; - - /** - * Construct the converter. - * - * @param formatters The pattern formatters to generate the text to highlight - */ - protected HighlightErrorConverter(List formatters) - { - super("highlightError", null); - this.formatters = formatters; - } - - @Override - public void format(LogEvent event, StringBuilder toAppendTo) - { - if (TerminalConsoleAppender.isAnsiSupported()) - { - Level level = event.getLevel(); - if (level.isMoreSpecificThan(Level.ERROR)) - { - format(ANSI_ERROR, event, toAppendTo); - return; - } - else if (level.isMoreSpecificThan(Level.WARN)) - { - format(ANSI_WARN, event, toAppendTo); - return; - } - } - - //noinspection ForLoopReplaceableByForEach - for (int i = 0, size = formatters.size(); i < size; i++) - { - formatters.get(i).format(event, toAppendTo); - } - } - - private void format(String style, LogEvent event, StringBuilder toAppendTo) - { - int start = toAppendTo.length(); - toAppendTo.append(style); - int end = toAppendTo.length(); - - //noinspection ForLoopReplaceableByForEach - for (int i = 0, size = formatters.size(); i < size; i++) - { - formatters.get(i).format(event, toAppendTo); - } - - if (toAppendTo.length() == end) - { - // No content so we don't need to append the ANSI escape code - toAppendTo.setLength(start); - } - else - { - // Append reset code after the line - toAppendTo.append(ANSI_RESET); - } - } - - @Override - public boolean handlesThrowable() - { - for (final PatternFormatter formatter : formatters) - { - if (formatter.handlesThrowable()) - { - return true; - } - } - return false; - } - - /** - * Gets a new instance of the {@link HighlightErrorConverter} with the - * specified options. - * - * @param config The current configuration - * @param options The pattern options - * @return The new instance - */ - @Nullable - public static HighlightErrorConverter newInstance(Configuration config, String[] options) - { - if (options.length != 1) - { - LOGGER.error("Incorrect number of options on highlightError. Expected 1 received " + options.length); - return null; - } - if (options[0] == null) - { - LOGGER.error("No pattern supplied on highlightError"); - return null; - } - - PatternParser parser = PatternLayout.createPatternParser(config); - List formatters = parser.parse(options[0]); - return new HighlightErrorConverter(formatters); - } - -} diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java b/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java deleted file mode 100644 index b01efba56..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * TerminalConsoleAppender - * Copyright (c) 2017 Minecrell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package net.minecraftforge.server.terminalconsole; - -import javax.annotation.Nullable; - -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.apache.logging.log4j.core.pattern.ConverterKeys; -import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; -import org.apache.logging.log4j.core.pattern.PatternConverter; -import org.apache.logging.log4j.core.pattern.PatternFormatter; -import org.apache.logging.log4j.core.pattern.PatternParser; -import org.apache.logging.log4j.util.PerformanceSensitive; -import org.apache.logging.log4j.util.PropertiesUtil; - -import java.util.List; - -/** - * Replaces Minecraft formatting codes in the result of a pattern with - * appropriate ANSI escape codes. The implementation will only replace valid - * color codes using the section sign (§). - * - *

The {@link MinecraftFormattingConverter} can be only used together with - * {@link TerminalConsoleAppender} to detect if the current console supports - * color output. When running in an unsupported environment, it will - * automatically strip all formatting codes instead.

- * - *

{@link TerminalConsoleAppender#ANSI_OVERRIDE_PROPERTY} may be used - * to force the use of ANSI colors even in unsupported environments. As an - * alternative, {@link #KEEP_FORMATTING_PROPERTY} may be used to keep the - * raw Minecraft formatting codes.

- * - *

Example usage: {@code %minecraftFormatting{%message}}
- * It can be configured to always strip formatting codes from the message: - * {@code %minecraftFormatting{%message}{strip}}

- * - * @see - * Formatting Codes - */ -@Plugin(name = "minecraftFormatting", category = PatternConverter.CATEGORY) -@ConverterKeys({ "minecraftFormatting" }) -@PerformanceSensitive("allocation") -public class MinecraftFormattingConverter extends LogEventPatternConverter -{ - /** - * System property that allows disabling the replacement of Minecraft - * formatting codes entirely, keeping them in the console output. For - * some applications they might be easier and more accurate for parsing - * in applications like certain control panels. - * - *

If this system property is not set, or set to any value except - * {@code true}, all Minecraft formatting codes will be replaced - * or stripped from the console output.

- */ - public static final String KEEP_FORMATTING_PROPERTY = TerminalConsoleAppender.PROPERTY_PREFIX + ".keepMinecraftFormatting"; - - private static final boolean KEEP_FORMATTING = PropertiesUtil.getProperties().getBooleanProperty(KEEP_FORMATTING_PROPERTY); - - private static final String ANSI_RESET = "\u001B[39;0m"; - - private static final char COLOR_CHAR = '\u00A7'; // § - private static final String LOOKUP = "0123456789abcdefklmnor"; - - private static final String[] ansiCodes = new String[] { - "\u001B[0;30;22m", // Black §0 - "\u001B[0;34;22m", // Dark Blue §1 - "\u001B[0;32;22m", // Dark Green §2 - "\u001B[0;36;22m", // Dark Aqua §3 - "\u001B[0;31;22m", // Dark Red §4 - "\u001B[0;35;22m", // Dark Purple §5 - "\u001B[0;33;22m", // Gold §6 - "\u001B[0;37;22m", // Gray §7 - "\u001B[0;30;1m", // Dark Gray §8 - "\u001B[0;34;1m", // Blue §9 - "\u001B[0;32;1m", // Green §a - "\u001B[0;36;1m", // Aqua §b - "\u001B[0;31;1m", // Red §c - "\u001B[0;35;1m", // Light Purple §d - "\u001B[0;33;1m", // Yellow §e - "\u001B[0;37;1m", // White §f - "\u001B[5m", // Obfuscated §k - "\u001B[21m", // Bold §l - "\u001B[9m", // Strikethrough §m - "\u001B[4m", // Underline §n - "\u001B[3m", // Italic §o - ANSI_RESET, // Reset §r - }; - - private final boolean ansi; - private final List formatters; - - /** - * Construct the converter. - * - * @param formatters The pattern formatters to generate the text to manipulate - * @param strip If true, the converter will strip all formatting codes - */ - protected MinecraftFormattingConverter(List formatters, boolean strip) - { - super("minecraftFormatting", null); - this.formatters = formatters; - this.ansi = !strip; - } - - @Override - public void format(LogEvent event, StringBuilder toAppendTo) - { - int start = toAppendTo.length(); - //noinspection ForLoopReplaceableByForEach - for (int i = 0, size = formatters.size(); i < size; i++) - { - formatters.get(i).format(event, toAppendTo); - } - - if (KEEP_FORMATTING || toAppendTo.length() == start) - { - // Skip replacement if disabled or if the content is empty - return; - } - - String content = toAppendTo.substring(start); - format(content, toAppendTo, start, ansi && TerminalConsoleAppender.isAnsiSupported()); - } - - private static void format(String s, StringBuilder result, int start, boolean ansi) - { - int next = s.indexOf(COLOR_CHAR); - int last = s.length() - 1; - if (next == -1 || next == last) - { - return; - } - - result.setLength(start + next); - - int pos = next; - int format; - do { - if (pos != next) - { - result.append(s, pos, next); - } - - format = LOOKUP.indexOf(s.charAt(next + 1)); - if (format != -1) - { - if (ansi) - { - result.append(ansiCodes[format]); - } - pos = next += 2; - } - else - { - next++; - } - - next = s.indexOf(COLOR_CHAR, next); - } while (next != -1 && next < last); - - result.append(s, pos, s.length()); - if (ansi) - { - result.append(ANSI_RESET); - } - } - - /** - * Gets a new instance of the {@link MinecraftFormattingConverter} with the - * specified options. - * - * @param config The current configuration - * @param options The pattern options - * @return The new instance - * - * @see MinecraftFormattingConverter - */ - @Nullable - public static MinecraftFormattingConverter newInstance(Configuration config, String[] options) - { - if (options.length < 1 || options.length > 2) - { - LOGGER.error("Incorrect number of options on minecraftFormatting. Expected at least 1, max 2 received " + options.length); - return null; - } - if (options[0] == null) - { - LOGGER.error("No pattern supplied on minecraftFormatting"); - return null; - } - - PatternParser parser = PatternLayout.createPatternParser(config); - List formatters = parser.parse(options[0]); - boolean strip = options.length > 1 && "strip".equals(options[1]); - return new MinecraftFormattingConverter(formatters, strip); - } - -} diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java b/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java deleted file mode 100644 index c1dcf8264..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * TerminalConsoleAppender - * Copyright (c) 2017 Minecrell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package net.minecraftforge.server.terminalconsole; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.io.PrintStream; -import java.io.Serializable; - -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.Core; -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.plugins.PluginAttribute; -import org.apache.logging.log4j.core.config.plugins.PluginElement; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; -import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.apache.logging.log4j.util.PropertiesUtil; -import org.jline.reader.LineReader; -import org.jline.terminal.Terminal; -import org.jline.terminal.TerminalBuilder; - -/** - * An {@link Appender} that uses the JLine 3.x {@link Terminal} to print messages - * to the console. - * - *

The JLine {@link Terminal} extends the regular console output with support - * for Ansi escape codes on Windows. Additionally, it's {@link LineReader} - * interface can be used to implement enhanced console input, with an - * persistent input line, as well as command history and command completion.

- * - *

The {@code TerminalConsole} appender replaces the default {@code Console} - * appender in your log4j configuration. By default, log4j will automatically - * close the standard output when the original {@code Console} appender is - * removed. Consequently, it is necessary to keep an unused {@code Console} - * appender.

- * - *

Example usage:

- *
{@code  
- *     
- * 
- *
- * }
- * - *

To use the enhanced console input it is necessary to set the - * {@link LineReader} using {@link #setReader(LineReader)}. The appender will - * then automatically redraw the current prompt. When creating the - * {@link LineReader} it's important to use the {@link Terminal} - * returned by {@link #getTerminal()}. Additionally, the reader should - * be removed from the appender as soon as it's no longer accepting - * input (for example when the user interrupted input using CTRL + C.

- * - *

By default, the JLine {@link Terminal} is enabled when the application - * is started with an attached terminal session. Usually, this is only the - * case if the application is started from the command line, not if it gets - * started by another application.

- * - *

In some cases, it might be possible to support a subset of the features - * in these unsupported environments (e.g. only ANSI color codes). In these - * cases, the system properties may be used to override the default behaviour: - *

- * - *
    - *
  • {@link TerminalConsoleAppender#JLINE_OVERRIDE_PROPERTY} - To enable the extended JLine - * input. By default this will also enable the ANSI escape codes.
  • - *
  • {@link TerminalConsoleAppender#ANSI_OVERRIDE_PROPERTY} - To enable the output of ANSI - * escape codes. May be used to force the use of ANSI escape codes - * if JLine is disabled or to disable them if it is enabled.
  • - *
- */ -@Plugin(name = TerminalConsoleAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true) -public class TerminalConsoleAppender extends AbstractAppender -{ - public static final String PLUGIN_NAME = "TerminalConsole"; - /** - * The prefix used for all system properties in TerminalConsoleAppender. - */ - public static final String PROPERTY_PREFIX = "terminal"; - /** - * System property that allows overriding the default detection of the - * console to force enable or force disable the use of JLine. In some - * environments the automatic detection might not work properly. - *

- *

If this system property is not set, or set to an invalid value - * (neither {@code true} nor {@code false}) then we will attempt - * to detect the best option automatically.

- */ - public static final String JLINE_OVERRIDE_PROPERTY = PROPERTY_PREFIX + ".jline"; - /** - * System property that allows overriding the use of ANSI escape codes - * for console formatting even though running in an unsupported - * environment. By default, ANSI color codes are only enabled if JLine - * is enabled. Some systems might be able to handle ANSI escape codes - * but are not capable of JLine's extended input mechanism. - *

- *

If this system property is not set, or set to an invalid value - * (neither {@code true} nor {@code false}) then we will attempt - * to detect the best option automatically.

- */ - public static final String ANSI_OVERRIDE_PROPERTY = PROPERTY_PREFIX + ".ansi"; - public static final Boolean ANSI_OVERRIDE = getOptionalBooleanProperty(ANSI_OVERRIDE_PROPERTY); - - /** - * We grab the standard output {@link PrintStream} early, otherwise we - * might cause infinite loops later if the application redirects - * {@link System#out} to Log4J. - */ - private static final PrintStream stdout = System.out; - - private static boolean initialized; - @Nullable - private static Terminal terminal; - @Nullable - private static LineReader reader; - - /** - * Returns the {@link Terminal} that is used to print messages to the - * console. Returns {@code null} in unsupported environments, unless - * overridden using the {@link TerminalConsoleAppender#JLINE_OVERRIDE_PROPERTY} system - * property. - * - * @return The terminal, or null if not supported - * @see TerminalConsoleAppender - */ - @Nullable - public static Terminal getTerminal() - { - return terminal; - } - - /** - * Returns the currently configured {@link LineReader} that is used to - * read input from the console. May be null if no {@link LineReader} - * was configured by the environment. - * - * @return The current line reader, or null if none - */ - @Nullable - public static LineReader getReader() - { - return reader; - } - - /** - * Sets the {@link LineReader} that is used to read input from the console. - * Setting the {@link LineReader} will allow the appender to automatically - * redraw the input line when a new log message is added. - * - *

Note: The specified {@link LineReader} must be created with - * the terminal returned by {@link #getTerminal()}.

- * - * @param newReader The new line reader - */ - public static void setReader(@Nullable LineReader newReader) - { - if (newReader != null && newReader.getTerminal() != terminal) - { - throw new IllegalArgumentException("Reader was not created with TerminalConsoleAppender.getTerminal()"); - } - - reader = newReader; - } - - /** - * Returns whether ANSI escapes codes should be written to the console - * output. - * - *

The return value is {@code true} by default if the JLine terminal - * is enabled and {@code false} otherwise. It may be overridden using - * the {@link TerminalConsoleAppender#ANSI_OVERRIDE_PROPERTY} system property.

- * - * @return true if ANSI escapes codes should be written to the console - */ - public static boolean isAnsiSupported() - { - return ANSI_OVERRIDE != null ? ANSI_OVERRIDE : terminal != null; - } - - /** - * Constructs a new {@link TerminalConsoleAppender}. - * - * @param name The name of the appender - * @param filter The filter, can be {@code null} - * @param layout The layout to use - * @param ignoreExceptions If {@code true} exceptions encountered when - * appending events are logged, otherwise they are propagated to the - * caller - */ - protected TerminalConsoleAppender(String name, @Nullable Filter filter, Layout layout, boolean ignoreExceptions) - { - super(name, filter, layout, ignoreExceptions); - initializeTerminal(); - } - - private static void initializeTerminal() - { - if (!initialized) - { - initialized = true; - - // A system property can be used to override our automatic detection - Boolean jlineOverride = getOptionalBooleanProperty(JLINE_OVERRIDE_PROPERTY); - - // By default, we disable JLine if there is no terminal attached - // (e.g. if the program output is redirected to a file or if it's - // started by some kind of control panel) - - // The same applies to IDEs, they usually provide only a very basic - // console implementation without support for ANSI escape codes - // (used for colors) or characters like \r. - - // There are two exceptions: - // 1. IntelliJ IDEA supports colors and control characters - // (We try to detect it using an additional JAR it adds to the classpath) - // 2. The system property forces the use of JLine. - boolean dumb = jlineOverride == Boolean.TRUE || System.getProperty("java.class.path").contains("idea_rt.jar"); - - if (jlineOverride != Boolean.FALSE) - { - try - { - terminal = TerminalBuilder.builder().dumb(dumb).build(); - } - catch (IllegalStateException e) - { - // Unless disabled using one of the exceptions above, - // JLine throws an exception before creating a dumb terminal - // Dumb terminals are used if there is no real terminal attached - // to the application. - - if (LOGGER.isDebugEnabled()) - { - // Log with stacktrace - LOGGER.warn("Disabling terminal, you're running in an unsupported environment.", e); - } - else - { - LOGGER.warn("Disabling terminal, you're running in an unsupported environment."); - } - } - catch (IOException e) - { - LOGGER.error("Failed to initialize terminal. Falling back to standard output", e); - } - } - } - } - - @Nullable - private static Boolean getOptionalBooleanProperty(String name) - { - String value = PropertiesUtil.getProperties().getStringProperty(name); - if (value == null) - { - return null; - } - - if (value.equalsIgnoreCase("true")) - { - return Boolean.TRUE; - } - else if (value.equalsIgnoreCase("false")) - { - return Boolean.FALSE; - } - else - { - LOGGER.warn("Invalid value for boolean input property '{}': {}", name, value); - return null; - } - } - - @Override - public void append(LogEvent event) - { - if (terminal != null) - { - if (reader != null) - { - // Draw the prompt line again if a reader is available - reader.callWidget(LineReader.CLEAR); - terminal.writer().print(getLayout().toSerializable(event)); - reader.callWidget(LineReader.REDRAW_LINE); - reader.callWidget(LineReader.REDISPLAY); - } - else - { - terminal.writer().print(getLayout().toSerializable(event)); - } - - terminal.writer().flush(); - } - else - { - stdout.print(getLayout().toSerializable(event)); - } - } - - /** - * Closes the JLine {@link Terminal} (if available) and restores the original - * terminal settings. - * - * @throws IOException If an I/O error occurs - */ - public static void close() throws IOException - { - if (initialized) - { - initialized = false; - if (terminal != null) - { - try - { - terminal.close(); - } - finally - { - terminal = null; - } - } - } - } - - /** - * Creates a new {@link TerminalConsoleAppender}. - * - * @param name The name of the appender - * @param filter The filter, can be {@code null} - * @param layout The layout, can be {@code null} - * @param ignoreExceptions If {@code true} exceptions encountered when - * appending events are logged, otherwise they are propagated to the - * caller - * @return The new appender - */ - @PluginFactory - public static TerminalConsoleAppender createAppender( - @Required(message = "No name provided for TerminalConsoleAppender") @PluginAttribute("name") String name, - @PluginElement("Filter") @Nullable Filter filter, - @PluginElement("Layout") @Nullable Layout layout, - @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) boolean ignoreExceptions) - { - if (layout == null) - { - layout = PatternLayout.createDefaultLayout(); - } - - return new TerminalConsoleAppender(name, filter, layout, ignoreExceptions); - } -} diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java b/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java deleted file mode 100644 index 66f0e35f1..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -package net.minecraftforge.server.terminalconsole; - -import javax.annotation.ParametersAreNonnullByDefault; - -import mcp.MethodsReturnNonnullByDefault; diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java b/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java deleted file mode 100644 index 88d58d08d..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * TerminalConsoleAppender - * Copyright (c) 2017 Minecrell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package net.minecraftforge.server.terminalconsole.util; - -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.Node; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.plugins.PluginAttribute; -import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; -import org.apache.logging.log4j.core.config.plugins.PluginElement; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; -import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.apache.logging.log4j.core.layout.PatternMatch; -import org.apache.logging.log4j.core.layout.PatternSelector; -import org.apache.logging.log4j.core.pattern.PatternFormatter; -import org.apache.logging.log4j.core.pattern.PatternParser; -import org.apache.logging.log4j.util.PerformanceSensitive; - -import java.util.ArrayList; -import java.util.List; - -/** - * A {@link PatternSelector} that selects patterns based on the logger name. - * Can be used to log messages from different loggers using different patterns. - * - *

Multiple logger names may be separated using comma in the - * {@link PatternMatch#getKey() PatternMatch "key"}. The pattern will be applied - * if the logger name matches at least one of them.

- * - *

Example usage:

- *
{@code  
- *     
- *         
- *         
- *         
- *     
- * }
- */ -@Plugin(name = "LoggerNamePatternSelector", category = Node.CATEGORY, elementType = PatternSelector.ELEMENT_TYPE) -@PerformanceSensitive("allocation") -public class LoggerNamePatternSelector implements PatternSelector -{ - private static class LoggerNameSelector - { - private final String name; - private final boolean isPackage; - private final PatternFormatter[] formatters; - - LoggerNameSelector(String name, PatternFormatter[] formatters) - { - this.name = name; - this.isPackage = name.endsWith("."); - this.formatters = formatters; - } - - PatternFormatter[] get() - { - return this.formatters; - } - - boolean test(String s) - { - return this.isPackage ? s.startsWith(this.name) : s.equals(this.name); - } - - } - - private final PatternFormatter[] defaultFormatters; - private final List formatters = new ArrayList<>(); - - /** - * Constructs a new {@link LoggerNamePatternSelector}. - * - * @param defaultPattern The default pattern to use if no logger name matches - * @param properties The pattern match rules to use - * @param alwaysWriteExceptions Write exceptions even if pattern does not - * include exception conversion - * @param disableAnsi If true, disable all ANSI escape codes - * @param noConsoleNoAnsi If true and {@link System#console()} is null, - * disable ANSI escape codes - * @param config The configuration - */ - protected LoggerNamePatternSelector(String defaultPattern, PatternMatch[] properties, - boolean alwaysWriteExceptions, boolean disableAnsi, boolean noConsoleNoAnsi, Configuration config) - { - PatternParser parser = PatternLayout.createPatternParser(config); - this.defaultFormatters = toArray(parser.parse(defaultPattern, alwaysWriteExceptions, disableAnsi, noConsoleNoAnsi)); - for (PatternMatch property : properties) - { - PatternFormatter[] formatters = toArray(parser.parse(property.getPattern(), alwaysWriteExceptions, disableAnsi, noConsoleNoAnsi)); - for (String name : property.getKey().split(",")) - { - this.formatters.add(new LoggerNameSelector(name, formatters)); - } - } - } - - private static PatternFormatter[] toArray(List formatters) - { - return formatters.toArray(new PatternFormatter[formatters.size()]); - } - - @Override - public PatternFormatter[] getFormatters(LogEvent event) - { - final String loggerName = event.getLoggerName(); - if (loggerName != null) - { - //noinspection ForLoopReplaceableByForEach - for (int i = 0; i < this.formatters.size(); i++) - { - LoggerNameSelector selector = this.formatters.get(i); - if (selector.test(loggerName)) - { - return selector.get(); - } - } - } - - return this.defaultFormatters; - } - - /** - * Creates a new {@link LoggerNamePatternSelector}. - * - * @param defaultPattern The default pattern to use if no logger name matches - * @param properties The pattern match rules to use - * @param alwaysWriteExceptions Write exceptions even if pattern does not - * include exception conversion - * @param disableAnsi If true, disable all ANSI escape codes - * @param noConsoleNoAnsi If true and {@link System#console()} is null, - * disable ANSI escape codes - * @param config The configuration - * @return The new pattern selector - */ - @PluginFactory - public static LoggerNamePatternSelector createSelector( - @Required(message = "Default pattern is required") @PluginAttribute(value = "defaultPattern") String defaultPattern, - @PluginElement("PatternMatch") PatternMatch[] properties, - @PluginAttribute(value = "alwaysWriteExceptions", defaultBoolean = true) boolean alwaysWriteExceptions, - @PluginAttribute("disableAnsi") boolean disableAnsi, - @PluginAttribute("noConsoleNoAnsi") boolean noConsoleNoAnsi, - @PluginConfiguration Configuration config) - { - return new LoggerNamePatternSelector(defaultPattern, properties, alwaysWriteExceptions, disableAnsi, noConsoleNoAnsi, config); - } - -} diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java b/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java deleted file mode 100644 index 448eef878..000000000 --- a/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -package net.minecraftforge.server.terminalconsole.util; - -import javax.annotation.ParametersAreNonnullByDefault; - -import mcp.MethodsReturnNonnullByDefault; diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 10b98cc8b..03927b48d 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -1,42 +1,33 @@ - + - + - + - - + + - - - - - - - - - - + - + - - + + - + - + @@ -64,8 +55,7 @@ - - + diff --git a/src/main/resources/log4j2_server.xml b/src/main/resources/log4j2_server.xml index 607f9e7f4..737cdfedd 100644 --- a/src/main/resources/log4j2_server.xml +++ b/src/main/resources/log4j2_server.xml @@ -1,12 +1,12 @@ - + - + - - + + @@ -41,7 +41,19 @@ - + + + + + + + + + + + + +