2025-11-24 22:52:51 +03:00

190 lines
6.7 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.collect.Lists
* com.mojang.logging.LogQueues
* com.mojang.logging.LogUtils
* org.slf4j.Logger
*/
package net.minecraft.server.gui;
import com.google.common.collect.Lists;
import com.mojang.logging.LogQueues;
import com.mojang.logging.LogUtils;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.gui.PlayerListComponent;
import net.minecraft.server.gui.StatsComponent;
import org.slf4j.Logger;
public class MinecraftServerGui
extends JComponent {
private static final Font MONOSPACED = new Font("Monospaced", 0, 12);
private static final Logger LOGGER = LogUtils.getLogger();
private static final String TITLE = "Minecraft server";
private static final String SHUTDOWN_TITLE = "Minecraft server - shutting down!";
private final DedicatedServer server;
private Thread logAppenderThread;
private final Collection<Runnable> finalizers = Lists.newArrayList();
private final AtomicBoolean isClosing = new AtomicBoolean();
public static MinecraftServerGui showFrameFor(final DedicatedServer server) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception exception) {
// empty catch block
}
final JFrame frame = new JFrame(TITLE);
final MinecraftServerGui gui = new MinecraftServerGui(server);
frame.setDefaultCloseOperation(2);
frame.add(gui);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent event) {
if (!gui.isClosing.getAndSet(true)) {
frame.setTitle(MinecraftServerGui.SHUTDOWN_TITLE);
server.halt(true);
gui.runFinalizers();
}
}
});
gui.addFinalizer(frame::dispose);
gui.start();
return gui;
}
private MinecraftServerGui(DedicatedServer server) {
this.server = server;
this.setPreferredSize(new Dimension(854, 480));
this.setLayout(new BorderLayout());
try {
this.add((Component)this.buildChatPanel(), "Center");
this.add((Component)this.buildInfoPanel(), "West");
}
catch (Exception e) {
LOGGER.error("Couldn't build server GUI", (Throwable)e);
}
}
public void addFinalizer(Runnable finalizer) {
this.finalizers.add(finalizer);
}
private JComponent buildInfoPanel() {
JPanel panel = new JPanel(new BorderLayout());
StatsComponent comp = new StatsComponent(this.server);
this.finalizers.add(comp::close);
panel.add((Component)comp, "North");
panel.add((Component)this.buildPlayerPanel(), "Center");
panel.setBorder(new TitledBorder(new EtchedBorder(), "Stats"));
return panel;
}
private JComponent buildPlayerPanel() {
PlayerListComponent playerList = new PlayerListComponent(this.server);
JScrollPane scrollPane = new JScrollPane(playerList, 22, 30);
scrollPane.setBorder(new TitledBorder(new EtchedBorder(), "Players"));
return scrollPane;
}
private JComponent buildChatPanel() {
JPanel panel = new JPanel(new BorderLayout());
JTextArea chatArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(chatArea, 22, 30);
chatArea.setEditable(false);
chatArea.setFont(MONOSPACED);
JTextField chatField = new JTextField();
chatField.addActionListener(event -> {
String text = chatField.getText().trim();
if (!text.isEmpty()) {
this.server.handleConsoleInput(text, this.server.createCommandSourceStack());
}
chatField.setText("");
});
chatArea.addFocusListener(new FocusAdapter(this){
@Override
public void focusGained(FocusEvent arg0) {
}
});
panel.add((Component)scrollPane, "Center");
panel.add((Component)chatField, "South");
panel.setBorder(new TitledBorder(new EtchedBorder(), "Log and chat"));
this.logAppenderThread = new Thread(() -> {
String line;
while ((line = LogQueues.getNextLogEvent((String)"ServerGuiConsole")) != null) {
this.print(chatArea, scrollPane, line);
}
});
this.logAppenderThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
this.logAppenderThread.setDaemon(true);
return panel;
}
public void start() {
this.logAppenderThread.start();
}
public void close() {
if (!this.isClosing.getAndSet(true)) {
this.runFinalizers();
}
}
private void runFinalizers() {
this.finalizers.forEach(Runnable::run);
}
public void print(JTextArea console, JScrollPane scrollPane, String line) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(() -> this.print(console, scrollPane, line));
return;
}
Document document = console.getDocument();
JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
boolean shouldScroll = false;
if (scrollPane.getViewport().getView() == console) {
shouldScroll = (double)scrollBar.getValue() + scrollBar.getSize().getHeight() + (double)(MONOSPACED.getSize() * 4) > (double)scrollBar.getMaximum();
}
try {
document.insertString(document.getLength(), line, null);
}
catch (BadLocationException badLocationException) {
// empty catch block
}
if (shouldScroll) {
scrollBar.setValue(Integer.MAX_VALUE);
}
}
}