mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-26 22:40:21 +01:00
Improve console implementation
Rewrite console improvements (console colors, tab completion, persistent input line, ...) using JLine 3.x and TerminalConsoleAppender. New features: - Support console colors for Vanilla commands - Add console colors for warnings and errors - Server can now be turned off safely using CTRL + C. JLine catches the signal and the implementation shuts down the server cleanly. - Support console colors and persistent input line when running in IntelliJ IDEA Other changes: - Update JLine to 3.3.1 (from 2.12.1) - Server starts 1-2 seconds faster thanks to optimizations in Log4j configuration
This commit is contained in:
parent
3b5e6cd48f
commit
e0aa38d35e
4 changed files with 620 additions and 28 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -42,11 +42,13 @@ work/test-server
|
|||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
out/
|
||||
|
||||
# Linux temp files
|
||||
*~
|
||||
|
||||
# other stuff
|
||||
run/
|
||||
|
||||
Paper-Server
|
||||
Paper-API
|
||||
|
@ -55,4 +57,4 @@ PaperSpigot-API
|
|||
Paperclip.jar
|
||||
paperclip.jar
|
||||
paperclip-*.jar
|
||||
paperclip.properties
|
||||
paperclip.properties
|
||||
|
|
|
@ -0,0 +1,612 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <dev@minecrell.net>
|
||||
Date: Fri, 9 Jun 2017 19:03:43 +0200
|
||||
Subject: [PATCH] Use TerminalConsoleAppender for console improvements
|
||||
|
||||
Rewrite console improvements (console colors, tab completion,
|
||||
persistent input line, ...) using JLine 3.x and TerminalConsoleAppender.
|
||||
|
||||
New features:
|
||||
- Support console colors for Vanilla commands
|
||||
- Add console colors for warnings and errors
|
||||
- Server can now be turned off safely using CTRL + C. JLine catches
|
||||
the signal and the implementation shuts down the server cleanly.
|
||||
- Support console colors and persistent input line when running in
|
||||
IntelliJ IDEA
|
||||
|
||||
Other changes:
|
||||
- Update JLine to 3.3.1 (from 2.12.1)
|
||||
- Server starts 1-2 seconds faster thanks to optimizations in Log4j
|
||||
configuration
|
||||
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
index b2aa10ff..0ae2c9c6 100644
|
||||
--- a/pom.xml
|
||||
+++ b/pom.xml
|
||||
@@ -0,0 +0,0 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
- <groupId>jline</groupId>
|
||||
- <artifactId>jline</artifactId>
|
||||
- <version>2.12.1</version>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.18.0</version>
|
||||
@@ -0,0 +0,0 @@
|
||||
<artifactId>trove4j</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
+
|
||||
+ <dependency>
|
||||
+ <groupId>net.minecrell</groupId>
|
||||
+ <artifactId>terminalconsoleappender</artifactId>
|
||||
+ <version>1.0.0-SNAPSHOT</version>
|
||||
+ </dependency>
|
||||
+ <dependency>
|
||||
+ <groupId>org.jline</groupId>
|
||||
+ <artifactId>jline-terminal-jna</artifactId>
|
||||
+ <version>3.3.1</version>
|
||||
+ <scope>runtime</scope>
|
||||
+ </dependency>
|
||||
+ <dependency>
|
||||
+ <groupId>net.java.dev.jna</groupId>
|
||||
+ <artifactId>jna</artifactId>
|
||||
+ <version>4.4.0</version>
|
||||
+ <scope>runtime</scope>
|
||||
+ </dependency>
|
||||
+
|
||||
+ <!--
|
||||
+ Required to add the missing Log4j2Plugins.dat file from log4j-core
|
||||
+ which has been removed by Mojang. Without it, log4j has to classload
|
||||
+ all its classes to check if they are plugins.
|
||||
+ Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
||||
+ -->
|
||||
+ <dependency>
|
||||
+ <groupId>org.apache.logging.log4j</groupId>
|
||||
+ <artifactId>log4j-core</artifactId>
|
||||
+ <version>2.8.1</version>
|
||||
+ <scope>runtime</scope>
|
||||
+ </dependency>
|
||||
+
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
@@ -0,0 +0,0 @@
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/services/java.sql.Driver</resource>
|
||||
</transformer>
|
||||
+ <transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" />
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
+ <dependencies>
|
||||
+ <dependency>
|
||||
+ <groupId>com.github.edwgiz</groupId>
|
||||
+ <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
|
||||
+ <version>2.8.1</version>
|
||||
+ </dependency>
|
||||
+ </dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
||||
new file mode 100644
|
||||
index 00000000..24f30efb
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.console;
|
||||
+
|
||||
+import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
|
||||
+
|
||||
+public class TerminalConsoleCommandSender extends CraftConsoleCommandSender {
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendRawMessage(String message) {
|
||||
+ // Print message with colors
|
||||
+ System.out.println(message);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalHandler.java b/src/main/java/com/destroystokyo/paper/console/TerminalHandler.java
|
||||
new file mode 100644
|
||||
index 00000000..dcd31fbc
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/console/TerminalHandler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.console;
|
||||
+
|
||||
+import net.minecraft.server.DedicatedServer;
|
||||
+import net.minecrell.terminalconsole.TerminalConsoleAppender;
|
||||
+import org.bukkit.craftbukkit.command.ConsoleCommandCompleter;
|
||||
+import org.jline.reader.LineReader;
|
||||
+import org.jline.reader.LineReaderBuilder;
|
||||
+import org.jline.reader.UserInterruptException;
|
||||
+import org.jline.terminal.Terminal;
|
||||
+
|
||||
+public class TerminalHandler {
|
||||
+
|
||||
+ private TerminalHandler() {
|
||||
+ }
|
||||
+
|
||||
+ public static boolean handleCommands(DedicatedServer server) {
|
||||
+ final Terminal terminal = TerminalConsoleAppender.getTerminal();
|
||||
+ if (terminal == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ LineReader reader = LineReaderBuilder.builder()
|
||||
+ .appName("Paper")
|
||||
+ .terminal(terminal)
|
||||
+ .completer(new ConsoleCommandCompleter(server))
|
||||
+ .build();
|
||||
+ reader.unsetOpt(LineReader.Option.INSERT_TAB);
|
||||
+
|
||||
+ TerminalConsoleAppender.setReader(reader);
|
||||
+
|
||||
+ try {
|
||||
+ String line;
|
||||
+ while (!server.isStopped() && server.isRunning()) {
|
||||
+ line = reader.readLine("> ");
|
||||
+ if (line == null) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ line = line.trim();
|
||||
+ if (!line.isEmpty()) {
|
||||
+ server.issueCommand(line, server);
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (UserInterruptException e) {
|
||||
+ server.safeShutdown();
|
||||
+ } finally {
|
||||
+ TerminalConsoleAppender.setReader(null);
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
index 2feeb855..db9ace0c 100644
|
||||
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
if (!org.bukkit.craftbukkit.Main.useConsole) {
|
||||
return;
|
||||
}
|
||||
- jline.console.ConsoleReader bufferedreader = reader;
|
||||
+ // Paper start - Use TerminalConsoleAppender implementation
|
||||
+ if (com.destroystokyo.paper.console.TerminalHandler.handleCommands(DedicatedServer.this)) return;
|
||||
+ BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
|
||||
String s;
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
try {
|
||||
// CraftBukkit start - JLine disabling compatibility
|
||||
while (!isStopped() && isRunning()) {
|
||||
+ // Paper start - code is not used for jline
|
||||
+ /*
|
||||
if (org.bukkit.craftbukkit.Main.useJline) {
|
||||
s = bufferedreader.readLine(">", null);
|
||||
} else {
|
||||
s = bufferedreader.readLine();
|
||||
}
|
||||
+ */
|
||||
+ s = bufferedreader.readLine();
|
||||
+ // Paper end
|
||||
+
|
||||
if (s != null && s.trim().length() > 0) { // Trim to filter lines which are just spaces
|
||||
issueCommand(s, DedicatedServer.this);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
}
|
||||
}
|
||||
|
||||
- new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start();
|
||||
-
|
||||
System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true));
|
||||
System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true));
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index d84f59da..8ca8fdce 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ import org.apache.commons.lang3.Validate;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
// CraftBukkit start
|
||||
-import jline.console.ConsoleReader;
|
||||
import joptsimple.OptionSet;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||||
public OptionSet options;
|
||||
public org.bukkit.command.ConsoleCommandSender console;
|
||||
public org.bukkit.command.RemoteConsoleCommandSender remoteConsole;
|
||||
- public ConsoleReader reader;
|
||||
+ //public ConsoleReader reader; // Paper
|
||||
public static int currentTick = 0; // Paper - Further improve tick loop
|
||||
public final Thread primaryThread;
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||||
this.dataConverterManager = dataconvertermanager;
|
||||
// CraftBukkit start
|
||||
this.options = options;
|
||||
+ // Paper start - Handled by TerminalConsoleAppender
|
||||
// Try to see if we're actually running in a terminal, disable jline if not
|
||||
+ /*
|
||||
if (System.console() == null && System.getProperty("jline.terminal") == null) {
|
||||
System.setProperty("jline.terminal", "jline.UnsupportedTerminal");
|
||||
Main.useJline = false;
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||||
LOGGER.warn((String) null, ex);
|
||||
}
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
|
||||
|
||||
this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||||
} finally {
|
||||
// CraftBukkit start - Restore terminal to original settings
|
||||
try {
|
||||
- reader.getTerminal().restore();
|
||||
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||||
}
|
||||
|
||||
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
|
||||
- MinecraftServer.LOGGER.info(ichatbasecomponent.toPlainText());
|
||||
+ // Paper - Log message with colors
|
||||
+ MinecraftServer.LOGGER.info(org.bukkit.craftbukkit.util.CraftChatMessage.fromComponent(ichatbasecomponent, net.minecraft.server.EnumChatFormat.WHITE));
|
||||
}
|
||||
|
||||
public boolean a(int i, String s) {
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
index 0c328782..ed0a749e 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
public PlayerList(MinecraftServer minecraftserver) {
|
||||
this.cserver = minecraftserver.server = new CraftServer(minecraftserver, this);
|
||||
- minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
|
||||
- minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server));
|
||||
+ minecraftserver.console = new com.destroystokyo.paper.console.TerminalConsoleCommandSender(); // Paper
|
||||
// CraftBukkit end
|
||||
|
||||
this.k = new GameProfileBanList(PlayerList.a);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 463f5890..df6a75b0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.base64.Base64;
|
||||
-import jline.console.ConsoleReader;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
return logger;
|
||||
}
|
||||
|
||||
+ // Paper start - JLine update
|
||||
+ /*
|
||||
public ConsoleReader getReader() {
|
||||
return console.reader;
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public PluginCommand getPluginCommand(String name) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 1cbcc3df..c3b2413a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ import java.util.logging.Logger;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
-import org.fusesource.jansi.AnsiConsole;
|
||||
+import net.minecrell.terminalconsole.TerminalConsoleAppender; // Paper
|
||||
|
||||
public class Main {
|
||||
public static boolean useJline = true;
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
}
|
||||
|
||||
try {
|
||||
+ // Paper start - Handled by TerminalConsoleAppender
|
||||
+ /*
|
||||
// This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals
|
||||
String jline_UnsupportedTerminal = new String(new char[] {'j','l','i','n','e','.','U','n','s','u','p','p','o','r','t','e','d','T','e','r','m','i','n','a','l'});
|
||||
String jline_terminal = new String(new char[] {'j','l','i','n','e','.','t','e','r','m','i','n','a','l'});
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
// This ensures the terminal literal will always match the jline implementation
|
||||
System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
|
||||
}
|
||||
+ */
|
||||
|
||||
+ if (options.has("nojline")) {
|
||||
+ System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false");
|
||||
+ useJline = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (options.has("noconsole")) {
|
||||
useConsole = false;
|
||||
+ useJline = false; // Paper
|
||||
+ System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
|
||||
}
|
||||
|
||||
if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
|
||||
deleted file mode 100644
|
||||
index 26a2fb89..00000000
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
|
||||
+++ /dev/null
|
||||
@@ -0,0 +0,0 @@
|
||||
-package org.bukkit.craftbukkit.command;
|
||||
-
|
||||
-import java.util.EnumMap;
|
||||
-import java.util.Map;
|
||||
-
|
||||
-import org.fusesource.jansi.Ansi;
|
||||
-import org.fusesource.jansi.Ansi.Attribute;
|
||||
-import jline.Terminal;
|
||||
-
|
||||
-import org.bukkit.Bukkit;
|
||||
-import org.bukkit.ChatColor;
|
||||
-import org.bukkit.command.ConsoleCommandSender;
|
||||
-import org.bukkit.craftbukkit.CraftServer;
|
||||
-
|
||||
-public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||
- private final Terminal terminal;
|
||||
- private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
|
||||
- private final ChatColor[] colors = ChatColor.values();
|
||||
-
|
||||
- protected ColouredConsoleSender() {
|
||||
- super();
|
||||
- this.terminal = ((CraftServer) getServer()).getReader().getTerminal();
|
||||
-
|
||||
- replacements.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).boldOff().toString());
|
||||
- replacements.put(ChatColor.GOLD, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).boldOff().toString());
|
||||
- replacements.put(ChatColor.GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).boldOff().toString());
|
||||
- replacements.put(ChatColor.DARK_GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).bold().toString());
|
||||
- replacements.put(ChatColor.BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).bold().toString());
|
||||
- replacements.put(ChatColor.GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).bold().toString());
|
||||
- replacements.put(ChatColor.AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).bold().toString());
|
||||
- replacements.put(ChatColor.RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).bold().toString());
|
||||
- replacements.put(ChatColor.LIGHT_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).bold().toString());
|
||||
- replacements.put(ChatColor.YELLOW, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).bold().toString());
|
||||
- replacements.put(ChatColor.WHITE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).bold().toString());
|
||||
- replacements.put(ChatColor.MAGIC, Ansi.ansi().a(Attribute.BLINK_SLOW).toString());
|
||||
- replacements.put(ChatColor.BOLD, Ansi.ansi().a(Attribute.UNDERLINE_DOUBLE).toString());
|
||||
- replacements.put(ChatColor.STRIKETHROUGH, Ansi.ansi().a(Attribute.STRIKETHROUGH_ON).toString());
|
||||
- replacements.put(ChatColor.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString());
|
||||
- replacements.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString());
|
||||
- replacements.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString());
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void sendMessage(String message) {
|
||||
- if (terminal.isAnsiSupported()) {
|
||||
- if (!conversationTracker.isConversingModaly()) {
|
||||
- String result = message;
|
||||
- for (ChatColor color : colors) {
|
||||
- if (replacements.containsKey(color)) {
|
||||
- result = result.replaceAll("(?i)" + color.toString(), replacements.get(color));
|
||||
- } else {
|
||||
- result = result.replaceAll("(?i)" + color.toString(), "");
|
||||
- }
|
||||
- }
|
||||
- System.out.println(result + Ansi.ansi().reset().toString());
|
||||
- }
|
||||
- } else {
|
||||
- super.sendMessage(message);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- public static ConsoleCommandSender getInstance() {
|
||||
- if (Bukkit.getConsoleSender() != null) {
|
||||
- return Bukkit.getConsoleSender();
|
||||
- } else {
|
||||
- return new ColouredConsoleSender();
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
index 33e8ea02..1e3aae3b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
@@ -0,0 +0,0 @@ import java.util.logging.Level;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
|
||||
-import jline.console.completer.Completer;
|
||||
+// Paper start - JLine update
|
||||
+import net.minecraft.server.DedicatedServer; // Paper
|
||||
+import org.jline.reader.Candidate;
|
||||
+import org.jline.reader.Completer;
|
||||
+import org.jline.reader.LineReader;
|
||||
+import org.jline.reader.ParsedLine;
|
||||
+// Paper end
|
||||
import org.bukkit.event.server.TabCompleteEvent;
|
||||
|
||||
public class ConsoleCommandCompleter implements Completer {
|
||||
- private final CraftServer server;
|
||||
+ private final DedicatedServer server; // Paper - CraftServer -> DedicatedServer
|
||||
|
||||
- public ConsoleCommandCompleter(CraftServer server) {
|
||||
+ public ConsoleCommandCompleter(DedicatedServer server) { // Paper - CraftServer -> DedicatedServer
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
|
||||
+ // Paper start - Change method signature for JLine update
|
||||
+ public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||
+ final CraftServer server = this.server.server;
|
||||
+ final String buffer = line.line();
|
||||
+ // Paper end
|
||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||
@Override
|
||||
protected List<String> evaluate() {
|
||||
@@ -0,0 +0,0 @@ public class ConsoleCommandCompleter implements Completer {
|
||||
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
||||
}
|
||||
};
|
||||
- this.server.getServer().processQueue.add(waitable);
|
||||
+ server.getServer().processQueue.add(waitable); // Paper - Remove "this."
|
||||
try {
|
||||
List<String> offers = waitable.get();
|
||||
if (offers == null) {
|
||||
- return cursor;
|
||||
+ return; // Paper - Method returns void
|
||||
}
|
||||
- candidates.addAll(offers);
|
||||
|
||||
+ // Paper start - JLine update
|
||||
+ for (String completion : offers) {
|
||||
+ if (completion.isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ candidates.add(new Candidate(completion));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ // Paper start - JLine handles cursor now
|
||||
+ /*
|
||||
final int lastSpace = buffer.lastIndexOf(' ');
|
||||
if (lastSpace == -1) {
|
||||
return cursor - buffer.length();
|
||||
} else {
|
||||
return cursor - (buffer.length() - lastSpace - 1);
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
} catch (ExecutionException e) {
|
||||
- this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
|
||||
+ server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); // Paper - Remove "this."
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
- return cursor;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
index ae3481ba..6a38025e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
@@ -0,0 +0,0 @@ public class ServerShutdownThread extends Thread {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
- server.reader.getTerminal().restore();
|
||||
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java
|
||||
deleted file mode 100644
|
||||
index b6409711..00000000
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java
|
||||
+++ /dev/null
|
||||
@@ -0,0 +0,0 @@
|
||||
-package org.bukkit.craftbukkit.util;
|
||||
-
|
||||
-import java.io.IOException;
|
||||
-import java.io.OutputStream;
|
||||
-import java.util.logging.Level;
|
||||
-import java.util.logging.Logger;
|
||||
-import jline.console.ConsoleReader;
|
||||
-import com.mojang.util.QueueLogAppender;
|
||||
-import org.bukkit.craftbukkit.Main;
|
||||
-import org.fusesource.jansi.Ansi;
|
||||
-import org.fusesource.jansi.Ansi.Erase;
|
||||
-
|
||||
-public class TerminalConsoleWriterThread implements Runnable {
|
||||
- final private ConsoleReader reader;
|
||||
- final private OutputStream output;
|
||||
-
|
||||
- public TerminalConsoleWriterThread(OutputStream output, ConsoleReader reader) {
|
||||
- this.output = output;
|
||||
- this.reader = reader;
|
||||
- }
|
||||
-
|
||||
- public void run() {
|
||||
- String message;
|
||||
-
|
||||
- // Using name from log4j config in vanilla jar
|
||||
- while (true) {
|
||||
- message = QueueLogAppender.getNextLogEvent("TerminalConsole");
|
||||
- if (message == null) {
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- try {
|
||||
- if (Main.useJline) {
|
||||
- reader.print(Ansi.ansi().eraseLine(Erase.ALL).toString() + ConsoleReader.RESET_LINE);
|
||||
- reader.flush();
|
||||
- output.write(message.getBytes());
|
||||
- output.flush();
|
||||
-
|
||||
- try {
|
||||
- reader.drawLine();
|
||||
- } catch (Throwable ex) {
|
||||
- reader.getCursorBuffer().clear();
|
||||
- }
|
||||
- reader.flush();
|
||||
- } else {
|
||||
- output.write(message.getBytes());
|
||||
- output.flush();
|
||||
- }
|
||||
- } catch (IOException ex) {
|
||||
- Logger.getLogger(TerminalConsoleWriterThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 5cee8f00..f248d05f 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -0,0 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
-<Configuration status="WARN" packages="com.mojang.util">
|
||||
+<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="WINDOWS_COMPAT" target="SYSTEM_OUT"></Console>
|
||||
- <Queue name="TerminalConsole">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||
- </Queue>
|
||||
+ <TerminalConsole name="TerminalConsole">
|
||||
+ <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
||||
+ </TerminalConsole>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
+ <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
||||
--
|
|
@ -1,27 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 17 May 2017 17:45:19 -0500
|
||||
Subject: [PATCH] Workaround for jansi bug with Windows
|
||||
|
||||
When jansi attempts to extract its natives, by default it tries to extract a specific version
|
||||
using the loading class's implementation version. Normally this works completely fine
|
||||
however when on Windows certain characters such as - and : can trigger special behaviour.
|
||||
|
||||
Furthermore this behaviour only occurs in specific combinations due to the parsing done by jansi.
|
||||
For example test-test works fine, but test-test-test does not! In order to avoid this all together but
|
||||
still keep our versions the same as they were, we set the override property to the essentially garbage version
|
||||
Paper. This version is only used when extracting the libraries to their temp folder.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 1cbcc3dfa..98e27fa25 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
}
|
||||
|
||||
if (useJline) {
|
||||
+ System.setProperty( "library.jansi.version", "Paper" ); // Paper - set jansi library version to avoid crash
|
||||
AnsiConsole.systemInstall();
|
||||
} else {
|
||||
// This ensures the terminal literal will always match the jline implementation
|
||||
--
|
5
pom.xml
5
pom.xml
|
@ -40,6 +40,11 @@
|
|||
<id>aikar</id>
|
||||
<url>http://ci.emc.gs/nexus/content/groups/aikar/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<!-- TODO: Remove when TerminalConsoleAppender is released -->
|
||||
<id>oss-snapshots</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<distributionManagement>
|
||||
|
|
Loading…
Reference in a new issue