Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit 7e8af54

Browse files
BillyGalbreathgranny
authored andcommitted
GUI Improvements
1 parent c5617e1 commit 7e8af54

7 files changed

Lines changed: 392 additions & 421 deletions

File tree

patches/server/0275-Make-GUI-Great-Again.patch

Lines changed: 0 additions & 421 deletions
This file was deleted.

purpur-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
--- a/net/minecraft/server/dedicated/DedicatedServer.java
22
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
3+
@@ -106,6 +_,7 @@
4+
// CraftBukkit start
5+
if (!org.bukkit.craftbukkit.Main.useConsole) return;
6+
// Paper start - Use TerminalConsoleAppender
7+
+ if (DedicatedServer.this.gui == null || System.console() != null) // Purpur - GUI Improvements - has no GUI or has console (did not double-click)
8+
new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
9+
/*
10+
jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader;
311
@@ -224,6 +_,15 @@
412
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
513
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
--- a/net/minecraft/server/gui/MinecraftServerGui.java
2+
+++ b/net/minecraft/server/gui/MinecraftServerGui.java
3+
@@ -39,6 +_,11 @@
4+
private Thread logAppenderThread;
5+
private final Collection<Runnable> finalizers = Lists.newArrayList();
6+
final AtomicBoolean isClosing = new AtomicBoolean();
7+
+ // Purpur start - GUI Improvements
8+
+ private final CommandHistory history = new CommandHistory();
9+
+ private String currentCommand = "";
10+
+ private int historyIndex = 0;
11+
+ // Purpur end - GUI Improvements
12+
13+
public static MinecraftServerGui showFrameFor(final DedicatedServer server) {
14+
try {
15+
@@ -46,7 +_,7 @@
16+
} catch (Exception var3) {
17+
}
18+
19+
- final JFrame jFrame = new JFrame("Minecraft server");
20+
+ final JFrame jFrame = new JFrame("Purpur Minecraft server"); // Purpur - Improve GUI
21+
final MinecraftServerGui minecraftServerGui = new MinecraftServerGui(server);
22+
jFrame.setDefaultCloseOperation(2);
23+
jFrame.add(minecraftServerGui);
24+
@@ -54,7 +_,7 @@
25+
jFrame.setLocationRelativeTo(null);
26+
jFrame.setVisible(true);
27+
// Paper start - Improve ServerGUI
28+
- jFrame.setName("Minecraft server");
29+
+ jFrame.setName("Purpur Minecraft server"); // Purpur - Improve GUI
30+
try {
31+
jFrame.setIconImage(javax.imageio.ImageIO.read(java.util.Objects.requireNonNull(MinecraftServerGui.class.getClassLoader().getResourceAsStream("logo.png"))));
32+
} catch (java.io.IOException ignore) {
33+
@@ -64,7 +_,7 @@
34+
@Override
35+
public void windowClosing(WindowEvent event) {
36+
if (!minecraftServerGui.isClosing.getAndSet(true)) {
37+
- jFrame.setTitle("Minecraft server - shutting down!");
38+
+ jFrame.setTitle("Purpur Minecraft server - shutting down!"); // Purpur - Improve GUI
39+
server.halt(true);
40+
minecraftServerGui.runFinalizers();
41+
}
42+
@@ -112,7 +_,7 @@
43+
44+
private JComponent buildChatPanel() {
45+
JPanel jPanel = new JPanel(new BorderLayout());
46+
- JTextArea jTextArea = new JTextArea();
47+
+ org.purpurmc.purpur.gui.JColorTextPane jTextArea = new org.purpurmc.purpur.gui.JColorTextPane(); // Purpur - GUI Improvements
48+
JScrollPane jScrollPane = new JScrollPane(jTextArea, 22, 30);
49+
jTextArea.setEditable(false);
50+
jTextArea.setFont(MONOSPACED);
51+
@@ -121,10 +_,43 @@
52+
String trimmed = jTextField.getText().trim();
53+
if (!trimmed.isEmpty()) {
54+
this.server.handleConsoleInput(trimmed, this.server.createCommandSourceStack());
55+
+ // Purpur start - GUI Improvements
56+
+ history.add(trimmed);
57+
+ historyIndex = -1;
58+
+ // Purpur end - GUI Improvements
59+
}
60+
61+
jTextField.setText("");
62+
});
63+
+ // Purpur start - GUI Improvements
64+
+ jTextField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("UP"), "up");
65+
+ jTextField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("DOWN"), "down");
66+
+ jTextField.getActionMap().put("up", new javax.swing.AbstractAction() {
67+
+ @Override
68+
+ public void actionPerformed(java.awt.event.ActionEvent actionEvent) {
69+
+ if (historyIndex < 0) {
70+
+ currentCommand = jTextField.getText();
71+
+ }
72+
+ if (historyIndex < history.size() - 1) {
73+
+ jTextField.setText(history.get(++historyIndex));
74+
+ }
75+
+ }
76+
+ });
77+
+ jTextField.getActionMap().put("down", new javax.swing.AbstractAction() {
78+
+ @Override
79+
+ public void actionPerformed(java.awt.event.ActionEvent actionEvent) {
80+
+ if (historyIndex >= 0) {
81+
+ if (historyIndex == 0) {
82+
+ --historyIndex;
83+
+ jTextField.setText(currentCommand);
84+
+ } else {
85+
+ --historyIndex;
86+
+ jTextField.setText(history.get(historyIndex));
87+
+ }
88+
+ }
89+
+ }
90+
+ });
91+
+ // Purpur end - GUI Improvements
92+
jTextArea.addFocusListener(new FocusAdapter() {
93+
@Override
94+
public void focusGained(FocusEvent event) {
95+
@@ -159,7 +_,7 @@
96+
}
97+
98+
private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper
99+
- public void print(JTextArea textArea, JScrollPane scrollPane, String line) {
100+
+ public void print(org.purpurmc.purpur.gui.JColorTextPane textArea, JScrollPane scrollPane, String line) { // Purpur - GUI Improvements
101+
if (!SwingUtilities.isEventDispatchThread()) {
102+
SwingUtilities.invokeLater(() -> this.print(textArea, scrollPane, line));
103+
} else {
104+
@@ -170,16 +_,29 @@
105+
flag = verticalScrollBar.getValue() + verticalScrollBar.getSize().getHeight() + MONOSPACED.getSize() * 4 > verticalScrollBar.getMaximum();
106+
}
107+
108+
- try {
109+
+ /*try { // Purpur - GUI Improvements
110+
document.insertString(document.getLength(), MinecraftServerGui.ANSI.matcher(line).replaceAll(""), null); // CraftBukkit
111+
} catch (BadLocationException var8) {
112+
- }
113+
+ }*/ // Purpur - GUI Improvements
114+
+ textArea.append(line); // Purpur - GUI Improvements
115+
116+
if (flag) {
117+
verticalScrollBar.setValue(Integer.MAX_VALUE);
118+
}
119+
}
120+
}
121+
+
122+
+ // Purpur start - GUI Improvements
123+
+ public static class CommandHistory extends java.util.LinkedList<String> {
124+
+ @Override
125+
+ public boolean add(String command) {
126+
+ if (size() > 1000) {
127+
+ remove();
128+
+ }
129+
+ return super.offerFirst(command);
130+
+ }
131+
+ }
132+
+ // Purpur end - GUI Improvements
133+
134+
// Paper start - Add onboarding message for initial server start
135+
private JComponent buildOnboardingPanel() {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
--- /dev/null
2+
+++ b/src/log4jPlugins/java/org/purpurmc/purpur/gui/util/HighlightErrorConverter.java
3+
@@ -1,0 +_,85 @@
4+
+package org.purpurmc.purpur.gui.util;
5+
+
6+
+import org.apache.logging.log4j.Level;
7+
+import org.apache.logging.log4j.core.LogEvent;
8+
+import org.apache.logging.log4j.core.config.Configuration;
9+
+import org.apache.logging.log4j.core.config.plugins.Plugin;
10+
+import org.apache.logging.log4j.core.layout.PatternLayout;
11+
+import org.apache.logging.log4j.core.pattern.ConverterKeys;
12+
+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
13+
+import org.apache.logging.log4j.core.pattern.PatternConverter;
14+
+import org.apache.logging.log4j.core.pattern.PatternFormatter;
15+
+import org.apache.logging.log4j.core.pattern.PatternParser;
16+
+import org.apache.logging.log4j.util.PerformanceSensitive;
17+
+
18+
+import java.util.List;
19+
+
20+
+@Plugin(name = "highlightGUIError", category = PatternConverter.CATEGORY)
21+
+@ConverterKeys({"highlightGUIError"})
22+
+@PerformanceSensitive("allocation")
23+
+public final class HighlightErrorConverter extends LogEventPatternConverter {
24+
+ private static final String ERROR = "\u00A74\u00A7l"; // Bold Red
25+
+ private static final String WARN = "\u00A7e\u00A7l"; // Bold Yellow
26+
+
27+
+ private final List<PatternFormatter> formatters;
28+
+
29+
+ private HighlightErrorConverter(List<PatternFormatter> formatters) {
30+
+ super("highlightGUIError", null);
31+
+ this.formatters = formatters;
32+
+ }
33+
+
34+
+ @Override
35+
+ public void format(LogEvent event, StringBuilder toAppendTo) {
36+
+ Level level = event.getLevel();
37+
+ if (level.isMoreSpecificThan(Level.ERROR)) {
38+
+ format(ERROR, event, toAppendTo);
39+
+ return;
40+
+ } else if (level.isMoreSpecificThan(Level.WARN)) {
41+
+ format(WARN, event, toAppendTo);
42+
+ return;
43+
+ }
44+
+ for (PatternFormatter formatter : formatters) {
45+
+ formatter.format(event, toAppendTo);
46+
+ }
47+
+ }
48+
+
49+
+ private void format(String style, LogEvent event, StringBuilder toAppendTo) {
50+
+ int start = toAppendTo.length();
51+
+ toAppendTo.append(style);
52+
+ int end = toAppendTo.length();
53+
+
54+
+ for (PatternFormatter formatter : formatters) {
55+
+ formatter.format(event, toAppendTo);
56+
+ }
57+
+
58+
+ if (toAppendTo.length() == end) {
59+
+ toAppendTo.setLength(start);
60+
+ }
61+
+ }
62+
+
63+
+ @Override
64+
+ public boolean handlesThrowable() {
65+
+ for (final PatternFormatter formatter : formatters) {
66+
+ if (formatter.handlesThrowable()) {
67+
+ return true;
68+
+ }
69+
+ }
70+
+ return false;
71+
+ }
72+
+
73+
+ public static HighlightErrorConverter newInstance(Configuration config, String[] options) {
74+
+ if (options.length != 1) {
75+
+ LOGGER.error("Incorrect number of options on highlightGUIError. Expected 1 received " + options.length);
76+
+ return null;
77+
+ }
78+
+
79+
+ if (options[0] == null) {
80+
+ LOGGER.error("No pattern supplied on highlightGUIError");
81+
+ return null;
82+
+ }
83+
+
84+
+ PatternParser parser = PatternLayout.createPatternParser(config);
85+
+ List<PatternFormatter> formatters = parser.parse(options[0]);
86+
+ return new HighlightErrorConverter(formatters);
87+
+ }
88+
+}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--- a/src/main/resources/log4j2.xml
2+
+++ b/src/main/resources/log4j2.xml
3+
@@ -2,7 +_,16 @@
4+
<Configuration status="WARN" shutdownHook="disable">
5+
<Appenders>
6+
<Queue name="ServerGuiConsole">
7+
- <PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" />
8+
+ <!-- Purpur start - copied from TerminalConsole -->
9+
+ <PatternLayout>
10+
+ <LoggerNamePatternSelector defaultPattern="%highlightGUIError{[%d{HH:mm:ss} %level]: [%logger] %stripAnsi{%msg}%n%xEx{full}}">
11+
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
12+
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
13+
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
14+
+ pattern="%highlightGUIError{[%d{HH:mm:ss} %level]: %stripAnsi{%msg}%n%xEx{full}}" />
15+
+ </LoggerNamePatternSelector>
16+
+ </PatternLayout>
17+
+ <!-- Purpur end -->
18+
</Queue>
19+
<TerminalConsole name="TerminalConsole">
20+
<PatternLayout>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.purpurmc.purpur.gui;
2+
3+
import net.md_5.bungee.api.ChatColor;
4+
5+
import java.awt.Color;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
public enum GUIColor {
10+
BLACK(ChatColor.BLACK, new Color(0x000000)),
11+
DARK_BLUE(ChatColor.DARK_BLUE, new Color(0x0000AA)),
12+
DARK_GREEN(ChatColor.DARK_GREEN, new Color(0x00AA00)),
13+
DARK_AQUA(ChatColor.DARK_AQUA, new Color(0x009999)),
14+
DARK_RED(ChatColor.DARK_RED, new Color(0xAA0000)),
15+
DARK_PURPLE(ChatColor.DARK_PURPLE, new Color(0xAA00AA)),
16+
GOLD(ChatColor.GOLD, new Color(0xBB8800)),
17+
GRAY(ChatColor.GRAY, new Color(0x888888)),
18+
DARK_GRAY(ChatColor.DARK_GRAY, new Color(0x444444)),
19+
BLUE(ChatColor.BLUE, new Color(0x5555FF)),
20+
GREEN(ChatColor.GREEN, new Color(0x55FF55)),
21+
AQUA(ChatColor.AQUA, new Color(0x55DDDD)),
22+
RED(ChatColor.RED, new Color(0xFF5555)),
23+
LIGHT_PURPLE(ChatColor.LIGHT_PURPLE, new Color(0xFF55FF)),
24+
YELLOW(ChatColor.YELLOW, new Color(0xFFBB00)),
25+
WHITE(ChatColor.WHITE, new Color(0xBBBBBB));
26+
27+
private final ChatColor chat;
28+
private final Color color;
29+
30+
private static final Map<ChatColor, GUIColor> BY_CHAT = new HashMap<>();
31+
32+
GUIColor(ChatColor chat, Color color) {
33+
this.chat = chat;
34+
this.color = color;
35+
}
36+
37+
public Color getColor() {
38+
return color;
39+
}
40+
41+
public ChatColor getChatColor() {
42+
return chat;
43+
}
44+
45+
public String getCode() {
46+
return chat.toString();
47+
}
48+
49+
public static GUIColor getColor(ChatColor chat) {
50+
return BY_CHAT.get(chat);
51+
}
52+
53+
static {
54+
for (GUIColor color : values()) {
55+
BY_CHAT.put(color.chat, color);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)