diff --git a/paper-server/pom.xml b/paper-server/pom.xml
index 9628e8bc23..c067169138 100644
--- a/paper-server/pom.xml
+++ b/paper-server/pom.xml
@@ -47,6 +47,11 @@
jopt-simple
3.2
+
+ jline
+ jline
+ 0.9.94
+
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 282642578e..93b9a7d7ce 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+import jline.ConsoleReader;
import net.minecraft.server.ChunkCoordinates;
import net.minecraft.server.ConvertProgressUpdater;
import net.minecraft.server.Convertable;
@@ -276,4 +277,8 @@ public final class CraftServer implements Server {
public Logger getLogger() {
return MinecraftServer.a;
}
+
+ public ConsoleReader getReader() {
+ return console.reader;
+ }
}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/paper-server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
new file mode 100644
index 0000000000..8bf86e0a11
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
@@ -0,0 +1,54 @@
+package org.bukkit.craftbukkit.command;
+
+import java.util.EnumMap;
+import java.util.Map;
+import jline.ANSIBuffer.ANSICodes;
+import jline.ConsoleReader;
+import jline.Terminal;
+import org.bukkit.ChatColor;
+import org.bukkit.command.ConsoleCommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+
+public class ColouredConsoleSender extends ConsoleCommandSender {
+ private final ConsoleReader reader;
+ private final Terminal terminal;
+ private final Map replacements = new EnumMap(ChatColor.class);
+ private final ChatColor[] colors = ChatColor.values();
+
+ public ColouredConsoleSender(CraftServer server) {
+ super(server);
+ this.reader = server.getReader();
+ this.terminal = reader.getTerminal();
+
+ replacements.put(ChatColor.BLACK, ANSICodes.attrib(0));
+ replacements.put(ChatColor.RED, ANSICodes.attrib(31));
+ replacements.put(ChatColor.DARK_RED, ANSICodes.attrib(31));
+ replacements.put(ChatColor.GREEN, ANSICodes.attrib(32));
+ replacements.put(ChatColor.DARK_GREEN, ANSICodes.attrib(32));
+ replacements.put(ChatColor.YELLOW, ANSICodes.attrib(33));
+ replacements.put(ChatColor.BLUE, ANSICodes.attrib(34));
+ replacements.put(ChatColor.DARK_BLUE, ANSICodes.attrib(34));
+ replacements.put(ChatColor.LIGHT_PURPLE, ANSICodes.attrib(35));
+ replacements.put(ChatColor.DARK_PURPLE, ANSICodes.attrib(35));
+ replacements.put(ChatColor.AQUA, ANSICodes.attrib(36));
+ replacements.put(ChatColor.WHITE, ANSICodes.attrib(37));
+ }
+
+ @Override
+ public void sendMessage(String message) {
+ if (terminal.isANSISupported()) {
+ String result = message;
+
+ for (ChatColor color : colors) {
+ if (replacements.containsKey(color)) {
+ result = result.replaceAll(color.toString(), replacements.get(color));
+ } else {
+ result = result.replaceAll(color.toString(), "");
+ }
+ }
+ System.out.println(result + ANSICodes.attrib(0));
+ } else {
+ super.sendMessage(message);
+ }
+ }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java
new file mode 100644
index 0000000000..ad4419f9aa
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java
@@ -0,0 +1,33 @@
+package org.bukkit.craftbukkit.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+public class ShortConsoleLogFormatter extends Formatter {
+ private final SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
+
+ @Override
+ public String format(LogRecord record) {
+ StringBuilder builder = new StringBuilder();
+ Throwable ex = record.getThrown();
+
+ builder.append(date.format(record.getMillis()));
+ builder.append(" [");
+ builder.append(record.getLevel().getLocalizedName().toUpperCase());
+ builder.append("] ");
+ builder.append(record.getMessage());
+ builder.append('\n');
+
+ if (ex != null) {
+ StringWriter writer = new StringWriter();
+ ex.printStackTrace(new PrintWriter(writer));
+ builder.append(writer);
+ }
+
+ return builder.toString();
+ }
+
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java
new file mode 100644
index 0000000000..a7beb5587d
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java
@@ -0,0 +1,27 @@
+package org.bukkit.craftbukkit.util;
+
+import java.io.IOException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jline.ConsoleReader;
+
+public class TerminalConsoleHandler extends ConsoleHandler {
+ private final ConsoleReader reader;
+
+ public TerminalConsoleHandler(ConsoleReader reader) {
+ super();
+ this.reader = reader;
+ }
+
+ @Override
+ public synchronized void flush() {
+ super.flush();
+ try {
+ reader.redrawLine();
+ } catch (IOException ex) {
+ Logger.getLogger(TerminalConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+}