Compare commits

...

39 Commits
2.3.1 ... main

Author SHA1 Message Date
games647 8846241df8
Add support for terminals in cat server
Fixes #33
2022-08-22 14:01:58 +02:00
games647 10af97eb50
Merge pull request #29 from games647/dependabot/maven/org.spongepowered-spongeapi-7.4.0
Bump spongeapi from 7.3.0 to 7.4.0
2021-12-18 14:45:32 +01:00
games647 2c8621b365
Merge pull request #28 from games647/dependabot/maven/org.fusesource.jansi-jansi-2.4.0
Bump jansi from 2.3.3 to 2.4.0
2021-12-18 14:45:14 +01:00
dependabot[bot] 8e4ffac2ca
Bump spongeapi from 7.3.0 to 7.4.0
Bumps [spongeapi](https://github.com/SpongePowered/SpongeAPI) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/SpongePowered/SpongeAPI/releases)
- [Commits](https://github.com/SpongePowered/SpongeAPI/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: org.spongepowered:spongeapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 18:05:46 +00:00
dependabot[bot] 4352123622
Bump jansi from 2.3.3 to 2.4.0
Bumps [jansi](https://github.com/fusesource/jansi) from 2.3.3 to 2.4.0.
- [Release notes](https://github.com/fusesource/jansi/releases)
- [Changelog](https://github.com/fusesource/jansi/blob/jansi-2.4.0/changelog.md)
- [Commits](https://github.com/fusesource/jansi/compare/jansi-2.3.3...jansi-2.4.0)

---
updated-dependencies:
- dependency-name: org.fusesource.jansi:jansi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-18 18:05:41 +00:00
games647 f12ca7acba
Merge pull request #24 from games647/dependabot/maven/org.fusesource.jansi-jansi-2.3.3
Bump jansi from 2.3.2 to 2.3.3
2021-06-14 10:30:42 +02:00
dependabot[bot] 0c798ab236
Bump jansi from 2.3.2 to 2.3.3
Bumps [jansi](https://github.com/fusesource/jansi) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/fusesource/jansi/releases)
- [Changelog](https://github.com/fusesource/jansi/blob/master/changelog.md)
- [Commits](https://github.com/fusesource/jansi/compare/jansi-2.3.2...jansi-2.3.3)

---
updated-dependencies:
- dependency-name: org.fusesource.jansi:jansi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-14 06:47:07 +00:00
games647 a0a2464798
Merge remote-tracking branch 'origin/main' 2021-05-19 17:47:04 +02:00
games647 67673ff6d7
Ignore log4j in dependency updates 2021-05-19 17:46:59 +02:00
games647 36ec26392d
Merge pull request #23 from games647/dependabot/maven/org.fusesource.jansi-jansi-2.3.2
Bump jansi from 2.3.0 to 2.3.2
2021-05-19 17:35:42 +02:00
dependabot[bot] d77fec09cd
Bump jansi from 2.3.0 to 2.3.2
Bumps [jansi](https://github.com/fusesource/jansi) from 2.3.0 to 2.3.2.
- [Release notes](https://github.com/fusesource/jansi/releases)
- [Changelog](https://github.com/fusesource/jansi/blob/master/changelog.md)
- [Commits](https://github.com/fusesource/jansi/compare/jansi-2.3.0...jansi-2.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-19 15:32:32 +00:00
games647 809b909c30
Update ANSI version
Fixes #22
2021-05-19 17:32:13 +02:00
games647 183b46aeac
Remove not needed dependency rules 2021-05-19 17:30:44 +02:00
games647 776c74b9ab
Merge pull request #20 from games647/dependabot/add-v2-config-file
Upgrade to GitHub-native Dependabot
2021-04-30 13:32:42 +02:00
dependabot-preview[bot] e81dbf507b
Upgrade to GitHub-native Dependabot 2021-04-29 21:52:36 +00:00
dependabot-preview[bot] e411a24808
Merge pull request #10 from games647/dependabot/maven/org.spongepowered-spongeapi-7.3.0 2020-09-01 14:08:23 +00:00
dependabot-preview[bot] 8eb476086c
Bump spongeapi from 7.2.0 to 7.3.0
Bumps [spongeapi](https://github.com/SpongePowered/SpongeAPI) from 7.2.0 to 7.3.0.
- [Release notes](https://github.com/SpongePowered/SpongeAPI/releases)
- [Commits](https://github.com/SpongePowered/SpongeAPI/compare/v7.2.0...v7.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-31 16:14:04 +00:00
dependabot-preview[bot] 009eb5f3a1
Merge pull request #9 from games647/dependabot/maven/net.md-5-bungeecord-api-1.16-R0.3 2020-07-21 08:46:36 +00:00
dependabot-preview[bot] 5906cf7956
Bump bungeecord-api from 1.13-SNAPSHOT to 1.16-R0.3
Bumps [bungeecord-api](https://github.com/SpigotMC/BungeeCord) from 1.13-SNAPSHOT to 1.16-R0.3.
- [Release notes](https://github.com/SpigotMC/BungeeCord/releases)
- [Commits](https://github.com/SpigotMC/BungeeCord/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-20 16:15:17 +00:00
dependabot-preview[bot] bbf67f8bdf
Merge pull request #7 from games647/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.2.4 2020-07-14 19:58:40 +00:00
dependabot-preview[bot] 1f18eaf49a
Merge pull request #8 from games647/dependabot/maven/org.spongepowered-spongeapi-7.2.0 2020-07-14 19:58:22 +00:00
dependabot-preview[bot] be30c970b2
Bump spongeapi from 7.1.0 to 7.2.0
Bumps [spongeapi](https://github.com/SpongePowered/SpongeAPI) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/SpongePowered/SpongeAPI/releases)
- [Commits](https://github.com/SpongePowered/SpongeAPI/compare/v7.1.0...v7.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-14 15:37:23 +00:00
dependabot-preview[bot] e574756415
Bump maven-shade-plugin from 3.2.1 to 3.2.4
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.2.1 to 3.2.4.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.2.1...maven-shade-plugin-3.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-14 15:37:00 +00:00
games647 4a11b78ba5
Do not add brackets for command output 2019-05-04 16:47:54 +02:00
games647 a974dfd859
Use regex for checking for the presence of plugin tags 2019-05-04 16:42:33 +02:00
games647 7ca5986b76
Ignore formatting of command output
Related #6
2019-05-03 14:35:42 +02:00
games647 1b493ec94d
Use a sorted map to check for deterministic results 2019-05-02 11:44:34 +02:00
games647 c59ac3c071
Use a single line to trick surefire testing 2019-05-02 11:37:35 +02:00
games647 1a1070e4ad
Refactor configuration handling 2019-05-02 11:27:55 +02:00
games647 82cf282d4e
Enable caching for travis 2019-05-02 11:26:56 +02:00
games647 6ece65130d
Improve compatibility with Paper 2018-07-29 18:33:21 +02:00
games647 9b93148afd
Don't transform because it's already compatible with 1.13 2018-07-25 16:57:58 +02:00
games647 c7e431e6fc
Fix FileAlreadyExistsException for sym linked folders 2018-01-27 21:53:34 +01:00
games647 8e73eecd51
Fix missing bungee repository (Fixes #5) 2017-11-30 09:36:32 +01:00
games647 f473188f1d
Replace java File API with the newer NIO API 2017-10-28 17:45:28 +02:00
games647 4ae4cb9f41
Fix showing plugin tag for Paper 2017-09-30 10:54:13 +02:00
games647 afe6f8edaf
Re add missing readme from last commit 2017-09-24 17:52:59 +02:00
games647 8cfe9343a1
Fix showing chat colors in newer PaperSpigot versions (Fixes #4) 2017-09-24 17:52:26 +02:00
games647 62ec40cc53
Minor clean up 2017-09-23 13:55:42 +02:00
28 changed files with 1017 additions and 652 deletions

9
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: weekly
ignore:
# Ignore log4j, because it's a provided library
- dependency-name: org.apache.logging.log4j:log4j-core

56
.gitignore vendored
View File

@ -1,37 +1,22 @@
# Eclipse stuff
/.classpath
/.project
/.settings
# Eclipse
.classpath
.project
.settings/
# netbeans
/nbproject
# NetBeans
nbproject/
nb-configuration.xml
# maven
/target
# vim
.*.sw[a-p]
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# various other potential build files
/build
/bin
/dist
/manifest.mf
*.log
# Mac filesystem dust
.DS_Store
# intellij
# IntelliJ
*.iml
*.ipr
*.iws
.idea/
# Maven
target/
pom.xml.versionsBackup
# Gradle
.gradle
@ -39,4 +24,21 @@ hs_err_pid*
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
!gradle-wrapper.jar
# various other potential build files
build/
bin/
dist/
manifest.mf
*.log
# Vim
.*.sw[a-p]
# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Mac filesystem dust
.DS_Store

View File

@ -1,13 +1,19 @@
# Use https://travis-ci.org/ for automatic tests
# Use https://travis-ci.org/ for automatic testing
# speed up testing http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
# speed up testing https://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
sudo: false
# This is a java project
language: java
script: mvn compile test
# Compile the project and run unit tests
script: mvn test -B
# We run on 8+
jdk:
- oraclejdk8
- openjdk11
# Cache Maven dependencies
cache:
directories:
- '$HOME/.m2/repository'

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016
Copyright (c) 2016-2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

25
README.md Normal file
View File

@ -0,0 +1,25 @@
# ColorConsole
![colorful log example](https://www.spigotmc.org/attachments/upload_2017-5-25_13-18-54-png.243110/)
## Description
This lightweight plugin to make your console more colorful. It colorize the message depending on the log level. This
means that important error messages will be printed in a red color. This gives you and your administrators a better
overview about what's happening on your server.
## Features
* Lightweight
* Different colors for different log levels
* Ignores specified log messages
* Custom logFormat
* Colorize plugin tags (customizable)
* Removes color from plugins if you want to
* Supports all versions above 1.8.8+
## Supports
* BungeeCord/Waterfall
* SpongeForge
* Spigot/Paper

View File

@ -1,17 +0,0 @@
# ColorConsole
![colorful log example](https://www.spigotmc.org/attachments/upload_2017-5-25_13-18-54-png.243110/)
## Description
This lightweight plugin to make your console more colorful. It colorize the message depending on the log level. This means that important error messages will be printed in a red color. This gives you and your administrators a better overview about what's happening on your server.
## Features
* Lightweight
* Different colors for different log levels
* Ignores specified log messages
* Custom logFormat
* Colorize plugin tags (customizable)
* Easy to use config
* Supports all versions above 1.8+

54
pom.xml
View File

@ -1,5 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.games647</groupId>
@ -8,15 +8,18 @@
<packaging>jar</packaging>
<name>ColorConsole</name>
<version>2.3.1</version>
<inceptionYear>2016</inceptionYear>
<url>http://dev.bukkit.org/bukkit-plugins/colorconsole/</url>
<version>3.0.0</version>
<url>https://dev.bukkit.org/bukkit-plugins/colorconsole/</url>
<description>
Print colorful console messages depending on the logging level
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
@ -25,29 +28,13 @@
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<version>3.2.4</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>
<include>org.fusesource.jansi:jansi</include>
</includes>
</artifactSet>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>org.fusesource.jansi:jansi</artifact>
@ -103,7 +90,12 @@
<!--Sponge-API-->
<repository>
<id>sponge-repo</id>
<url>http://repo.spongepowered.org/maven</url>
<url>https://repo.spongepowered.org/maven</url>
</repository>
<repository>
<id>bungeecord-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
@ -112,7 +104,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@ -120,21 +112,22 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.12-SNAPSHOT</version>
<version>1.16-R0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>7.0.0-SNAPSHOT</version>
<version>7.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.16</version>
<version>2.4.0</version>
<!-- Shade this library for ANSI codes -->
</dependency>
<dependency>
@ -145,5 +138,12 @@
<!--<version>2.0-beta9</version>-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,110 +1,112 @@
package com.github.games647.colorconsole.bukkit;
import com.github.games647.colorconsole.common.CommonLogInstaller;
import com.google.common.collect.Maps;
import com.github.games647.colorconsole.common.ColorAppender;
import com.github.games647.colorconsole.common.ConsoleConfig;
import com.github.games647.colorconsole.common.Log4JInstaller;
import com.github.games647.colorconsole.common.LoggingLevel;
import com.github.games647.colorconsole.common.PlatformPlugin;
import java.io.Serializable;
import java.util.Map;
import java.nio.file.Path;
import java.util.Collection;
import java.util.logging.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
public class ColorConsoleBukkit extends JavaPlugin {
public class ColorConsoleBukkit extends JavaPlugin implements PlatformPlugin {
private static String TERMINAL_NAME = "TerminalConsole";
private static final String TERMINAL_NAME = "TerminalConsole";
private static final String CATSERVER_TERMINAL = "Console";
private final Log4JInstaller installer = new Log4JInstaller();
private Layout<? extends Serializable> oldLayout;
@Override
public void onLoad() {
saveDefaultConfig();
Map<String, String> levelColors = Maps.newHashMap();
levelColors.put("FATAL", getConfig().getString("FATAL"));
levelColors.put("ERROR", getConfig().getString("ERROR"));
levelColors.put("WARN", getConfig().getString("WARN"));
levelColors.put("DEBUG", getConfig().getString("DEBUG"));
levelColors.put("TRACE", getConfig().getString("TRACE"));
//try to run it as early as possible
installLogFormat(levelColors);
}
@Override
public void onEnable() {
saveDefaultConfig();
ConsoleConfig configuration = loadConfiguration();
installLogFormat(configuration);
}
@Override
public void onDisable() {
//restore the old format
Appender terminalAppender = CommonLogInstaller.getTerminalAppender(TERMINAL_NAME);
Logger rootLogger = ((Logger) LogManager.getRootLogger());
ColorPluginAppender colorPluginAppender = null;
for (Appender value : rootLogger.getAppenders().values()) {
if (value instanceof ColorPluginAppender) {
colorPluginAppender = (ColorPluginAppender) value;
break;
}
}
if (colorPluginAppender != null) {
rootLogger.removeAppender(terminalAppender);
rootLogger.addAppender(colorPluginAppender.getOldAppender());
}
revertLogFormat();
}
@Override
public void installLogFormat(ConsoleConfig configuration) {
try {
CommonLogInstaller.setLayout(oldLayout, terminalAppender);
oldLayout = installer.installLog4JFormat(this, getTerminalName(), configuration);
} catch (ReflectiveOperationException reflectiveEx) {
getLogger().log(Level.WARNING, "Failed to install log format", reflectiveEx);
}
}
@Override
public ColorAppender createAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol) {
return new ColorPluginAppender(oldAppender, hideMessages, truncateCol);
}
@Override
public void revertLogFormat() {
try {
installer.revertLog4JFormat(getTerminalName(), oldLayout);
} catch (ReflectiveOperationException ex) {
getLogger().log(Level.WARNING, "Cannot revert log format", ex);
}
}
private void installLogFormat(Map<String, String> levelColors) {
Appender terminalAppender = CommonLogInstaller.getTerminalAppender(TERMINAL_NAME);
@Override
public Path getPluginFolder() {
return getDataFolder().toPath();
}
oldLayout = terminalAppender.getLayout();
String logFormat = getConfig().getString("logFormat");
if (oldLayout.toString().contains("minecraftFormatting")) {
logFormat = logFormat.replace("%msg", "%minecraftFormatting{%msg}");
}
@Override
public ConsoleConfig loadConfiguration() {
FileConfiguration bukkitConfig = getConfig();
if (getConfig().getBoolean("colorLoggingLevel")) {
logFormat = logFormat.replace("%level", "%highlight{%level}{"
+ "FATAL=" + getConfig().getString("FATAL") + ", "
+ "ERROR=" + getConfig().getString("ERROR") + ", "
+ "WARN=" + getConfig().getString("WARN") + ", "
+ "INFO=" + getConfig().getString("INFO") + ", "
+ "DEBUG=" + getConfig().getString("DEBUG") + ", "
+ "TRACE=" + getConfig().getString("TRACE") + "}");
}
ConsoleConfig consoleConfig = new ConsoleConfig();
consoleConfig.setLogFormat(bukkitConfig.getString("logFormat"));
consoleConfig.setDateStyle(bukkitConfig.getString("dateStyle"));
String dateStyle = getConfig().getString("dateStyle");
logFormat = logFormat.replaceFirst("(%d)\\{.{1,}\\}", "%style{$0}{" + dateStyle + "}");
try {
PatternLayout layout = CommonLogInstaller.createLayout(logFormat);
CommonLogInstaller.setLayout(layout, terminalAppender);
} catch (ReflectiveOperationException ex) {
getLogger().log(Level.WARNING, "Cannot install log format", ex);
}
ColorPluginAppender pluginAppender = new ColorPluginAppender(terminalAppender, getConfig(), levelColors);
Map<String, String> colors = Maps.newHashMap();
for (Map.Entry<String, Object> entry : getConfig().getValues(false).entrySet()) {
if (!entry.getKey().startsWith("P-")) {
continue;
consoleConfig.getLevelColors().clear();
if (bukkitConfig.getBoolean("colorLoggingLevel")) {
ConfigurationSection levelSection = bukkitConfig.getConfigurationSection("Level");
for (LoggingLevel level : LoggingLevel.values()) {
consoleConfig.getLevelColors().put(level, levelSection.getString(level.name(), ""));
}
colors.put(entry.getKey().replace("P-", ""), (String) entry.getValue());
}
pluginAppender.initPluginColors(colors, getConfig().getString("PLUGIN"));
CommonLogInstaller.installAppender(pluginAppender, TERMINAL_NAME);
consoleConfig.getPluginColors().clear();
if (bukkitConfig.getBoolean("colorPluginTag")) {
ConfigurationSection pluginSection = bukkitConfig.getConfigurationSection("Plugin");
consoleConfig.setDefaultPluginColor(pluginSection.getString(ConsoleConfig.DEFAULT_PLUGIN_KEY));
for (String pluginKey : pluginSection.getKeys(false)) {
consoleConfig.getPluginColors().put(pluginKey, pluginSection.getString(pluginKey));
}
}
consoleConfig.getHideMessages().clear();
consoleConfig.getHideMessages().addAll(bukkitConfig.getStringList("hide-messages"));
consoleConfig.setTruncateColor(bukkitConfig.getBoolean("truncateColor"));
return consoleConfig;
}
private String getTerminalName() {
if (Bukkit.getVersion().contains("Cat")) {
return CATSERVER_TERMINAL;
}
return TERMINAL_NAME;
}
}

View File

@ -1,11 +1,10 @@
package com.github.games647.colorconsole.bukkit;
import com.github.games647.colorconsole.common.ColorAppender;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Set;
import java.util.stream.Stream;
import org.apache.logging.log4j.core.Appender;
@ -13,29 +12,53 @@ import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.Plugin;
import static java.util.stream.Collectors.toSet;
public class ColorPluginAppender extends ColorAppender {
public ColorPluginAppender(Appender oldAppender, FileConfiguration config, Map<String, String> levelColors) {
super(oldAppender
, config.getStringList("hide-messages")
, config.getBoolean("colorPluginTag")
, config.getBoolean("truncateColor")
, config.getBoolean("colorMessage") ? levelColors : Collections.emptyMap());
private static final Set<String> disabledPrefix = Sets.newHashSet(
"net.minecraft",
"Minecraft",
"com.mojang",
"com.sk89q",
"ru.tehkode",
"Minecraft.AWE"
);
private final boolean isVanillaAppender;
public ColorPluginAppender(Appender oldAppender, Collection<String> hideMessage, boolean truncateColor) {
super(oldAppender, hideMessage, truncateColor);
this.isVanillaAppender = "QueueLogAppender".equals(oldAppender.getClass().getSimpleName());
}
@Override
public LogEvent onAppend(LogEvent logEvent) {
String oldMessage = logEvent.getMessage().getFormattedMessage();
Message newMessage = new SimpleMessage(formatter.colorizePluginTag(oldMessage, logEvent.getLevel().name()));
String prefix = "";
if (!logEvent.getLoggerName().isEmpty()) {
// this only necessary in Bukkit for console messages like commands
prefix = '[' + logEvent.getLoggerName() + "] ";
}
//PaperSpigot append prefix
if (!isVanillaAppender
&& disabledPrefix.stream().noneMatch(disabled -> logEvent.getLoggerName().startsWith(disabled))) {
oldMessage = prefix + oldMessage;
}
String message = formatter.colorizePluginTag(oldMessage);
Message newMessage = new SimpleMessage(message);
return clone(logEvent, logEvent.getLoggerName(), newMessage);
}
@Override
protected Collection<String> loadPluginNames() {
return Stream.of(Bukkit.getPluginManager().getPlugins())
.map(plugin -> plugin.getName())
.collect(Collectors.toSet());
.map(Plugin::getName)
.collect(toSet());
}
}

View File

@ -1,10 +1,16 @@
package com.github.games647.colorconsole.bungee;
import java.io.File;
import com.github.games647.colorconsole.common.ColorAppender;
import com.github.games647.colorconsole.common.ConsoleConfig;
import com.github.games647.colorconsole.common.Log4JInstaller;
import com.github.games647.colorconsole.common.LoggingLevel;
import com.github.games647.colorconsole.common.PlatformPlugin;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.io.Serializable;
import java.nio.file.Path;
import java.util.Collection;
import java.util.EnumMap;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
@ -16,69 +22,136 @@ import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
public class ColorConsoleBungee extends Plugin {
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
private Configuration configuration;
public class ColorConsoleBungee extends Plugin implements PlatformPlugin {
private static final String TERMINAL_NAME = "TerminalConsole";
private final Log4JInstaller installer = new Log4JInstaller();
private Layout<? extends Serializable> oldLayout;
@Override
public void onLoad() {
saveDefaultConfig();
File configFile = new File(getDataFolder(), "config.yml");
public void onEnable() {
ConsoleConfig configuration;
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
saveDefaultConfig();
configuration = loadConfiguration();
} catch (IOException ioEx) {
getLogger().log(Level.SEVERE, "Unable to load configuration", ioEx);
return;
}
//try to run it as early as possible
installLogFormat();
installLogFormat(configuration);
}
@Override
public void onDisable() {
//restore the old format
ProxyServer bungee = ProxyServer.getInstance();
Logger bungeeLogger = bungee.getLogger();
revertLogFormat();
}
Handler[] handlers = bungeeLogger.getHandlers();
for (Handler handler : handlers) {
Formatter formatter = handler.getFormatter();
if (formatter instanceof ColorLogFormatter) {
handler.setFormatter(((ColorLogFormatter) formatter).getOldFormatter());
@Override
public void installLogFormat(ConsoleConfig config) {
if (isWaterfallLog4J()) {
try {
oldLayout = installer.installLog4JFormat(this, TERMINAL_NAME, config);
} catch (ReflectiveOperationException reflectiveEx) {
getLogger().log(Level.WARNING, "Cannot install log format", reflectiveEx);
}
} else {
getLogger().info("Waterfall Log4J not detected. Falling back to vanilla logging");
ProxyServer bungee = ProxyServer.getInstance();
Logger bungeeLogger = bungee.getLogger();
Handler[] handlers = bungeeLogger.getHandlers();
for (Handler handler : handlers) {
Formatter oldFormatter = handler.getFormatter();
EnumMap<LoggingLevel, String> levelColors = config.getLevelColors();
Collection<String> hideMessages = config.getHideMessages();
boolean truncateCol = config.isTruncateColor();
ColorLogFormatter newForm = new ColorLogFormatter(oldFormatter, levelColors, hideMessages, truncateCol);
newForm.initPluginColors(config.getPluginColors(), config.getDefaultPluginColor());
handler.setFormatter(newForm);
}
}
}
public Configuration getConfiguration() {
return configuration;
@Override
public ColorAppender createAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol) {
return new ColorPluginAppender(oldAppender, hideMessages, truncateCol);
}
private void installLogFormat() {
ProxyServer bungee = ProxyServer.getInstance();
Logger bungeeLogger = bungee.getLogger();
@Override
public void revertLogFormat() {
if (isWaterfallLog4J()) {
try {
installer.revertLog4JFormat(TERMINAL_NAME, oldLayout);
} catch (ReflectiveOperationException reflectiveEx) {
getLogger().log(Level.WARNING, "Cannot revert logging format", reflectiveEx);
}
} else {
ProxyServer bungee = ProxyServer.getInstance();
Logger bungeeLogger = bungee.getLogger();
Handler[] handlers = bungeeLogger.getHandlers();
for (Handler handler : handlers) {
Formatter oldFormatter = handler.getFormatter();
ColorLogFormatter newFormatter = new ColorLogFormatter(this, oldFormatter);
newFormatter.initPluginColors(getConfiguration().getString("PLUGIN"));
handler.setFormatter(newFormatter);
Handler[] handlers = bungeeLogger.getHandlers();
for (Handler handler : handlers) {
Formatter formatter = handler.getFormatter();
if (formatter instanceof ColorLogFormatter) {
handler.setFormatter(((ColorLogFormatter) formatter).getOldFormatter());
}
}
}
}
private void saveDefaultConfig() {
getDataFolder().mkdir();
@Override
public Path getPluginFolder() {
return getDataFolder().toPath();
}
Path configFile = getDataFolder().toPath().resolve("config.yml");
if (Files.notExists(configFile)) {
try (InputStream in = getResourceAsStream("config.yml")) {
Files.copy(in, configFile);
} catch (IOException ioExc) {
getLogger().log(Level.SEVERE, "Error saving default config", ioExc);
@Override
public ConsoleConfig loadConfiguration() throws IOException {
Path configPath = getPluginFolder().resolve(CONFIG_NAME);
ConfigurationProvider yamlProvider = ConfigurationProvider.getProvider(YamlConfiguration.class);
Configuration bungeeConfig = yamlProvider.load(configPath.toFile());
ConsoleConfig consoleConfig = new ConsoleConfig();
consoleConfig.setLogFormat(bungeeConfig.getString("logFormat"));
consoleConfig.setDateStyle(bungeeConfig.getString("dateStyle"));
consoleConfig.getLevelColors().clear();
if (bungeeConfig.getBoolean("colorLoggingLevel")) {
Configuration levelSection = bungeeConfig.getSection("Level");
for (LoggingLevel level : LoggingLevel.values()) {
consoleConfig.getLevelColors().put(level, levelSection.getString(level.name(), ""));
}
}
consoleConfig.getPluginColors().clear();
if (bungeeConfig.getBoolean("colorPluginTag")) {
Configuration pluginSection = bungeeConfig.getSection("Plugin");
consoleConfig.setDefaultPluginColor(pluginSection.getString(ConsoleConfig.DEFAULT_PLUGIN_KEY));
for (String pluginKey : pluginSection.getKeys()) {
consoleConfig.getPluginColors().put(pluginKey, pluginSection.getString(pluginKey));
}
}
consoleConfig.getHideMessages().clear();
consoleConfig.getHideMessages().addAll(bungeeConfig.getStringList("hide-messages"));
consoleConfig.setTruncateColor(bungeeConfig.getBoolean("truncateColor"));
return consoleConfig;
}
private boolean isWaterfallLog4J() {
try {
Class.forName("io.github.waterfallmc.waterfall.log4j.WaterfallLogger");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}

View File

@ -1,50 +1,37 @@
package com.github.games647.colorconsole.bungee;
import com.github.games647.colorconsole.common.CommonFormatter;
import com.google.common.collect.Maps;
import com.github.games647.colorconsole.common.LoggingLevel;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.stream.Collectors;
import net.md_5.bungee.api.ProxyServer;
import static java.util.stream.Collectors.toSet;
public class ColorLogFormatter extends Formatter {
private final ColorConsoleBungee plugin;
private final Formatter oldFormatter;
private final DateTimeFormatter date = DateTimeFormatter.ofPattern("HH:mm:ss");
private final DateFormat date = new SimpleDateFormat("HH:mm:ss");
private final EnumMap<LoggingLevel, String> levelColors;
private final CommonFormatter formatter;
public ColorLogFormatter(ColorConsoleBungee plugin, Formatter oldFormatter) {
this.plugin = plugin;
public ColorLogFormatter(Formatter oldFormatter, EnumMap<LoggingLevel, String> levels,
Collection<String> hideMessages, boolean truncateColor) {
this.oldFormatter = oldFormatter;
List<String> ignoreMessages = plugin.getConfiguration().getStringList("hide-messages");
boolean colorizeTag = plugin.getConfiguration().getBoolean("colorPluginTag");
boolean truncateColor = plugin.getConfiguration().getBoolean("truncateColor", false);
Map<String, String> levelColors = Maps.newHashMap();
if (plugin.getConfiguration().getBoolean("colorMessage", false)) {
levelColors.put("FATAL", plugin.getConfiguration().getString("FATAL"));
levelColors.put("ERROR", plugin.getConfiguration().getString("ERROR"));
levelColors.put("WARN", plugin.getConfiguration().getString("WARN"));
levelColors.put("DEBUG", plugin.getConfiguration().getString("DEBUG"));
levelColors.put("TRACE", plugin.getConfiguration().getString("TRACE"));
}
this.formatter = new CommonFormatter(ignoreMessages, colorizeTag, truncateColor, levelColors);
this.levelColors = levels;
this.formatter = new CommonFormatter(hideMessages, truncateColor);
}
@Override
@ -56,22 +43,17 @@ public class ColorLogFormatter extends Formatter {
StringBuilder formatted = new StringBuilder();
String message = oldFormatter.formatMessage(record);
String levelColor = "";
if (plugin.getConfiguration().getBoolean("colorLoggingLevel")) {
String log4JName = translateToLog4JName(record.getLevel());
levelColor = formatter.format(plugin.getConfiguration().getString(log4JName));
}
String levelColor = levelColors.getOrDefault(translateToLog4JName(record.getLevel()), "");
formatted.append(levelColor);
formatted.append(this.date.format(record.getMillis()));
formatted.append(date.format(Instant.ofEpochMilli(record.getMillis())));
formatted.append(" [");
formatted.append(record.getLevel().getName());
formatted.append("] ");
formatted.append(formatter.getReset());
formatted.append(formatter.colorizePluginTag(message, translateToLog4JName(record.getLevel())));
formatted.append(formatter.colorizePluginTag(message));
formatted.append('\n');
if (record.getThrown() != null) {
@ -87,38 +69,27 @@ public class ColorLogFormatter extends Formatter {
return oldFormatter;
}
private String translateToLog4JName(Level level) {
private LoggingLevel translateToLog4JName(Level level) {
if (level == Level.SEVERE) {
return "ERROR";
return LoggingLevel.ERROR;
} else if (level == Level.WARNING) {
return "WARN";
return LoggingLevel.WARN;
} else if (level == Level.INFO) {
return "INFO";
return LoggingLevel.INFO;
} else if (level == Level.CONFIG) {
return "DEBUG";
return LoggingLevel.DEBUG;
} else {
return "TRACE";
return LoggingLevel.TRACE;
}
}
private Set<String> loadPluginNames() {
return ProxyServer.getInstance().getPluginManager().getPlugins().stream()
.map(plugin -> plugin.getDescription().getName())
.collect(Collectors.toSet());
.collect(toSet());
}
public void initPluginColors(String def) {
Set<String> plugins = loadPluginNames();
Map<String, String> pluginColors = new HashMap<>();
for (String pluginName : plugins) {
String color = plugin.getConfiguration().getString("P-" + pluginName);
if (color == null) {
continue;
}
pluginColors.put(pluginName, color);
}
formatter.initPluginColors(plugins, pluginColors, def);
public void initPluginColors(Map<String, String> pluginColors, String def) {
formatter.initPluginColors(loadPluginNames(), pluginColors, def);
}
}

View File

@ -0,0 +1,51 @@
package com.github.games647.colorconsole.bungee;
import com.github.games647.colorconsole.common.ColorAppender;
import java.util.Collection;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import static java.util.stream.Collectors.toSet;
public class ColorPluginAppender extends ColorAppender {
private static final String PROXY_PREFIX = "BungeeCord";
public ColorPluginAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol) {
super(oldAppender, hideMessages, truncateCol);
}
@Override
public LogEvent onAppend(LogEvent logEvent) {
String message = logEvent.getMessage().getFormattedMessage();
String loggerName = logEvent.getLoggerName();
//old message + potential prefix and color codes
StringBuilder msgBuilder = new StringBuilder(message.length() + loggerName.length() + 10);
if (!PROXY_PREFIX.equals(loggerName)) {
msgBuilder.append('[')
.append(formatter.colorizePluginName(loggerName))
.append("] ");
message = msgBuilder.append(message).toString();
}
Message newMessage = new SimpleMessage(message);
return clone(logEvent, loggerName, newMessage);
}
@Override
protected Collection<String> loadPluginNames() {
return ProxyServer.getInstance().getPluginManager().getPlugins().stream()
.map(Plugin::getDescription)
.map(PluginDescription::getName)
.collect(toSet());
}
}

View File

@ -12,26 +12,32 @@ import org.apache.logging.log4j.message.Message;
public abstract class ColorAppender extends AbstractAppender {
private final Appender oldAppender;
private Method loggerClassGetter;
private static final Method loggerClassGetter;
private boolean disabled = loggerClassGetter == null;
static {
Method classGetter = null;
for (Method method : LogEvent.class.getDeclaredMethods()) {
String methodName = method.getName();
if ("getLoggerFqcn".equalsIgnoreCase(methodName)
|| "getFQCN".equalsIgnoreCase(methodName)) {
classGetter = method;
method.setAccessible(true);
break;
}
}
loggerClassGetter = classGetter;
}
protected final Appender oldAppender;
protected final CommonFormatter formatter;
protected ColorAppender(Appender oldAppender, Collection<String> hideMessages
, boolean colorizeTag, boolean truncateColor, Map<String, String> levelColors) {
protected ColorAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateColor) {
super(oldAppender.getName(), null, oldAppender.getLayout());
this.oldAppender = oldAppender;
this.formatter = new CommonFormatter(hideMessages, colorizeTag, truncateColor, levelColors);
for (Method method : LogEvent.class.getDeclaredMethods()) {
String methodName = method.getName();
if (methodName.equalsIgnoreCase("getLoggerFqcn")
|| methodName.equalsIgnoreCase("getFQCN")) {
loggerClassGetter = method;
method.setAccessible(true);
}
}
this.formatter = new CommonFormatter(hideMessages, truncateColor);
}
public void initPluginColors(Map<String, String> configColors, String def) {
@ -50,18 +56,21 @@ public abstract class ColorAppender extends AbstractAppender {
}
}
protected abstract LogEvent onAppend(LogEvent logEvent);
public LogEvent onAppend(LogEvent logEvent) {
String newLoggerName = formatter.colorizePluginName(logEvent.getLoggerName());
return clone(logEvent, newLoggerName, logEvent.getMessage());
}
protected abstract Collection<String> loadPluginNames();
protected LogEvent clone(LogEvent oldEvent, String loggerName, Message message) {
String className = null;
if (loggerClassGetter != null) {
if (!disabled) {
try {
className = (String) loggerClassGetter.invoke(oldEvent);
} catch (ReflectiveOperationException refEx) {
//if this method cannot be found then the other methods wouldn't work neither
loggerClassGetter = null;
disabled = true;
}
}

View File

@ -4,11 +4,13 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSet;
import io.netty.util.internal.ThreadLocalRandom;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Attribute;
@ -17,41 +19,24 @@ import org.fusesource.jansi.AnsiRenderer.Code;
public class CommonFormatter {
//copied from AnsiEscape in order to provide compatibility with older minecraft versions
//copied from AnsiEscape in order to provide compatibility with older Minecraft versions
private static final String CSI = "\u001b[";
private static final String SUFFIX = "m";
private final String reset = Ansi.ansi().a(Ansi.Attribute.RESET).toString();
private static final char SUFFIX = 'm';
private static final Pattern TAG_PATTERN = Pattern.compile("^\\[.+\\].*$");
private final String reset = Ansi.ansi().a(Attribute.RESET).toString();
private final Set<String> ignoreMessages;
private final boolean colorizeTag;
private final boolean truncateColor;
private Map<String, String> pluginColors;
private Map<String, String> levelColors;
public CommonFormatter(Collection<String> ignoreMessages, boolean colorizeTag, boolean truncateColor
, Map<String, String> levelColors) {
public CommonFormatter(Collection<String> ignoreMessages, boolean truncateColor) {
this.ignoreMessages = ImmutableSet.copyOf(ignoreMessages);
this.colorizeTag = colorizeTag;
this.truncateColor = truncateColor;
Builder<String, String> builder = ImmutableMap.builder();
for (Map.Entry<String, String> entry : levelColors.entrySet()) {
if (entry.getKey().equals("INFO")) {
continue;
}
builder.put(entry.getKey(), format(entry.getValue()));
}
this.levelColors = builder.build();
}
public boolean shouldIgnore(String message) {
if (message == null) {
return false;
}
for (String ignore : ignoreMessages) {
if (message.contains(ignore)) {
return true;
@ -61,18 +46,17 @@ public class CommonFormatter {
return false;
}
public void initPluginColors(Collection<String> plugins, Map<String, String> configColors, String def) {
Random random = new Random();
public void initPluginColors(Iterable<String> plugins, Map<String, String> configColors, String def) {
Color[] colors = Color.values();
//remove black, because it's often hard to read
// remove black, because it's often hard to read
colors = Arrays.copyOfRange(colors, 1, colors.length);
ImmutableMap.Builder<String, String> colorBuilder = ImmutableMap.builder();
Builder<String, String> colorBuilder = ImmutableMap.builder();
for (String plugin : plugins) {
String styleCode = configColors.getOrDefault(plugin, def);
if (styleCode.equalsIgnoreCase("random")) {
if ("random".equalsIgnoreCase(styleCode)) {
//ignore default
styleCode = colors[random.nextInt(colors.length - 1)].name();
styleCode = colors[ThreadLocalRandom.current().nextInt(colors.length - 1)].name();
}
colorBuilder.put(plugin, format(styleCode));
@ -81,45 +65,35 @@ public class CommonFormatter {
this.pluginColors = colorBuilder.build();
}
public String colorizePluginTag(String message, String level) {
if (!message.contains("[") || !message.contains("]")) {
return levelColors.getOrDefault(level, "") + message + reset;
}
public String colorizePluginTag(String message) {
String newMessage = message;
if (!TAG_PATTERN.matcher(message).matches()) {
return newMessage;
}
String startingColorCode = "";
if (message.startsWith(CSI)) {
int endColor = message.indexOf(SUFFIX);
newMessage = message.substring(endColor + 1, message.length());
newMessage = message.substring(endColor + 1);
if (!truncateColor) {
startingColorCode = message.substring(0, endColor + 1);
}
}
if (!newMessage.startsWith("[")) {
return levelColors.getOrDefault(level, "") + message + reset;
}
int startTag = newMessage.indexOf('[') + 1;
int endTag = newMessage.indexOf(']', startTag);
String pluginName = colorizePluginName(newMessage.substring(startTag, endTag));
return '[' + pluginName + ']' + startingColorCode
+ levelColors.getOrDefault(level, "") + newMessage.substring(endTag + 1) + reset;
return '[' + pluginName + ']' + startingColorCode + newMessage.substring(endTag + 1) + reset;
}
public String colorizePluginName(String pluginName) {
if (!colorizeTag) {
return pluginName;
}
String pluginColor = pluginColors.getOrDefault(pluginName, "");
return pluginColor + pluginName + reset;
}
public String format(String keyCode) {
private String format(String keyCode) {
String[] formatParts = keyCode.split(" ");
Ansi ansi = Ansi.ansi();
for (String format : formatParts) {
@ -157,14 +131,6 @@ public class CommonFormatter {
if ("reverse".equalsIgnoreCase(format)) {
ansi.a(Attribute.NEGATIVE_ON);
continue;
}
for (Color color : Color.values()) {
if (format.equalsIgnoreCase(color.name())) {
ansi.fg(color);
break;
}
}
}

View File

@ -1,60 +0,0 @@
package com.github.games647.colorconsole.common;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
public class CommonLogInstaller {
public static PatternLayout createLayout(String logFormat) throws ReflectiveOperationException {
try {
Method builder = PatternLayout.class
.getDeclaredMethod("createLayout", String.class, Configuration.class, RegexReplacement.class
, String.class, String.class);
return (PatternLayout) builder.invoke(null, logFormat, new DefaultConfiguration(), null
, Charset.defaultCharset().name(), "true");
} catch (NoSuchMethodException methodEx) {
return PatternLayout.newBuilder()
.withCharset(Charset.defaultCharset())
.withPattern(logFormat)
.withConfiguration(new DefaultConfiguration())
.withAlwaysWriteExceptions(true)
.build();
}
}
public static void installAppender(Appender colorAppender, String terminalName) {
Logger rootLogger = (Logger) LogManager.getRootLogger();
colorAppender.start();
rootLogger.removeAppender(getTerminalAppender(terminalName));
rootLogger.addAppender(colorAppender);
}
public static void setLayout(Layout<? extends Serializable> layout, Appender terminalAppender)
throws ReflectiveOperationException {
Field field = terminalAppender.getClass().getSuperclass().getDeclaredField("layout");
field.setAccessible(true);
field.set(terminalAppender, layout);
}
public static Appender getTerminalAppender(String terminalName) {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration conf = ctx.getConfiguration();
return conf.getAppenders().get(terminalName);
}
}

View File

@ -0,0 +1,68 @@
package com.github.games647.colorconsole.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConsoleConfig {
public static String DEFAULT_PLUGIN_KEY = "Default";
private String logFormat;
private String dateStyle;
private final EnumMap<LoggingLevel, String> levelColors = new EnumMap<>(LoggingLevel.class);
private String defaultPluginColor;
private final Map<String, String> pluginColors = new HashMap<>();
private final List<String> hideMessages = new ArrayList<>();
private boolean truncateColor;
public String getLogFormat() {
return logFormat;
}
public EnumMap<LoggingLevel, String> getLevelColors() {
return levelColors;
}
public String getDefaultPluginColor() {
return defaultPluginColor;
}
public Map<String, String> getPluginColors() {
return pluginColors;
}
public Collection<String> getHideMessages() {
return hideMessages;
}
public String getDateStyle() {
return dateStyle;
}
public boolean isTruncateColor() {
return truncateColor;
}
public void setLogFormat(String logFormat) {
this.logFormat = logFormat;
}
public void setDateStyle(String dateStyle) {
this.dateStyle = dateStyle;
}
public void setDefaultPluginColor(String defaultPluginColor) {
this.defaultPluginColor = defaultPluginColor;
}
public void setTruncateColor(boolean truncateColor) {
this.truncateColor = truncateColor;
}
}

View File

@ -0,0 +1,132 @@
package com.github.games647.colorconsole.common;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
public class Log4JInstaller {
public PatternLayout createLayout(String logFormat) throws ReflectiveOperationException {
try {
Method builder = PatternLayout.class
.getDeclaredMethod("createLayout", String.class, Configuration.class, RegexReplacement.class
, String.class, String.class);
return (PatternLayout) builder.invoke(null, logFormat, new DefaultConfiguration(), null
, Charset.defaultCharset().name(), "true");
} catch (NoSuchMethodException methodEx) {
return PatternLayout.newBuilder()
.withCharset(Charset.defaultCharset())
.withPattern(logFormat)
.withConfiguration(new DefaultConfiguration())
.withAlwaysWriteExceptions(true)
.build();
}
}
public void installAppender(Appender colorAppender, String terminalName) {
Logger rootLogger = (Logger) LogManager.getRootLogger();
colorAppender.start();
rootLogger.removeAppender(getTerminalAppender(terminalName));
rootLogger.addAppender(colorAppender);
}
public void setLayout(Layout<? extends Serializable> layout, Appender terminalAppender)
throws ReflectiveOperationException {
Field field = terminalAppender.getClass().getSuperclass().getDeclaredField("layout");
field.setAccessible(true);
field.set(terminalAppender, layout);
}
public Layout<? extends Serializable> installLog4JFormat(PlatformPlugin pl,
String terminalName, ConsoleConfig config)
throws ReflectiveOperationException {
Appender terminalAppender = getTerminalAppender(terminalName);
Layout<? extends Serializable> oldLayout = terminalAppender.getLayout();
String logFormat = config.getLogFormat();
String appenderClass = terminalAppender.getClass().getName();
if (isMinecrellFormatted(oldLayout, appenderClass)) {
logFormat = logFormat.replace("%msg", "%minecraftFormatting{%msg}");
}
logFormat = mapLoggingLevels(logFormat, config.getLevelColors());
logFormat = formatDate(logFormat, config.getDateStyle());
PatternLayout layout = createLayout(logFormat);
setLayout(layout, terminalAppender);
Collection<String> hideMessages = config.getHideMessages();
boolean truncateColor = config.isTruncateColor();
ColorAppender appender = pl.createAppender(terminalAppender, hideMessages, truncateColor);
appender.initPluginColors(config.getPluginColors(), config.getDefaultPluginColor());
installAppender(appender, terminalName);
return oldLayout;
}
public void revertLog4JFormat(String terminalName, Layout<? extends Serializable> oldLayout)
throws ReflectiveOperationException {
Appender terminalAppender = getTerminalAppender(terminalName);
Logger rootLogger = (Logger) LogManager.getRootLogger();
ColorAppender colorPluginAppender = null;
for (Appender value : rootLogger.getAppenders().values()) {
if (value instanceof ColorAppender) {
colorPluginAppender = (ColorAppender) value;
break;
}
}
if (colorPluginAppender != null) {
rootLogger.removeAppender(terminalAppender);
rootLogger.addAppender(colorPluginAppender.getOldAppender());
}
setLayout(oldLayout, terminalAppender);
}
public Appender getTerminalAppender(String terminalName) {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration conf = ctx.getConfiguration();
return conf.getAppender(terminalName);
}
@VisibleForTesting
protected boolean isMinecrellFormatted(Layout<? extends Serializable> oldLayout, String appenderClass) {
return oldLayout.toString().contains("minecraftFormatting") || appenderClass.contains("minecrell");
}
@VisibleForTesting
protected String formatDate(String logFormat, String dateStyle) {
return logFormat.replaceFirst("(%d)\\{.*?}", "%style{$0}{" + dateStyle + '}');
}
@VisibleForTesting
protected String mapLoggingLevels(String logFormat, Map<LoggingLevel, String> levelColors) {
Map<LoggingLevel, String> sortedColors = new EnumMap<>(LoggingLevel.class);
sortedColors.putAll(levelColors);
String levelFormat = Joiner.on(", ").withKeyValueSeparator('=').join(sortedColors);
return logFormat.replace("%level", "%highlight{%level}{" + levelFormat + '}');
}
}

View File

@ -0,0 +1,16 @@
package com.github.games647.colorconsole.common;
public enum LoggingLevel {
FATAL,
ERROR,
WARN,
INFO,
DEBUG,
TRACE
}

View File

@ -0,0 +1,43 @@
package com.github.games647.colorconsole.common;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import org.apache.logging.log4j.core.Appender;
public interface PlatformPlugin {
String CONFIG_NAME = "config.yml";
void installLogFormat(ConsoleConfig configuration);
ColorAppender createAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol);
//restore the old format
void revertLogFormat();
Path getPluginFolder();
ConsoleConfig loadConfiguration() throws IOException;
default void saveDefaultConfig() throws IOException {
Path dataFolder = getPluginFolder();
if (Files.notExists(dataFolder)) {
Files.createDirectories(dataFolder);
}
Path configFile = dataFolder.resolve(CONFIG_NAME);
if (Files.notExists(configFile)) {
try (InputStream defaultStream = getClass().getClassLoader().getResourceAsStream(CONFIG_NAME)) {
if (defaultStream == null) {
return;
}
Files.copy(defaultStream, configFile);
}
}
}
}

View File

@ -1,118 +0,0 @@
package com.github.games647.colorconsole.sponge;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ninja.leaping.configurate.objectmapping.Setting;
public class ColorConsoleConfig {
public ColorConsoleConfig() {
this.pluginColors = Maps.newHashMap();
this.pluginColors.put("ColorConsole", "yellow");
this.levelColors = Maps.newHashMap();
this.levelColors.put("FATAL", "red blink");
this.levelColors.put("ERROR", "red");
this.levelColors.put("WARN", "yellow bold");
this.levelColors.put("INFO", "green");
this.levelColors.put("DEBUG", "green bold");
this.levelColors.put("TRACE", "blue");
}
@Setting(comment = "Should the plugin tag [PLUGIN_NAME] be highlighted")
private boolean colorPluginTag = true;
@Setting(comment = "Should the log message be highlighted depending on the logging level")
private boolean colorLoggingLevel = true;
@Setting(comment = "How the messages should be displayed\n"
+ "\n"
+ "Variables:\n"
+ "%thread - Thread name\n"
+ "%d{HH:mm:ss} - Timestamp\n"
+ "%msg - log message\n"
+ "%logger - logger name\n"
+ "%n - new line\n"
+ "\n"
+ "These variables try to get the orgin. This is an expensive operation and may impact performance. "
+ "Use with caution.\n"
+ "\n"
+ "%class{precision} - Class name\n"
+ "%method - Method name\n"
+ "%line - Line number\n"
+ "\n"
+ "For more details vist: https://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns")
private String logFormat = "[%d{HH:mm:ss} %level] [%logger{1}]: %msg%n";
@Setting(comment = "Log Level Colors")
private Map<String, String> levelColors;
@Setting(comment = "Plugin Colors or random")
private String defaultPluginColor = "blue";
@Setting(comment = "Custom plugin colors")
private Map<String, String> pluginColors;
@Setting(comment = "How should the time be highlighted\n" +
"Like below it could also be default which means it's the default font color depending on " +
"your terminal settings.")
private String dateStyle = "cyan";
@Setting(comment = "Hides the log message if it contains one or more of the following texts\n"
+ "The texts are case-sensitive")
private List<String> hideMessages = Lists.newArrayList();
@Setting(comment = "Removes color formatting if the complete message has color formatting")
private boolean truncateColor;
@Setting(comment = "Should the complete logging message be colored in the same style as the logging level " +
"(like ColorConsole v1).\n" +
"If not it's using the default color (like ColorConsole v2+)")
private boolean colorMessage;
public boolean isColorPluginTag() {
return colorPluginTag;
}
public boolean isColorLoggingLevel() {
return colorLoggingLevel;
}
public String getLogFormat() {
return logFormat;
}
public Map<String, String> getLevelColors() {
return levelColors;
}
public String getDefaultPluginColor() {
return defaultPluginColor;
}
public Map<String, String> getPluginColors() {
return pluginColors;
}
public Set<String> getHideMessages() {
return ImmutableSet.copyOf(hideMessages);
}
public String getDateStyle() {
return dateStyle;
}
public boolean isTruncateColor() {
return truncateColor;
}
public boolean isColorMessage() {
return colorMessage;
}
}

View File

@ -1,115 +1,129 @@
package com.github.games647.colorconsole.sponge;
import com.github.games647.colorconsole.common.CommonLogInstaller;
import com.github.games647.colorconsole.common.ColorAppender;
import com.github.games647.colorconsole.common.ConsoleConfig;
import com.github.games647.colorconsole.common.Log4JInstaller;
import com.github.games647.colorconsole.common.LoggingLevel;
import com.github.games647.colorconsole.common.PlatformPlugin;
import com.google.common.reflect.TypeToken;
import com.google.inject.Inject;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.objectmapping.ObjectMapper;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.slf4j.Logger;
import org.spongepowered.api.config.DefaultConfig;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.plugin.Plugin;
@Plugin(id = PomData.ARTIFACT_ID, name = PomData.NAME, version = PomData.VERSION
, url = PomData.URL, description = PomData.DESCRIPTION)
public class ColorConsoleSponge {
@Plugin(id = PomData.ARTIFACT_ID, name = PomData.NAME, version = PomData.VERSION,
url = PomData.URL, description = PomData.DESCRIPTION)
public class ColorConsoleSponge implements PlatformPlugin {
// private static String TERMINAL_NAME = "FmlConsole";
// private static String TERMINAL_NAME = "Console";
private static String TERMINAL_NAME = "MinecraftConsole";
//Console is maybe required too?
private static final String TERMINAL_NAME = "MinecraftConsole";
private final Path pluginFolder;
private final Logger logger;
@Inject
@DefaultConfig(sharedRoot = true)
private Path configFile;
private final Log4JInstaller installer = new Log4JInstaller();
private Layout<? extends Serializable> oldLayout;
@Inject
@DefaultConfig(sharedRoot = true)
private ConfigurationLoader<CommentedConfigurationNode> configManager;
private ObjectMapper<ColorConsoleConfig>.BoundInstance configMapper;
private CommentedConfigurationNode rootNode;
@Inject
public ColorConsoleSponge(Logger logger) {
public ColorConsoleSponge(Logger logger, @ConfigDir(sharedRoot = false) Path dataFolder) {
this.pluginFolder = dataFolder;
this.logger = logger;
}
public ColorConsoleConfig getConfig() {
return configMapper.getInstance();
}
@Listener //During this state, the plugin gets ready for initialization. Logger and config
@Listener
public void onPreInit(GamePreInitializationEvent preInitEvent) {
logger.info("Setting up config");
rootNode = configManager.createEmptyNode();
ConfigurationLoader<CommentedConfigurationNode> configLoader = HoconConfigurationLoader.builder()
.setPath(configFile).build();
ConsoleConfig configuration;
try {
configMapper = ObjectMapper
.forClass(ColorConsoleConfig.class).bindToNew();
rootNode = configManager.load();
configMapper.populate(rootNode);
//add and save missing values
configMapper.serialize(rootNode);
configLoader.save(rootNode);
} catch (IOException | ObjectMappingException ioEx) {
logger.error("Cannot save default config", ioEx);
saveDefaultConfig();
configuration = loadConfiguration();
} catch (IOException ioEx) {
logger.warn("Failed to load configuration file. Canceling plugin setup", ioEx);
return;
}
installLogFormat();
installLogFormat(configuration);
}
private void installLogFormat() {
Appender terminalAppender = CommonLogInstaller.getTerminalAppender(TERMINAL_NAME);
Layout<? extends Serializable> oldLayout = terminalAppender.getLayout();
String logFormat = configMapper.getInstance().getLogFormat();
if (oldLayout.toString().contains("%minecraftFormatting")) {
logFormat = logFormat.replace("%msg", "%minecraftFormatting{%msg}");
}
if (configMapper.getInstance().isColorLoggingLevel()) {
logFormat = logFormat.replace("%level", "%highlight{%level}{"
+ "FATAL=" + configMapper.getInstance().getLevelColors().get("FATAL") + ", "
+ "ERROR=" + configMapper.getInstance().getLevelColors().get("ERROR") + ", "
+ "WARN=" + configMapper.getInstance().getLevelColors().get("WARN") + ", "
+ "INFO=" + configMapper.getInstance().getLevelColors().get("INFO") + ", "
+ "DEBUG=" + configMapper.getInstance().getLevelColors().get("DEBUG") + ", "
+ "TRACE=" + configMapper.getInstance().getLevelColors().get("TRACE") + "}");
}
String dateStyle = configMapper.getInstance().getDateStyle();
logFormat = logFormat.replace("%d{HH:mm:ss}", "%style{" + "%d{HH:mm:ss}" + "}{" + dateStyle + "}");
@Override
public void installLogFormat(ConsoleConfig configuration) {
try {
PatternLayout layout = CommonLogInstaller.createLayout(logFormat);
CommonLogInstaller.setLayout(layout, terminalAppender);
} catch (ReflectiveOperationException ex) {
logger.warn("Cannot install log format", ex);
oldLayout = installer.installLog4JFormat(this, TERMINAL_NAME, configuration);
} catch (ReflectiveOperationException reflectiveEx) {
logger.error("Failed to install log format", reflectiveEx);
}
}
@Override
public void revertLogFormat() {
try {
installer.revertLog4JFormat(TERMINAL_NAME, oldLayout);
} catch (ReflectiveOperationException reflectiveEx) {
logger.warn("Cannot revert log format", reflectiveEx);
}
}
@Override
public ColorAppender createAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol) {
return new SpongeAppender(oldAppender, hideMessages, truncateCol);
}
@Override
public Path getPluginFolder() {
return pluginFolder;
}
@Override
public ConsoleConfig loadConfiguration() throws IOException {
Path configPath = pluginFolder.resolve(CONFIG_NAME);
YAMLConfigurationLoader configLoader = YAMLConfigurationLoader.builder().setPath(configPath).build();
ConsoleConfig consoleConfig = new ConsoleConfig();
ConfigurationNode rootNode = configLoader.load();
consoleConfig.setLogFormat(rootNode.getNode("logFormat").getString());
consoleConfig.setDateStyle(rootNode.getNode("dateStyle").getString());
consoleConfig.getLevelColors().clear();
if (rootNode.getNode("colorLoggingLevel").getBoolean()) {
ConfigurationNode levelSection = rootNode.getNode("Level");
for (LoggingLevel level : LoggingLevel.values()) {
consoleConfig.getLevelColors().put(level, levelSection.getNode(level.name()).getString(""));
}
}
ColorPluginAppender pluginAppender = new ColorPluginAppender(terminalAppender, getConfig());
pluginAppender.initPluginColors(getConfig().getPluginColors(), getConfig().getDefaultPluginColor());
consoleConfig.getPluginColors().clear();
if (rootNode.getNode("colorPluginTag").getBoolean()) {
ConfigurationNode pluginSection = rootNode.getNode("Plugin");
consoleConfig.setDefaultPluginColor(pluginSection.getNode(ConsoleConfig.DEFAULT_PLUGIN_KEY).getString(""));
for (Entry<Object, ? extends ConfigurationNode> pluginEntry : pluginSection.getChildrenMap().entrySet()) {
consoleConfig.getPluginColors().put((String) pluginEntry.getKey(), pluginEntry.getValue().getString());
}
}
CommonLogInstaller.installAppender(pluginAppender, TERMINAL_NAME);
CommonLogInstaller.installAppender(pluginAppender, "Console");
consoleConfig.getHideMessages().clear();
try {
List<String> list = rootNode.getNode("hide-messages").getList(TypeToken.of(String.class));
consoleConfig.getHideMessages().addAll(list);
} catch (ObjectMappingException mappingException) {
throw new IOException(mappingException);
}
consoleConfig.setTruncateColor(rootNode.getNode("truncateColor").getBoolean());
return consoleConfig;
}
}

View File

@ -1,32 +0,0 @@
package com.github.games647.colorconsole.sponge;
import com.github.games647.colorconsole.common.ColorAppender;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.spongepowered.api.Sponge;
public class ColorPluginAppender extends ColorAppender {
public ColorPluginAppender(Appender oldAppender, ColorConsoleConfig config) {
super(oldAppender, config.getHideMessages(), config.isColorPluginTag(), config.isTruncateColor()
, config.isColorMessage() ? config.getLevelColors() : Collections.emptyMap());
}
@Override
public LogEvent onAppend(LogEvent logEvent) {
String newLoggerName = formatter.colorizePluginName(logEvent.getLoggerName());
return clone(logEvent, newLoggerName, logEvent.getMessage());
}
@Override
protected Collection<String> loadPluginNames() {
return Sponge.getPluginManager().getPlugins().stream()
.map(pluginContainer -> pluginContainer.getId())
.collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,25 @@
package com.github.games647.colorconsole.sponge;
import com.github.games647.colorconsole.common.ColorAppender;
import java.util.Collection;
import org.apache.logging.log4j.core.Appender;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.plugin.PluginContainer;
import static java.util.stream.Collectors.toSet;
public class SpongeAppender extends ColorAppender {
public SpongeAppender(Appender oldAppender, Collection<String> hideMessages, boolean truncateCol) {
super(oldAppender, hideMessages, truncateCol);
}
@Override
protected Collection<String> loadPluginNames() {
return Sponge.getPluginManager().getPlugins().stream()
.map(PluginContainer::getId)
.collect(toSet());
}
}

View File

@ -6,7 +6,7 @@ name: ${project.name}
main: ${project.groupId}.${project.artifactId}.bungee.${project.name}Bungee
version: ${project.version}
author: games647, http://github.com/games647/ColorConsole/graphs/contributors
author: games647, https://github.com/games647/ColorConsole/graphs/contributors
description: |
${project.description}
${project.description}

View File

@ -1,15 +1,5 @@
# ConsoleColor config
# Should the plugin tag [PLUGIN_NAME] be highlighted
colorPluginTag: true
# Should the log message be highlighted depending on the logging level
colorLoggingLevel: true
# Should the complete logging message be colored in the same style as the logging level (like ColorConsole v1).
# If not it's using the default color (like ColorConsole v2+)
colorMessage: false
# How the messages should be displayed
#
# Variables:
@ -17,43 +7,52 @@ colorMessage: false
# %d{HH:mm:ss} - Timestamp
# %msg - log message
# %n - new line
# These variables try to get the orgin. This is an expensive operation and may impact performance. Use with caution.
# These variables try to get the origin. This is an expensive operation and may impact performance. Use with caution.
# %class{precision} - Class name
# %method - Method name
# %line - Line number
#
# For more details vist: https://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns
# For more details visit: https://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns
logFormat: '[%d{HH:mm:ss} %level]: %msg%n'
# How should the time be highlighted
# Like below it could also be default which means it's the default font color depending on your terminal settings.
dateStyle: cyan
# Should the log message be highlighted depending on the logging level
colorLoggingLevel: true
# Log Level Colors
FATAL: red
ERROR: red
WARN: yellow
INFO: green
DEBUG: green
TRACE: blue
Level:
FATAL: red
ERROR: red
WARN: yellow
INFO: green
DEBUG: green
TRACE: blue
# Should the plugin tag [PLUGIN_NAME] be highlighted
colorPluginTag: true
# Plugin Colors
# This can be the default color or "random" it gives each plugin (besides the ones specified below) a different color
# which keeps the same until the server shuts down.
# Black is ignored by default, because it's often hard to read on the console
PLUGIN: blue
# Plugin: random
P-Essentials: green
P-LagMonitor: red
P-WorldEdit: red
P-FastLogin: cyan
P-WorldGuard: cyan
P-Vault: magenta
P-ChangeSkin: yellow
P-ScoreboardStats: white
P-mcMMOAction: blue
# How should the time be highlighted
# Like below it could also be default which means it's the default font color depending on your terminal settings.
dateStyle: cyan
Plugin:
Default: random
Essentials: green
LagMonitor: red
WorldEdit: red
FastLogin: cyan
WorldGuard: cyan
Vault: magenta
ChangeSkin: yellow
ScoreboardStats: white
mcMMOAction: blue
mcMMOExtras: yellow
ColorConsole: orange
# Available foreground colors | Available background colors
# Black | BG_Black

View File

@ -1,12 +1,15 @@
# project informations for Bukkit in order to register our plugin with all it components
# project data for Bukkit in order to register our plugin with all it components
# ${-} are variables from Maven (pom.xml) which will be replaced after the build
name: ${project.name}
version: ${project.version}
main: ${project.groupId}.${project.artifactId}.bukkit.${project.name}Bukkit
# meta informations for plugin managers
# meta data for plugin managers
authors: [games647, 'https://github.com/games647/ColorConsole/graphs/contributors']
description: |
${project.description}
website: ${project.url}
dev-url: ${project.url}
# This plugin don't have to be transformed for compatibility with Minecraft >= 1.13
api-version: 1.13

View File

@ -0,0 +1,90 @@
package com.github.games647.colorconsole.common;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.fusesource.jansi.Ansi;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class CommonFormatterTest {
private CommonFormatter formatter;
@Before
public void setUp() throws Exception {
formatter = new CommonFormatter(Collections.singleton("ignore"), false);
}
@Test
public void testShouldIgnore() {
assertThat(formatter.shouldIgnore("123"), is(false));
assertThat(formatter.shouldIgnore("ignore"), is(true));
assertThat(formatter.shouldIgnore("start ignore end"), is(true));
}
@Test
public void testColorizePluginTagPresent() {
loadPluginColors();
Ansi reset = Ansi.ansi().reset();
String expected = "[" + Ansi.ansi().fgBlue() + "TestPlugin" + reset + "] msg" + reset;
assertThat(formatter.colorizePluginTag("[TestPlugin] msg"), is(expected));
}
@Test
public void testColorizePluginTagNotPresentRight() {
loadPluginColors();
// unmodified
String msg = "[TestPlugin msg";
assertThat(formatter.colorizePluginTag(msg), is(msg));
}
@Test
public void testColorizePluginTagNotPresentLeft() {
loadPluginColors();
// unmodified
String msg = "TestPlugin] msg";
assertThat(formatter.colorizePluginTag(msg), is(msg));
}
@Test
public void testColorizePluginTagWrongOrder() {
loadPluginColors();
// unmodified
String msg = "]TestPlugin[ msg";
assertThat(formatter.colorizePluginTag(msg), is(msg));
}
@Test
public void testColorizeNameDefault() {
loadPluginColors();
Ansi reset = Ansi.ansi().reset();
assertThat(formatter.colorizePluginName("None"), is(Ansi.ansi().fgRed() + "None" + reset));
}
@Test
public void testColorizePluginName() {
loadPluginColors();
Ansi reset = Ansi.ansi().reset();
assertThat(formatter.colorizePluginName("TestPlugin"), is(Ansi.ansi().fgBlue() + "TestPlugin" + reset));
}
private void loadPluginColors() {
List<String> plugins = Arrays.asList("TestPlugin", "None");
Map<String, String> map = Collections.singletonMap("TestPlugin", "blue");
formatter.initPluginColors(plugins, map, "red");
}
}

View File

@ -0,0 +1,65 @@
package com.github.games647.colorconsole.common;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class Log4JInstallerTest {
private Log4JInstaller installer;
@Before
public void setUp() throws Exception {
this.installer = new Log4JInstaller();
}
@Test
public void testFormatDateVanilla() {
String expected = "[%style{%d{HH:mm:ss}}{cyan} %level]: %msg%n";
String configFormat = "[%d{HH:mm:ss} %level]: %msg%n";
assertThat(installer.formatDate(configFormat, "cyan"), is(expected));
}
@Test
public void testMappingLevels() {
Map<LoggingLevel, String> levelColors = new HashMap<>();
levelColors.put(LoggingLevel.FATAL, "red");
levelColors.put(LoggingLevel.ERROR, "red");
levelColors.put(LoggingLevel.WARN, "yellow");
levelColors.put(LoggingLevel.INFO, "green");
levelColors.put(LoggingLevel.DEBUG, "green");
levelColors.put(LoggingLevel.TRACE, "blue");
String configFormat = "[%d{HH:mm:ss} %level]: %msg%n";
String expected = "[%d{HH:mm:ss} %highlight{%level}{FATAL=red, ERROR=red, WARN=yellow, " +
"INFO=green, DEBUG=green, TRACE=blue}]: %msg%n";
assertThat(installer.mapLoggingLevels(configFormat, levelColors), is(expected));
}
@Test
public void testMinecrellDetection() {
PatternLayout crellPattern = PatternLayout.newBuilder()
.withPattern("%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx}")
.build();
String crellAppender = "net.minecrell.terminalconsole.TerminalConsoleAppender";
assertThat(installer.isMinecrellFormatted(crellPattern, ""), is(true));
assertThat(installer.isMinecrellFormatted(PatternLayout.createDefaultLayout(), crellAppender), is(true));
}
@Test
public void testVanillaDetection() {
PatternLayout vanillaPattern = PatternLayout.newBuilder()
.withPattern("[%d{HH:mm:ss}] [%t/%level]: %msg%n")
.build();
String vanillaAppender = "org.apache.logging.log4j.core.appender.ConsoleAppender";
assertThat(installer.isMinecrellFormatted(vanillaPattern, "vanillaAppender"), is(false));
}
}