From dc3dc7f0e53caf7b9e9936243c9f994b87b3d883 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 16 Jan 2020 14:59:16 -0600 Subject: [PATCH] Fix layout and add colors to the Server GUI --- .../java/net/minecraft/server/ServerGUI.java | 6 +- .../java/net/pl3x/purpur/swing/ColorPane.java | 129 ++++++++++++++++++ .../java/org/bukkit/craftbukkit/Main.java | 1 + src/main/resources/log4j2.xml | 11 +- 4 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 src/main/java/net/pl3x/purpur/swing/ColorPane.java diff --git a/src/main/java/net/minecraft/server/ServerGUI.java b/src/main/java/net/minecraft/server/ServerGUI.java index 95561d9db..2ce99770b 100644 --- a/src/main/java/net/minecraft/server/ServerGUI.java +++ b/src/main/java/net/minecraft/server/ServerGUI.java @@ -109,7 +109,7 @@ public class ServerGUI extends JComponent { private JComponent e() { JPanel jpanel = new JPanel(new BorderLayout()); - JTextArea jtextarea = new JTextArea(); + net.pl3x.purpur.swing.ColorPane jtextarea = new net.pl3x.purpur.swing.ColorPane(); // Purpur JScrollPane jscrollpane = new JScrollPane(jtextarea, 22, 30); jtextarea.setEditable(false); @@ -160,7 +160,7 @@ public class ServerGUI extends JComponent { } private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})*)?[m|K]"); // CraftBukkit - public void a(JTextArea jtextarea, JScrollPane jscrollpane, String s) { + public void a(net.pl3x.purpur.swing.ColorPane jtextarea, JScrollPane jscrollpane, String s) { // Purpur if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(() -> { this.a(jtextarea, jscrollpane, s); @@ -174,11 +174,13 @@ public class ServerGUI extends JComponent { flag = (double) jscrollbar.getValue() + jscrollbar.getSize().getHeight() + (double) (ServerGUI.a.getSize() * 4) > (double) jscrollbar.getMaximum(); } + /* // Purpur try { document.insertString(document.getLength(), ANSI.matcher(s).replaceAll(""), (AttributeSet) null); // CraftBukkit } catch (BadLocationException badlocationexception) { ; } + */ jtextarea.appendANSI(s); // Purpur if (flag) { jscrollbar.setValue(Integer.MAX_VALUE); diff --git a/src/main/java/net/pl3x/purpur/swing/ColorPane.java b/src/main/java/net/pl3x/purpur/swing/ColorPane.java new file mode 100644 index 000000000..6f702ad4d --- /dev/null +++ b/src/main/java/net/pl3x/purpur/swing/ColorPane.java @@ -0,0 +1,129 @@ +package net.pl3x.purpur.swing; + +import org.apache.commons.lang.StringEscapeUtils; + +import javax.swing.*; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import java.awt.*; + +/* + * Class from: https://stackoverflow.com/a/6899478 + */ + +public class ColorPane extends JTextPane { + static final Color BLACK = Color.BLACK; + static final Color RED = Color.RED; + static final Color BLUE = Color.BLUE; + static final Color MAGENTA = Color.MAGENTA; + static final Color GREEN = Color.GREEN; + static final Color YELLOW = Color.getHSBColor(0.15f, 1.0f, 1.0f); + static final Color CYAN = Color.CYAN; + static final Color WHITE = Color.LIGHT_GRAY; + + static Color colorCurrent = BLACK; + String remaining = ""; + + public void append(Color c, String s) { + StyleContext sc = StyleContext.getDefaultStyleContext(); + AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c); + if (c != BLACK) { + aset = sc.addAttribute(aset, StyleConstants.CharacterConstants.Bold, true); + } + int len = getDocument().getLength(); // same value as getText().length(); + + //setCaretPosition(len); // place caret at the end (with no selection) + //setCharacterAttributes(aset, false); + //replaceSelection(s); // there is no selection, so inserts at caret + + try { + getDocument().insertString(len, s, aset); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + + public void appendANSI(String s) { // convert ANSI color codes first + int aPos = 0; // current char position in addString + int aIndex = 0; // index of next Escape sequence + int mIndex = 0; // index of "m" terminating Escape sequence + String tmpString = ""; + boolean stillSearching = true; // true until no more Escape sequences + String addString = remaining + s; + remaining = ""; + colorCurrent = BLACK; // reset the colors + + if (addString.length() > 0) { + aIndex = addString.indexOf("\u001B"); // find first escape + if (aIndex == -1) { // no escape/color change in this string, so just send it with current color + append(colorCurrent, addString); + return; + } + // otherwise There is an escape character in the string, so we must process it + + if (aIndex > 0) { // Escape is not first char, so send text up to first escape + tmpString = addString.substring(0, aIndex); + append(colorCurrent, tmpString); + aPos = aIndex; + } + // aPos is now at the beginning of the first escape sequence + + stillSearching = true; + while (stillSearching) { + mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence + if (mIndex < 0) { // the buffer ends halfway through the ansi string! + remaining = addString.substring(aPos, addString.length()); + stillSearching = false; + continue; + } else { + tmpString = addString.substring(aPos, mIndex + 1); + colorCurrent = getANSIColor(tmpString); + } + aPos = mIndex + 1; + // now we have the color, send text that is in that color (up to next escape) + + aIndex = addString.indexOf("\u001B", aPos); + + if (aIndex == -1) { // if that was the last sequence of the input, send remaining text + tmpString = addString.substring(aPos, addString.length()); + append(colorCurrent, tmpString); + stillSearching = false; + continue; // jump out of loop early, as the whole string has been sent now + } + + // there is another escape sequence, so send part of the string and prepare for the next + tmpString = addString.substring(aPos, aIndex); + aPos = aIndex; + append(colorCurrent, tmpString); + + } // while there's text in the input buffer + } + } + + public Color getANSIColor(String ANSIColor) { + if (ANSIColor.isEmpty()) { + return BLACK; + } else if (ANSIColor.contains("30")) { + return BLACK; + } else if (ANSIColor.contains("31")) { + return RED; + } else if (ANSIColor.contains("32")) { + return GREEN; + } else if (ANSIColor.contains("33")) { + return YELLOW; + } else if (ANSIColor.contains("34")) { + return BLUE; + } else if (ANSIColor.contains("35")) { + return MAGENTA; + } else if (ANSIColor.contains("36")) { + return CYAN; + } else if (ANSIColor.contains("37")) { + return WHITE; + } else { + return BLACK; + } + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 7e8b6cab7..f30bcbd48 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -144,6 +144,7 @@ public class Main { .ofType(File.class) .defaultsTo(new File("purpur.yml")) .describedAs("Yml file"); + accepts("nogui", "Disables the graphical window"); // Purpur end // Paper start diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 869bff4af..2a3e57c2f 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -2,7 +2,16 @@ - + + + + + + + + + -- 2.24.0