├── .github
└── dependabot.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
├── java-templates
│ └── com
│ │ └── github
│ │ └── games647
│ │ └── colorconsole
│ │ └── sponge
│ │ └── PomData.java
├── java
│ └── com
│ │ └── github
│ │ └── games647
│ │ └── colorconsole
│ │ ├── bukkit
│ │ ├── ColorConsoleBukkit.java
│ │ └── ColorPluginAppender.java
│ │ ├── bungee
│ │ ├── ColorConsoleBungee.java
│ │ ├── ColorLogFormatter.java
│ │ └── ColorPluginAppender.java
│ │ ├── common
│ │ ├── ColorAppender.java
│ │ ├── CommonFormatter.java
│ │ ├── ConsoleConfig.java
│ │ ├── Log4JInstaller.java
│ │ ├── LoggingLevel.java
│ │ └── PlatformPlugin.java
│ │ └── sponge
│ │ ├── ColorConsoleSponge.java
│ │ └── SpongeAppender.java
└── resources
│ ├── bungee.yml
│ ├── config.yml
│ └── plugin.yml
└── test
└── java
└── com
└── github
└── games647
└── colorconsole
└── common
├── CommonFormatterTest.java
└── Log4JInstallerTest.java
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: maven
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 | ignore:
8 | # Ignore log4j, because it's a provided library
9 | - dependency-name: org.apache.logging.log4j:log4j-core
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Eclipse
2 | .classpath
3 | .project
4 | .settings/
5 |
6 | # NetBeans
7 | nbproject/
8 | nb-configuration.xml
9 |
10 | # IntelliJ
11 | *.iml
12 | *.ipr
13 | *.iws
14 | .idea/
15 |
16 | # Maven
17 | target/
18 | pom.xml.versionsBackup
19 |
20 | # Gradle
21 | .gradle
22 |
23 | # Ignore Gradle GUI config
24 | gradle-app.setting
25 |
26 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
27 | !gradle-wrapper.jar
28 |
29 | # various other potential build files
30 | build/
31 | bin/
32 | dist/
33 | manifest.mf
34 | *.log
35 |
36 | # Vim
37 | .*.sw[a-p]
38 |
39 | # virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
40 | hs_err_pid*
41 |
42 | # Mac filesystem dust
43 | .DS_Store
44 |
45 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # Use https://travis-ci.org/ for automatic testing
2 |
3 | # speed up testing https://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
4 | sudo: false
5 |
6 | # This is a java project
7 | language: java
8 |
9 | # Compile the project and run unit tests
10 | script: mvn test -B
11 |
12 | jdk:
13 | - oraclejdk8
14 | - openjdk11
15 |
16 | # Cache Maven dependencies
17 | cache:
18 | directories:
19 | - '$HOME/.m2/repository'
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2018
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ColorConsole
2 |
3 | 
4 |
5 | ## Description
6 |
7 | This lightweight plugin to make your console more colorful. It colorize the message depending on the log level. This
8 | means that important error messages will be printed in a red color. This gives you and your administrators a better
9 | overview about what's happening on your server.
10 |
11 | ## Features
12 |
13 | * Lightweight
14 | * Different colors for different log levels
15 | * Ignores specified log messages
16 | * Custom logFormat
17 | * Colorize plugin tags (customizable)
18 | * Removes color from plugins if you want to
19 | * Supports all versions above 1.8.8+
20 |
21 | ## Supports
22 |
23 | * BungeeCord/Waterfall
24 | * SpongeForge
25 | * Spigot/Paper
26 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.github.games647
6 |
7 | colorconsole
8 | jar
9 |
10 | ColorConsole
11 | 3.0.0
12 |
13 | https://dev.bukkit.org/bukkit-plugins/colorconsole/
14 |
15 | Print colorful console messages depending on the logging level
16 |
17 |
18 |
19 | UTF-8
20 |
21 | 1.8
22 | 1.8
23 |
24 |
25 |
26 | install
27 |
28 | ${project.name}
29 |
30 |
31 |
32 | org.apache.maven.plugins
33 | maven-shade-plugin
34 | 3.2.4
35 |
36 | false
37 | true
38 |
39 |
40 | org.fusesource.jansi:jansi
41 |
42 |
43 | META-INF/**
44 |
45 |
46 |
47 | true
48 |
49 |
50 |
51 | package
52 |
53 | shade
54 |
55 |
56 |
57 |
58 |
59 |
60 | org.codehaus.mojo
61 | templating-maven-plugin
62 | 1.0.0
63 |
64 |
65 | filter-src
66 |
67 | filter-sources
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | src/main/resources
77 |
78 | true
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | spigot-repo
87 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/
88 |
89 |
90 |
91 |
92 | sponge-repo
93 | https://repo.spongepowered.org/maven
94 |
95 |
96 |
97 | bungeecord-repo
98 | https://oss.sonatype.org/content/repositories/snapshots
99 |
100 |
101 |
102 |
103 |
104 |
105 | org.spigotmc
106 | spigot-api
107 | 1.16.5-R0.1-SNAPSHOT
108 | provided
109 |
110 |
111 |
112 |
113 | net.md-5
114 | bungeecord-api
115 | 1.16-R0.3
116 | provided
117 |
118 |
119 |
120 | org.spongepowered
121 | spongeapi
122 | 7.4.0
123 | provided
124 |
125 |
126 |
127 | org.fusesource.jansi
128 | jansi
129 | 2.4.0
130 |
131 |
132 |
133 |
134 | org.apache.logging.log4j
135 | log4j-core
136 |
137 | 2.1
138 |
139 | provided
140 |
141 |
142 |
143 | junit
144 | junit
145 | 4.13.2
146 | test
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/src/main/java-templates/com/github/games647/colorconsole/sponge/PomData.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.sponge;
2 |
3 | class PomData {
4 |
5 | public static final String ARTIFACT_ID = "${project.artifactId}";
6 | public static final String NAME = "${project.name}";
7 | public static final String VERSION = "${project.version}";
8 | public static final String URL = "${project.url}";
9 | public static final String DESCRIPTION = "${project.description}";
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/bukkit/ColorConsoleBukkit.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.bukkit;
2 |
3 | import com.github.games647.colorconsole.common.ColorAppender;
4 | import com.github.games647.colorconsole.common.ConsoleConfig;
5 | import com.github.games647.colorconsole.common.Log4JInstaller;
6 | import com.github.games647.colorconsole.common.LoggingLevel;
7 | import com.github.games647.colorconsole.common.PlatformPlugin;
8 |
9 | import java.io.Serializable;
10 | import java.nio.file.Path;
11 | import java.util.Collection;
12 | import java.util.logging.Level;
13 |
14 | import org.apache.logging.log4j.core.Appender;
15 | import org.apache.logging.log4j.core.Layout;
16 | import org.bukkit.Bukkit;
17 | import org.bukkit.configuration.ConfigurationSection;
18 | import org.bukkit.configuration.file.FileConfiguration;
19 | import org.bukkit.plugin.java.JavaPlugin;
20 |
21 | public class ColorConsoleBukkit extends JavaPlugin implements PlatformPlugin {
22 |
23 | private static final String TERMINAL_NAME = "TerminalConsole";
24 | private static final String CATSERVER_TERMINAL = "Console";
25 |
26 |
27 | private final Log4JInstaller installer = new Log4JInstaller();
28 |
29 | private Layout extends Serializable> oldLayout;
30 |
31 | @Override
32 | public void onLoad() {
33 | //try to run it as early as possible
34 | saveDefaultConfig();
35 | ConsoleConfig configuration = loadConfiguration();
36 |
37 | installLogFormat(configuration);
38 | }
39 |
40 | @Override
41 | public void onDisable() {
42 | revertLogFormat();
43 | }
44 |
45 | @Override
46 | public void installLogFormat(ConsoleConfig configuration) {
47 | try {
48 | oldLayout = installer.installLog4JFormat(this, getTerminalName(), configuration);
49 | } catch (ReflectiveOperationException reflectiveEx) {
50 | getLogger().log(Level.WARNING, "Failed to install log format", reflectiveEx);
51 | }
52 | }
53 |
54 | @Override
55 | public ColorAppender createAppender(Appender oldAppender, Collection hideMessages, boolean truncateCol) {
56 | return new ColorPluginAppender(oldAppender, hideMessages, truncateCol);
57 | }
58 |
59 | @Override
60 | public void revertLogFormat() {
61 | try {
62 | installer.revertLog4JFormat(getTerminalName(), oldLayout);
63 | } catch (ReflectiveOperationException ex) {
64 | getLogger().log(Level.WARNING, "Cannot revert log format", ex);
65 | }
66 | }
67 |
68 | @Override
69 | public Path getPluginFolder() {
70 | return getDataFolder().toPath();
71 | }
72 |
73 | @Override
74 | public ConsoleConfig loadConfiguration() {
75 | FileConfiguration bukkitConfig = getConfig();
76 |
77 | ConsoleConfig consoleConfig = new ConsoleConfig();
78 | consoleConfig.setLogFormat(bukkitConfig.getString("logFormat"));
79 | consoleConfig.setDateStyle(bukkitConfig.getString("dateStyle"));
80 |
81 | consoleConfig.getLevelColors().clear();
82 | if (bukkitConfig.getBoolean("colorLoggingLevel")) {
83 | ConfigurationSection levelSection = bukkitConfig.getConfigurationSection("Level");
84 | for (LoggingLevel level : LoggingLevel.values()) {
85 | consoleConfig.getLevelColors().put(level, levelSection.getString(level.name(), ""));
86 | }
87 | }
88 |
89 | consoleConfig.getPluginColors().clear();
90 | if (bukkitConfig.getBoolean("colorPluginTag")) {
91 | ConfigurationSection pluginSection = bukkitConfig.getConfigurationSection("Plugin");
92 | consoleConfig.setDefaultPluginColor(pluginSection.getString(ConsoleConfig.DEFAULT_PLUGIN_KEY));
93 | for (String pluginKey : pluginSection.getKeys(false)) {
94 | consoleConfig.getPluginColors().put(pluginKey, pluginSection.getString(pluginKey));
95 | }
96 | }
97 |
98 | consoleConfig.getHideMessages().clear();
99 | consoleConfig.getHideMessages().addAll(bukkitConfig.getStringList("hide-messages"));
100 |
101 | consoleConfig.setTruncateColor(bukkitConfig.getBoolean("truncateColor"));
102 | return consoleConfig;
103 | }
104 |
105 | private String getTerminalName() {
106 | if (Bukkit.getVersion().contains("Cat")) {
107 | return CATSERVER_TERMINAL;
108 | }
109 |
110 | return TERMINAL_NAME;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/bukkit/ColorPluginAppender.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.bukkit;
2 |
3 | import com.github.games647.colorconsole.common.ColorAppender;
4 | import com.google.common.collect.Sets;
5 |
6 | import java.util.Collection;
7 | import java.util.Set;
8 | import java.util.stream.Stream;
9 |
10 | import org.apache.logging.log4j.core.Appender;
11 | import org.apache.logging.log4j.core.LogEvent;
12 | import org.apache.logging.log4j.message.Message;
13 | import org.apache.logging.log4j.message.SimpleMessage;
14 | import org.bukkit.Bukkit;
15 | import org.bukkit.plugin.Plugin;
16 |
17 | import static java.util.stream.Collectors.toSet;
18 |
19 | public class ColorPluginAppender extends ColorAppender {
20 |
21 | private static final Set disabledPrefix = Sets.newHashSet(
22 | "net.minecraft",
23 | "Minecraft",
24 | "com.mojang",
25 | "com.sk89q",
26 | "ru.tehkode",
27 | "Minecraft.AWE"
28 | );
29 |
30 | private final boolean isVanillaAppender;
31 |
32 | public ColorPluginAppender(Appender oldAppender, Collection hideMessage, boolean truncateColor) {
33 | super(oldAppender, hideMessage, truncateColor);
34 | this.isVanillaAppender = "QueueLogAppender".equals(oldAppender.getClass().getSimpleName());
35 | }
36 |
37 | @Override
38 | public LogEvent onAppend(LogEvent logEvent) {
39 | String oldMessage = logEvent.getMessage().getFormattedMessage();
40 |
41 | String prefix = "";
42 | if (!logEvent.getLoggerName().isEmpty()) {
43 | // this only necessary in Bukkit for console messages like commands
44 | prefix = '[' + logEvent.getLoggerName() + "] ";
45 | }
46 |
47 | //PaperSpigot append prefix
48 | if (!isVanillaAppender
49 | && disabledPrefix.stream().noneMatch(disabled -> logEvent.getLoggerName().startsWith(disabled))) {
50 | oldMessage = prefix + oldMessage;
51 | }
52 |
53 | String message = formatter.colorizePluginTag(oldMessage);
54 | Message newMessage = new SimpleMessage(message);
55 | return clone(logEvent, logEvent.getLoggerName(), newMessage);
56 | }
57 |
58 | @Override
59 | protected Collection loadPluginNames() {
60 | return Stream.of(Bukkit.getPluginManager().getPlugins())
61 | .map(Plugin::getName)
62 | .collect(toSet());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/bungee/ColorConsoleBungee.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.bungee;
2 |
3 | import com.github.games647.colorconsole.common.ColorAppender;
4 | import com.github.games647.colorconsole.common.ConsoleConfig;
5 | import com.github.games647.colorconsole.common.Log4JInstaller;
6 | import com.github.games647.colorconsole.common.LoggingLevel;
7 | import com.github.games647.colorconsole.common.PlatformPlugin;
8 |
9 | import java.io.IOException;
10 | import java.io.Serializable;
11 | import java.nio.file.Path;
12 | import java.util.Collection;
13 | import java.util.EnumMap;
14 | import java.util.logging.Formatter;
15 | import java.util.logging.Handler;
16 | import java.util.logging.Level;
17 | import java.util.logging.Logger;
18 |
19 | import net.md_5.bungee.api.ProxyServer;
20 | import net.md_5.bungee.api.plugin.Plugin;
21 | import net.md_5.bungee.config.Configuration;
22 | import net.md_5.bungee.config.ConfigurationProvider;
23 | import net.md_5.bungee.config.YamlConfiguration;
24 |
25 | import org.apache.logging.log4j.core.Appender;
26 | import org.apache.logging.log4j.core.Layout;
27 |
28 | public class ColorConsoleBungee extends Plugin implements PlatformPlugin {
29 |
30 | private static final String TERMINAL_NAME = "TerminalConsole";
31 |
32 | private final Log4JInstaller installer = new Log4JInstaller();
33 | private Layout extends Serializable> oldLayout;
34 |
35 | @Override
36 | public void onEnable() {
37 | ConsoleConfig configuration;
38 | try {
39 | saveDefaultConfig();
40 | configuration = loadConfiguration();
41 | } catch (IOException ioEx) {
42 | getLogger().log(Level.SEVERE, "Unable to load configuration", ioEx);
43 | return;
44 | }
45 |
46 | installLogFormat(configuration);
47 | }
48 |
49 | @Override
50 | public void onDisable() {
51 | revertLogFormat();
52 | }
53 |
54 | @Override
55 | public void installLogFormat(ConsoleConfig config) {
56 | if (isWaterfallLog4J()) {
57 | try {
58 | oldLayout = installer.installLog4JFormat(this, TERMINAL_NAME, config);
59 | } catch (ReflectiveOperationException reflectiveEx) {
60 | getLogger().log(Level.WARNING, "Cannot install log format", reflectiveEx);
61 | }
62 | } else {
63 | getLogger().info("Waterfall Log4J not detected. Falling back to vanilla logging");
64 | ProxyServer bungee = ProxyServer.getInstance();
65 | Logger bungeeLogger = bungee.getLogger();
66 |
67 | Handler[] handlers = bungeeLogger.getHandlers();
68 | for (Handler handler : handlers) {
69 | Formatter oldFormatter = handler.getFormatter();
70 |
71 | EnumMap levelColors = config.getLevelColors();
72 | Collection hideMessages = config.getHideMessages();
73 | boolean truncateCol = config.isTruncateColor();
74 | ColorLogFormatter newForm = new ColorLogFormatter(oldFormatter, levelColors, hideMessages, truncateCol);
75 |
76 | newForm.initPluginColors(config.getPluginColors(), config.getDefaultPluginColor());
77 | handler.setFormatter(newForm);
78 | }
79 | }
80 | }
81 |
82 | @Override
83 | public ColorAppender createAppender(Appender oldAppender, Collection hideMessages, boolean truncateCol) {
84 | return new ColorPluginAppender(oldAppender, hideMessages, truncateCol);
85 | }
86 |
87 | @Override
88 | public void revertLogFormat() {
89 | if (isWaterfallLog4J()) {
90 | try {
91 | installer.revertLog4JFormat(TERMINAL_NAME, oldLayout);
92 | } catch (ReflectiveOperationException reflectiveEx) {
93 | getLogger().log(Level.WARNING, "Cannot revert logging format", reflectiveEx);
94 | }
95 | } else {
96 | ProxyServer bungee = ProxyServer.getInstance();
97 | Logger bungeeLogger = bungee.getLogger();
98 |
99 | Handler[] handlers = bungeeLogger.getHandlers();
100 | for (Handler handler : handlers) {
101 | Formatter formatter = handler.getFormatter();
102 | if (formatter instanceof ColorLogFormatter) {
103 | handler.setFormatter(((ColorLogFormatter) formatter).getOldFormatter());
104 | }
105 | }
106 | }
107 | }
108 |
109 | @Override
110 | public Path getPluginFolder() {
111 | return getDataFolder().toPath();
112 | }
113 |
114 | @Override
115 | public ConsoleConfig loadConfiguration() throws IOException {
116 | Path configPath = getPluginFolder().resolve(CONFIG_NAME);
117 |
118 | ConfigurationProvider yamlProvider = ConfigurationProvider.getProvider(YamlConfiguration.class);
119 | Configuration bungeeConfig = yamlProvider.load(configPath.toFile());
120 |
121 | ConsoleConfig consoleConfig = new ConsoleConfig();
122 | consoleConfig.setLogFormat(bungeeConfig.getString("logFormat"));
123 | consoleConfig.setDateStyle(bungeeConfig.getString("dateStyle"));
124 |
125 | consoleConfig.getLevelColors().clear();
126 | if (bungeeConfig.getBoolean("colorLoggingLevel")) {
127 | Configuration levelSection = bungeeConfig.getSection("Level");
128 | for (LoggingLevel level : LoggingLevel.values()) {
129 | consoleConfig.getLevelColors().put(level, levelSection.getString(level.name(), ""));
130 | }
131 | }
132 |
133 | consoleConfig.getPluginColors().clear();
134 | if (bungeeConfig.getBoolean("colorPluginTag")) {
135 | Configuration pluginSection = bungeeConfig.getSection("Plugin");
136 | consoleConfig.setDefaultPluginColor(pluginSection.getString(ConsoleConfig.DEFAULT_PLUGIN_KEY));
137 | for (String pluginKey : pluginSection.getKeys()) {
138 | consoleConfig.getPluginColors().put(pluginKey, pluginSection.getString(pluginKey));
139 | }
140 | }
141 |
142 | consoleConfig.getHideMessages().clear();
143 | consoleConfig.getHideMessages().addAll(bungeeConfig.getStringList("hide-messages"));
144 |
145 | consoleConfig.setTruncateColor(bungeeConfig.getBoolean("truncateColor"));
146 | return consoleConfig;
147 | }
148 |
149 | private boolean isWaterfallLog4J() {
150 | try {
151 | Class.forName("io.github.waterfallmc.waterfall.log4j.WaterfallLogger");
152 | return true;
153 | } catch (ClassNotFoundException e) {
154 | return false;
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/bungee/ColorLogFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.bungee;
2 |
3 | import com.github.games647.colorconsole.common.CommonFormatter;
4 | import com.github.games647.colorconsole.common.LoggingLevel;
5 |
6 | import java.io.PrintWriter;
7 | import java.io.StringWriter;
8 | import java.time.Instant;
9 | import java.time.format.DateTimeFormatter;
10 | import java.util.Collection;
11 | import java.util.EnumMap;
12 | import java.util.Map;
13 | import java.util.Set;
14 | import java.util.logging.Formatter;
15 | import java.util.logging.Level;
16 | import java.util.logging.LogRecord;
17 |
18 | import net.md_5.bungee.api.ProxyServer;
19 |
20 | import static java.util.stream.Collectors.toSet;
21 |
22 | public class ColorLogFormatter extends Formatter {
23 |
24 | private final Formatter oldFormatter;
25 | private final DateTimeFormatter date = DateTimeFormatter.ofPattern("HH:mm:ss");
26 |
27 | private final EnumMap levelColors;
28 | private final CommonFormatter formatter;
29 |
30 | public ColorLogFormatter(Formatter oldFormatter, EnumMap levels,
31 | Collection hideMessages, boolean truncateColor) {
32 | this.oldFormatter = oldFormatter;
33 | this.levelColors = levels;
34 | this.formatter = new CommonFormatter(hideMessages, truncateColor);
35 | }
36 |
37 | @Override
38 | public String format(LogRecord record) {
39 | if (formatter.shouldIgnore(record.getMessage())) {
40 | return "";
41 | }
42 |
43 | StringBuilder formatted = new StringBuilder();
44 | String message = oldFormatter.formatMessage(record);
45 |
46 | String levelColor = levelColors.getOrDefault(translateToLog4JName(record.getLevel()), "");
47 | formatted.append(levelColor);
48 |
49 | formatted.append(date.format(Instant.ofEpochMilli(record.getMillis())));
50 | formatted.append(" [");
51 | formatted.append(record.getLevel().getName());
52 | formatted.append("] ");
53 |
54 | formatted.append(formatter.getReset());
55 |
56 | formatted.append(formatter.colorizePluginTag(message));
57 |
58 | formatted.append('\n');
59 | if (record.getThrown() != null) {
60 | StringWriter writer = new StringWriter();
61 | record.getThrown().printStackTrace(new PrintWriter(writer));
62 | formatted.append(writer);
63 | }
64 |
65 | return formatted.toString();
66 | }
67 |
68 | public Formatter getOldFormatter() {
69 | return oldFormatter;
70 | }
71 |
72 | private LoggingLevel translateToLog4JName(Level level) {
73 | if (level == Level.SEVERE) {
74 | return LoggingLevel.ERROR;
75 | } else if (level == Level.WARNING) {
76 | return LoggingLevel.WARN;
77 | } else if (level == Level.INFO) {
78 | return LoggingLevel.INFO;
79 | } else if (level == Level.CONFIG) {
80 | return LoggingLevel.DEBUG;
81 | } else {
82 | return LoggingLevel.TRACE;
83 | }
84 | }
85 |
86 | private Set loadPluginNames() {
87 | return ProxyServer.getInstance().getPluginManager().getPlugins().stream()
88 | .map(plugin -> plugin.getDescription().getName())
89 | .collect(toSet());
90 | }
91 |
92 | public void initPluginColors(Map pluginColors, String def) {
93 | formatter.initPluginColors(loadPluginNames(), pluginColors, def);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/bungee/ColorPluginAppender.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.bungee;
2 |
3 | import com.github.games647.colorconsole.common.ColorAppender;
4 |
5 | import java.util.Collection;
6 |
7 | import net.md_5.bungee.api.ProxyServer;
8 | import net.md_5.bungee.api.plugin.Plugin;
9 | import net.md_5.bungee.api.plugin.PluginDescription;
10 |
11 | import org.apache.logging.log4j.core.Appender;
12 | import org.apache.logging.log4j.core.LogEvent;
13 | import org.apache.logging.log4j.message.Message;
14 | import org.apache.logging.log4j.message.SimpleMessage;
15 |
16 | import static java.util.stream.Collectors.toSet;
17 |
18 | public class ColorPluginAppender extends ColorAppender {
19 |
20 | private static final String PROXY_PREFIX = "BungeeCord";
21 |
22 | public ColorPluginAppender(Appender oldAppender, Collection hideMessages, boolean truncateCol) {
23 | super(oldAppender, hideMessages, truncateCol);
24 | }
25 |
26 | @Override
27 | public LogEvent onAppend(LogEvent logEvent) {
28 | String message = logEvent.getMessage().getFormattedMessage();
29 | String loggerName = logEvent.getLoggerName();
30 |
31 | //old message + potential prefix and color codes
32 | StringBuilder msgBuilder = new StringBuilder(message.length() + loggerName.length() + 10);
33 | if (!PROXY_PREFIX.equals(loggerName)) {
34 | msgBuilder.append('[')
35 | .append(formatter.colorizePluginName(loggerName))
36 | .append("] ");
37 | message = msgBuilder.append(message).toString();
38 | }
39 |
40 | Message newMessage = new SimpleMessage(message);
41 | return clone(logEvent, loggerName, newMessage);
42 | }
43 |
44 | @Override
45 | protected Collection loadPluginNames() {
46 | return ProxyServer.getInstance().getPluginManager().getPlugins().stream()
47 | .map(Plugin::getDescription)
48 | .map(PluginDescription::getName)
49 | .collect(toSet());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/ColorAppender.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.Collection;
5 | import java.util.Map;
6 |
7 | import org.apache.logging.log4j.core.Appender;
8 | import org.apache.logging.log4j.core.LogEvent;
9 | import org.apache.logging.log4j.core.appender.AbstractAppender;
10 | import org.apache.logging.log4j.core.impl.Log4jLogEvent;
11 | import org.apache.logging.log4j.message.Message;
12 |
13 | public abstract class ColorAppender extends AbstractAppender {
14 |
15 | private static final Method loggerClassGetter;
16 | private boolean disabled = loggerClassGetter == null;
17 |
18 | static {
19 | Method classGetter = null;
20 | for (Method method : LogEvent.class.getDeclaredMethods()) {
21 | String methodName = method.getName();
22 | if ("getLoggerFqcn".equalsIgnoreCase(methodName)
23 | || "getFQCN".equalsIgnoreCase(methodName)) {
24 | classGetter = method;
25 | method.setAccessible(true);
26 | break;
27 | }
28 | }
29 |
30 | loggerClassGetter = classGetter;
31 | }
32 |
33 | protected final Appender oldAppender;
34 | protected final CommonFormatter formatter;
35 |
36 | protected ColorAppender(Appender oldAppender, Collection hideMessages, boolean truncateColor) {
37 | super(oldAppender.getName(), null, oldAppender.getLayout());
38 |
39 | this.oldAppender = oldAppender;
40 | this.formatter = new CommonFormatter(hideMessages, truncateColor);
41 | }
42 |
43 | public void initPluginColors(Map configColors, String def) {
44 | formatter.initPluginColors(loadPluginNames(), configColors, def);
45 | }
46 |
47 | @Override
48 | public final void append(LogEvent logEvent) {
49 | if (oldAppender.isStarted()) {
50 | String oldMessage = logEvent.getMessage().getFormattedMessage();
51 | if (formatter.shouldIgnore(oldMessage)) {
52 | return;
53 | }
54 |
55 | oldAppender.append(onAppend(logEvent));
56 | }
57 | }
58 |
59 | public LogEvent onAppend(LogEvent logEvent) {
60 | String newLoggerName = formatter.colorizePluginName(logEvent.getLoggerName());
61 | return clone(logEvent, newLoggerName, logEvent.getMessage());
62 | }
63 |
64 | protected abstract Collection loadPluginNames();
65 |
66 | protected LogEvent clone(LogEvent oldEvent, String loggerName, Message message) {
67 | String className = null;
68 | if (!disabled) {
69 | try {
70 | className = (String) loggerClassGetter.invoke(oldEvent);
71 | } catch (ReflectiveOperationException refEx) {
72 | //if this method cannot be found then the other methods wouldn't work neither
73 | disabled = true;
74 | }
75 | }
76 |
77 | return new Log4jLogEvent(loggerName, oldEvent.getMarker(), className
78 | , oldEvent.getLevel(), message, oldEvent.getThrown());
79 | }
80 |
81 | public Appender getOldAppender() {
82 | return oldAppender;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/CommonFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import com.google.common.collect.ImmutableMap.Builder;
5 | import com.google.common.collect.ImmutableSet;
6 |
7 | import io.netty.util.internal.ThreadLocalRandom;
8 |
9 | import java.util.Arrays;
10 | import java.util.Collection;
11 | import java.util.Map;
12 | import java.util.Set;
13 | import java.util.regex.Pattern;
14 |
15 | import org.fusesource.jansi.Ansi;
16 | import org.fusesource.jansi.Ansi.Attribute;
17 | import org.fusesource.jansi.Ansi.Color;
18 | import org.fusesource.jansi.AnsiRenderer.Code;
19 |
20 | public class CommonFormatter {
21 |
22 | //copied from AnsiEscape in order to provide compatibility with older Minecraft versions
23 | private static final String CSI = "\u001b[";
24 | private static final char SUFFIX = 'm';
25 |
26 | private static final Pattern TAG_PATTERN = Pattern.compile("^\\[.+\\].*$");
27 |
28 | private final String reset = Ansi.ansi().a(Attribute.RESET).toString();
29 |
30 | private final Set ignoreMessages;
31 | private final boolean truncateColor;
32 | private Map pluginColors;
33 |
34 | public CommonFormatter(Collection ignoreMessages, boolean truncateColor) {
35 | this.ignoreMessages = ImmutableSet.copyOf(ignoreMessages);
36 | this.truncateColor = truncateColor;
37 | }
38 |
39 | public boolean shouldIgnore(String message) {
40 | for (String ignore : ignoreMessages) {
41 | if (message.contains(ignore)) {
42 | return true;
43 | }
44 | }
45 |
46 | return false;
47 | }
48 |
49 | public void initPluginColors(Iterable plugins, Map configColors, String def) {
50 | Color[] colors = Color.values();
51 | // remove black, because it's often hard to read
52 | colors = Arrays.copyOfRange(colors, 1, colors.length);
53 |
54 | Builder colorBuilder = ImmutableMap.builder();
55 | for (String plugin : plugins) {
56 | String styleCode = configColors.getOrDefault(plugin, def);
57 | if ("random".equalsIgnoreCase(styleCode)) {
58 | //ignore default
59 | styleCode = colors[ThreadLocalRandom.current().nextInt(colors.length - 1)].name();
60 | }
61 |
62 | colorBuilder.put(plugin, format(styleCode));
63 | }
64 |
65 | this.pluginColors = colorBuilder.build();
66 | }
67 |
68 | public String colorizePluginTag(String message) {
69 | String newMessage = message;
70 | if (!TAG_PATTERN.matcher(message).matches()) {
71 | return newMessage;
72 | }
73 |
74 | String startingColorCode = "";
75 | if (message.startsWith(CSI)) {
76 | int endColor = message.indexOf(SUFFIX);
77 |
78 | newMessage = message.substring(endColor + 1);
79 | if (!truncateColor) {
80 | startingColorCode = message.substring(0, endColor + 1);
81 | }
82 | }
83 |
84 | int startTag = newMessage.indexOf('[') + 1;
85 | int endTag = newMessage.indexOf(']', startTag);
86 |
87 | String pluginName = colorizePluginName(newMessage.substring(startTag, endTag));
88 | return '[' + pluginName + ']' + startingColorCode + newMessage.substring(endTag + 1) + reset;
89 | }
90 |
91 | public String colorizePluginName(String pluginName) {
92 | String pluginColor = pluginColors.getOrDefault(pluginName, "");
93 | return pluginColor + pluginName + reset;
94 | }
95 |
96 | private String format(String keyCode) {
97 | String[] formatParts = keyCode.split(" ");
98 | Ansi ansi = Ansi.ansi();
99 | for (String format : formatParts) {
100 | for (Code ansiCode : Code.values()) {
101 | if (ansiCode.name().equalsIgnoreCase(format)) {
102 | if (ansiCode.isAttribute()) {
103 | ansi.a(ansiCode.getAttribute());
104 | } else if (ansiCode.isBackground()) {
105 | ansi.bg(ansiCode.getColor());
106 | } else {
107 | ansi.fg(ansiCode.getColor());
108 | }
109 | }
110 | }
111 |
112 | if ("blink".equalsIgnoreCase(format)) {
113 | ansi.a(Attribute.BLINK_SLOW);
114 | continue;
115 | }
116 |
117 | if ("strikethrough".equalsIgnoreCase(format)) {
118 | ansi.a(Attribute.STRIKETHROUGH_ON);
119 | continue;
120 | }
121 |
122 | if ("hidden".equalsIgnoreCase(format)) {
123 | ansi.a(Attribute.CONCEAL_OFF);
124 | continue;
125 | }
126 |
127 | if ("dim".equalsIgnoreCase(format)) {
128 | ansi.a(Attribute.INTENSITY_FAINT);
129 | continue;
130 | }
131 |
132 | if ("reverse".equalsIgnoreCase(format)) {
133 | ansi.a(Attribute.NEGATIVE_ON);
134 | }
135 | }
136 |
137 | return ansi.toString();
138 | }
139 |
140 | public String getReset() {
141 | return reset;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/ConsoleConfig.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 | import java.util.EnumMap;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | public class ConsoleConfig {
11 |
12 | public static String DEFAULT_PLUGIN_KEY = "Default";
13 |
14 | private String logFormat;
15 | private String dateStyle;
16 |
17 | private final EnumMap levelColors = new EnumMap<>(LoggingLevel.class);
18 |
19 | private String defaultPluginColor;
20 | private final Map pluginColors = new HashMap<>();
21 |
22 | private final List hideMessages = new ArrayList<>();
23 | private boolean truncateColor;
24 |
25 | public String getLogFormat() {
26 | return logFormat;
27 | }
28 |
29 | public EnumMap getLevelColors() {
30 | return levelColors;
31 | }
32 |
33 | public String getDefaultPluginColor() {
34 | return defaultPluginColor;
35 | }
36 |
37 | public Map getPluginColors() {
38 | return pluginColors;
39 | }
40 |
41 | public Collection getHideMessages() {
42 | return hideMessages;
43 | }
44 |
45 | public String getDateStyle() {
46 | return dateStyle;
47 | }
48 |
49 | public boolean isTruncateColor() {
50 | return truncateColor;
51 | }
52 |
53 | public void setLogFormat(String logFormat) {
54 | this.logFormat = logFormat;
55 | }
56 |
57 | public void setDateStyle(String dateStyle) {
58 | this.dateStyle = dateStyle;
59 | }
60 |
61 | public void setDefaultPluginColor(String defaultPluginColor) {
62 | this.defaultPluginColor = defaultPluginColor;
63 | }
64 |
65 | public void setTruncateColor(boolean truncateColor) {
66 | this.truncateColor = truncateColor;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/Log4JInstaller.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | import com.google.common.annotations.VisibleForTesting;
4 | import com.google.common.base.Joiner;
5 |
6 | import java.io.Serializable;
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Method;
9 | import java.nio.charset.Charset;
10 | import java.util.Collection;
11 | import java.util.EnumMap;
12 | import java.util.Map;
13 |
14 | import org.apache.logging.log4j.LogManager;
15 | import org.apache.logging.log4j.core.Appender;
16 | import org.apache.logging.log4j.core.Layout;
17 | import org.apache.logging.log4j.core.Logger;
18 | import org.apache.logging.log4j.core.LoggerContext;
19 | import org.apache.logging.log4j.core.config.Configuration;
20 | import org.apache.logging.log4j.core.config.DefaultConfiguration;
21 | import org.apache.logging.log4j.core.layout.PatternLayout;
22 | import org.apache.logging.log4j.core.pattern.RegexReplacement;
23 |
24 | public class Log4JInstaller {
25 |
26 | public PatternLayout createLayout(String logFormat) throws ReflectiveOperationException {
27 | try {
28 | Method builder = PatternLayout.class
29 | .getDeclaredMethod("createLayout", String.class, Configuration.class, RegexReplacement.class
30 | , String.class, String.class);
31 |
32 | return (PatternLayout) builder.invoke(null, logFormat, new DefaultConfiguration(), null
33 | , Charset.defaultCharset().name(), "true");
34 | } catch (NoSuchMethodException methodEx) {
35 | return PatternLayout.newBuilder()
36 | .withCharset(Charset.defaultCharset())
37 | .withPattern(logFormat)
38 | .withConfiguration(new DefaultConfiguration())
39 | .withAlwaysWriteExceptions(true)
40 | .build();
41 | }
42 | }
43 |
44 | public void installAppender(Appender colorAppender, String terminalName) {
45 | Logger rootLogger = (Logger) LogManager.getRootLogger();
46 |
47 | colorAppender.start();
48 |
49 | rootLogger.removeAppender(getTerminalAppender(terminalName));
50 | rootLogger.addAppender(colorAppender);
51 | }
52 |
53 | public void setLayout(Layout extends Serializable> layout, Appender terminalAppender)
54 | throws ReflectiveOperationException {
55 | Field field = terminalAppender.getClass().getSuperclass().getDeclaredField("layout");
56 | field.setAccessible(true);
57 | field.set(terminalAppender, layout);
58 | }
59 |
60 | public Layout extends Serializable> installLog4JFormat(PlatformPlugin pl,
61 | String terminalName, ConsoleConfig config)
62 | throws ReflectiveOperationException {
63 | Appender terminalAppender = getTerminalAppender(terminalName);
64 | Layout extends Serializable> oldLayout = terminalAppender.getLayout();
65 |
66 | String logFormat = config.getLogFormat();
67 | String appenderClass = terminalAppender.getClass().getName();
68 | if (isMinecrellFormatted(oldLayout, appenderClass)) {
69 | logFormat = logFormat.replace("%msg", "%minecraftFormatting{%msg}");
70 | }
71 |
72 | logFormat = mapLoggingLevels(logFormat, config.getLevelColors());
73 | logFormat = formatDate(logFormat, config.getDateStyle());
74 |
75 | PatternLayout layout = createLayout(logFormat);
76 | setLayout(layout, terminalAppender);
77 |
78 | Collection hideMessages = config.getHideMessages();
79 | boolean truncateColor = config.isTruncateColor();
80 | ColorAppender appender = pl.createAppender(terminalAppender, hideMessages, truncateColor);
81 | appender.initPluginColors(config.getPluginColors(), config.getDefaultPluginColor());
82 |
83 | installAppender(appender, terminalName);
84 | return oldLayout;
85 | }
86 |
87 | public void revertLog4JFormat(String terminalName, Layout extends Serializable> oldLayout)
88 | throws ReflectiveOperationException {
89 | Appender terminalAppender = getTerminalAppender(terminalName);
90 |
91 | Logger rootLogger = (Logger) LogManager.getRootLogger();
92 | ColorAppender colorPluginAppender = null;
93 | for (Appender value : rootLogger.getAppenders().values()) {
94 | if (value instanceof ColorAppender) {
95 | colorPluginAppender = (ColorAppender) value;
96 | break;
97 | }
98 | }
99 |
100 | if (colorPluginAppender != null) {
101 | rootLogger.removeAppender(terminalAppender);
102 | rootLogger.addAppender(colorPluginAppender.getOldAppender());
103 | }
104 |
105 | setLayout(oldLayout, terminalAppender);
106 | }
107 |
108 | public Appender getTerminalAppender(String terminalName) {
109 | LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
110 | Configuration conf = ctx.getConfiguration();
111 | return conf.getAppender(terminalName);
112 | }
113 |
114 | @VisibleForTesting
115 | protected boolean isMinecrellFormatted(Layout extends Serializable> oldLayout, String appenderClass) {
116 | return oldLayout.toString().contains("minecraftFormatting") || appenderClass.contains("minecrell");
117 | }
118 |
119 | @VisibleForTesting
120 | protected String formatDate(String logFormat, String dateStyle) {
121 | return logFormat.replaceFirst("(%d)\\{.*?}", "%style{$0}{" + dateStyle + '}');
122 | }
123 |
124 | @VisibleForTesting
125 | protected String mapLoggingLevels(String logFormat, Map levelColors) {
126 | Map sortedColors = new EnumMap<>(LoggingLevel.class);
127 | sortedColors.putAll(levelColors);
128 |
129 | String levelFormat = Joiner.on(", ").withKeyValueSeparator('=').join(sortedColors);
130 | return logFormat.replace("%level", "%highlight{%level}{" + levelFormat + '}');
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/LoggingLevel.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | public enum LoggingLevel {
4 |
5 | FATAL,
6 |
7 | ERROR,
8 |
9 | WARN,
10 |
11 | INFO,
12 |
13 | DEBUG,
14 |
15 | TRACE
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/common/PlatformPlugin.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.common;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.nio.file.Files;
6 | import java.nio.file.Path;
7 | import java.util.Collection;
8 |
9 | import org.apache.logging.log4j.core.Appender;
10 |
11 | public interface PlatformPlugin {
12 |
13 | String CONFIG_NAME = "config.yml";
14 |
15 | void installLogFormat(ConsoleConfig configuration);
16 |
17 | ColorAppender createAppender(Appender oldAppender, Collection hideMessages, boolean truncateCol);
18 |
19 | //restore the old format
20 | void revertLogFormat();
21 |
22 | Path getPluginFolder();
23 |
24 | ConsoleConfig loadConfiguration() throws IOException;
25 |
26 | default void saveDefaultConfig() throws IOException {
27 | Path dataFolder = getPluginFolder();
28 | if (Files.notExists(dataFolder)) {
29 | Files.createDirectories(dataFolder);
30 | }
31 |
32 | Path configFile = dataFolder.resolve(CONFIG_NAME);
33 | if (Files.notExists(configFile)) {
34 | try (InputStream defaultStream = getClass().getClassLoader().getResourceAsStream(CONFIG_NAME)) {
35 | if (defaultStream == null) {
36 | return;
37 | }
38 |
39 | Files.copy(defaultStream, configFile);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/github/games647/colorconsole/sponge/ColorConsoleSponge.java:
--------------------------------------------------------------------------------
1 | package com.github.games647.colorconsole.sponge;
2 |
3 | import com.github.games647.colorconsole.common.ColorAppender;
4 | import com.github.games647.colorconsole.common.ConsoleConfig;
5 | import com.github.games647.colorconsole.common.Log4JInstaller;
6 | import com.github.games647.colorconsole.common.LoggingLevel;
7 | import com.github.games647.colorconsole.common.PlatformPlugin;
8 | import com.google.common.reflect.TypeToken;
9 | import com.google.inject.Inject;
10 |
11 | import java.io.IOException;
12 | import java.io.Serializable;
13 | import java.nio.file.Path;
14 | import java.util.Collection;
15 | import java.util.List;
16 | import java.util.Map.Entry;
17 |
18 | import ninja.leaping.configurate.ConfigurationNode;
19 | import ninja.leaping.configurate.objectmapping.ObjectMappingException;
20 | import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
21 |
22 | import org.apache.logging.log4j.core.Appender;
23 | import org.apache.logging.log4j.core.Layout;
24 | import org.slf4j.Logger;
25 | import org.spongepowered.api.config.ConfigDir;
26 | import org.spongepowered.api.event.Listener;
27 | import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
28 | import org.spongepowered.api.plugin.Plugin;
29 |
30 | @Plugin(id = PomData.ARTIFACT_ID, name = PomData.NAME, version = PomData.VERSION,
31 | url = PomData.URL, description = PomData.DESCRIPTION)
32 | public class ColorConsoleSponge implements PlatformPlugin {
33 |
34 | //Console is maybe required too?
35 | private static final String TERMINAL_NAME = "MinecraftConsole";
36 |
37 | private final Path pluginFolder;
38 | private final Logger logger;
39 |
40 | private final Log4JInstaller installer = new Log4JInstaller();
41 | private Layout extends Serializable> oldLayout;
42 |
43 | @Inject
44 | public ColorConsoleSponge(Logger logger, @ConfigDir(sharedRoot = false) Path dataFolder) {
45 | this.pluginFolder = dataFolder;
46 | this.logger = logger;
47 | }
48 |
49 | @Listener
50 | public void onPreInit(GamePreInitializationEvent preInitEvent) {
51 | ConsoleConfig configuration;
52 | try {
53 | saveDefaultConfig();
54 | configuration = loadConfiguration();
55 | } catch (IOException ioEx) {
56 | logger.warn("Failed to load configuration file. Canceling plugin setup", ioEx);
57 | return;
58 | }
59 |
60 | installLogFormat(configuration);
61 | }
62 |
63 | @Override
64 | public void installLogFormat(ConsoleConfig configuration) {
65 | try {
66 | oldLayout = installer.installLog4JFormat(this, TERMINAL_NAME, configuration);
67 | } catch (ReflectiveOperationException reflectiveEx) {
68 | logger.error("Failed to install log format", reflectiveEx);
69 | }
70 | }
71 |
72 | @Override
73 | public void revertLogFormat() {
74 | try {
75 | installer.revertLog4JFormat(TERMINAL_NAME, oldLayout);
76 | } catch (ReflectiveOperationException reflectiveEx) {
77 | logger.warn("Cannot revert log format", reflectiveEx);
78 | }
79 | }
80 |
81 | @Override
82 | public ColorAppender createAppender(Appender oldAppender, Collection hideMessages, boolean truncateCol) {
83 | return new SpongeAppender(oldAppender, hideMessages, truncateCol);
84 | }
85 |
86 | @Override
87 | public Path getPluginFolder() {
88 | return pluginFolder;
89 | }
90 |
91 | @Override
92 | public ConsoleConfig loadConfiguration() throws IOException {
93 | Path configPath = pluginFolder.resolve(CONFIG_NAME);
94 | YAMLConfigurationLoader configLoader = YAMLConfigurationLoader.builder().setPath(configPath).build();
95 |
96 | ConsoleConfig consoleConfig = new ConsoleConfig();
97 | ConfigurationNode rootNode = configLoader.load();
98 | consoleConfig.setLogFormat(rootNode.getNode("logFormat").getString());
99 | consoleConfig.setDateStyle(rootNode.getNode("dateStyle").getString());
100 |
101 | consoleConfig.getLevelColors().clear();
102 | if (rootNode.getNode("colorLoggingLevel").getBoolean()) {
103 | ConfigurationNode levelSection = rootNode.getNode("Level");
104 | for (LoggingLevel level : LoggingLevel.values()) {
105 | consoleConfig.getLevelColors().put(level, levelSection.getNode(level.name()).getString(""));
106 | }
107 | }
108 |
109 | consoleConfig.getPluginColors().clear();
110 | if (rootNode.getNode("colorPluginTag").getBoolean()) {
111 | ConfigurationNode pluginSection = rootNode.getNode("Plugin");
112 | consoleConfig.setDefaultPluginColor(pluginSection.getNode(ConsoleConfig.DEFAULT_PLUGIN_KEY).getString(""));
113 | for (Entry