summaryrefslogtreecommitdiffhomepage
path: root/patches/server/0366-Make-the-GUI-graph-fancier.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0366-Make-the-GUI-graph-fancier.patch')
-rw-r--r--patches/server/0366-Make-the-GUI-graph-fancier.patch398
1 files changed, 398 insertions, 0 deletions
diff --git a/patches/server/0366-Make-the-GUI-graph-fancier.patch b/patches/server/0366-Make-the-GUI-graph-fancier.patch
new file mode 100644
index 0000000000..b97ce20f84
--- /dev/null
+++ b/patches/server/0366-Make-the-GUI-graph-fancier.patch
@@ -0,0 +1,398 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: William Blake Galbreath <[email protected]>
+Date: Sun, 2 Feb 2020 04:00:40 -0600
+Subject: [PATCH] Make the GUI graph fancier
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/gui/GraphColor.java b/src/main/java/com/destroystokyo/paper/gui/GraphColor.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..a4e641fdcccd3efcd1a2865dc6dc28d50671b995
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/gui/GraphColor.java
+@@ -0,0 +1,44 @@
++package com.destroystokyo.paper.gui;
++
++import java.awt.Color;
++
++public class GraphColor {
++ private static final Color[] colorLine = new Color[101];
++ private static final Color[] colorFill = new Color[101];
++
++ static {
++ for (int i = 0; i < 101; i++) {
++ Color color = createColor(i);
++ colorLine[i] = new Color(color.getRed() / 2, color.getGreen() / 2, color.getBlue() / 2, 255);
++ colorFill[i] = new Color(colorLine[i].getRed(), colorLine[i].getGreen(), colorLine[i].getBlue(), 125);
++ }
++ }
++
++ public static Color getLineColor(int percent) {
++ return colorLine[percent];
++ }
++
++ public static Color getFillColor(int percent) {
++ return colorFill[percent];
++ }
++
++ private static Color createColor(int percent) {
++ if (percent <= 50) {
++ return new Color(0X00FF00);
++ }
++
++ int value = 510 - (int) (Math.min(Math.max(0, ((percent - 50) / 50F)), 1) * 510);
++
++ int red, green;
++ if (value < 255) {
++ red = 255;
++ green = (int) (Math.sqrt(value) * 16);
++ } else {
++ green = 255;
++ value = value - 255;
++ red = 255 - (value * value / 255);
++ }
++
++ return new Color(red, green, 0);
++ }
++}
+diff --git a/src/main/java/com/destroystokyo/paper/gui/GraphData.java b/src/main/java/com/destroystokyo/paper/gui/GraphData.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..186fc722965e403f76b1480e1c2381fc34e29049
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/gui/GraphData.java
+@@ -0,0 +1,47 @@
++package com.destroystokyo.paper.gui;
++
++import java.awt.Color;
++
++public class GraphData {
++ private long total;
++ private long free;
++ private long max;
++ private long usedMem;
++ private int usedPercent;
++
++ public GraphData(long total, long free, long max) {
++ this.total = total;
++ this.free = free;
++ this.max = max;
++ this.usedMem = total - free;
++ this.usedPercent = usedMem == 0 ? 0 : (int) (usedMem * 100L / max);
++ }
++
++ public long getTotal() {
++ return total;
++ }
++
++ public long getFree() {
++ return free;
++ }
++
++ public long getMax() {
++ return max;
++ }
++
++ public long getUsedMem() {
++ return usedMem;
++ }
++
++ public int getUsedPercent() {
++ return usedPercent;
++ }
++
++ public Color getFillColor() {
++ return GraphColor.getFillColor(usedPercent);
++ }
++
++ public Color getLineColor() {
++ return GraphColor.getLineColor(usedPercent);
++ }
++}
+diff --git a/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..537bc6213545e8ff1b7b51bc4b27fd5b2a740883
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java
+@@ -0,0 +1,41 @@
++package com.destroystokyo.paper.gui;
++
++import net.minecraft.server.MinecraftServer;
++
++import javax.swing.JPanel;
++import javax.swing.Timer;
++import java.awt.BorderLayout;
++import java.awt.Dimension;
++
++public class GuiStatsComponent extends JPanel {
++ private final Timer timer;
++ private final RAMGraph ramGraph;
++
++ public GuiStatsComponent(MinecraftServer server) {
++ super(new BorderLayout());
++
++ setOpaque(false);
++
++ ramGraph = new RAMGraph();
++ RAMDetails ramDetails = new RAMDetails(server);
++
++ add(ramGraph, "North");
++ add(ramDetails, "Center");
++
++ timer = new Timer(500, (event) -> {
++ ramGraph.update();
++ ramDetails.update();
++ });
++ timer.start();
++ }
++
++ @Override
++ public Dimension getPreferredSize() {
++ return new Dimension(350, 200);
++ }
++
++ public void close() {
++ timer.stop();
++ ramGraph.stop();
++ }
++}
+diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..23239679d6584f1088b2b94c46eb9a5c1f9ad91d
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
+@@ -0,0 +1,73 @@
++package com.destroystokyo.paper.gui;
++
++import net.minecraft.Util;
++import net.minecraft.server.MinecraftServer;
++
++import javax.swing.DefaultListCellRenderer;
++import javax.swing.DefaultListSelectionModel;
++import javax.swing.JList;
++import javax.swing.border.EmptyBorder;
++import java.awt.Dimension;
++import java.text.DecimalFormat;
++import java.text.DecimalFormatSymbols;
++import java.util.Locale;
++import java.util.Vector;
++
++public class RAMDetails extends JList<String> {
++ public static final DecimalFormat DECIMAL_FORMAT = Util.make(new DecimalFormat("########0.000"), (format)
++ -> format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)));
++
++ private final MinecraftServer server;
++
++ public RAMDetails(MinecraftServer server) {
++ this.server = server;
++
++ setBorder(new EmptyBorder(0, 10, 0, 0));
++ setFixedCellHeight(20);
++ setOpaque(false);
++
++ DefaultListCellRenderer renderer = new DefaultListCellRenderer();
++ renderer.setOpaque(false);
++ setCellRenderer(renderer);
++
++ setSelectionModel(new DefaultListSelectionModel() {
++ @Override
++ public void setAnchorSelectionIndex(final int anchorIndex) {
++ }
++
++ @Override
++ public void setLeadAnchorNotificationEnabled(final boolean flag) {
++ }
++
++ @Override
++ public void setLeadSelectionIndex(final int leadIndex) {
++ }
++
++ @Override
++ public void setSelectionInterval(final int index0, final int index1) {
++ }
++ });
++ }
++
++ @Override
++ public Dimension getPreferredSize() {
++ return new Dimension(350, 100);
++ }
++
++ public void update() {
++ GraphData data = RAMGraph.DATA.peekLast();
++ Vector<String> vector = new Vector<>();
++ vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)");
++ vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb");
++ vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.tickTimes)) + " ms");
++ setListData(vector);
++ }
++
++ public double getAverage(long[] tickTimes) {
++ long total = 0L;
++ for (long value : tickTimes) {
++ total += value;
++ }
++ return ((double) total / (double) tickTimes.length) * 1.0E-6D;
++ }
++}
+diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java b/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..c3e54da4ab6440811aab2f9dd1e218802ac13285
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java
+@@ -0,0 +1,144 @@
++package com.destroystokyo.paper.gui;
++
++import javax.swing.JComponent;
++import javax.swing.SwingUtilities;
++import javax.swing.Timer;
++import javax.swing.ToolTipManager;
++import java.awt.Color;
++import java.awt.Dimension;
++import java.awt.Graphics;
++import java.awt.MouseInfo;
++import java.awt.Point;
++import java.awt.PointerInfo;
++import java.awt.event.MouseAdapter;
++import java.awt.event.MouseEvent;
++import java.text.SimpleDateFormat;
++import java.util.Date;
++import java.util.LinkedList;
++import java.util.concurrent.TimeUnit;
++
++public class RAMGraph extends JComponent {
++ public static final LinkedList<GraphData> DATA = new LinkedList<GraphData>() {
++ @Override
++ public boolean add(GraphData data) {
++ if (size() >= 348) {
++ remove();
++ }
++ return super.add(data);
++ }
++ };
++
++ static {
++ GraphData empty = new GraphData(0, 0, 0);
++ for (int i = 0; i < 350; i++) {
++ DATA.add(empty);
++ }
++ }
++
++ private final Timer timer;
++ private final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
++
++ private int currentTick;
++
++ public RAMGraph() {
++ ToolTipManager.sharedInstance().setInitialDelay(0);
++
++ addMouseListener(new MouseAdapter() {
++ final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
++ final int dismissDelayMinutes = (int) TimeUnit.MINUTES.toMillis(10);
++
++ @Override
++ public void mouseEntered(MouseEvent me) {
++ ToolTipManager.sharedInstance().setDismissDelay(dismissDelayMinutes);
++ }
++
++ @Override
++ public void mouseExited(MouseEvent me) {
++ ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout);
++ }
++ });
++
++ timer = new Timer(50, (event) -> repaint());
++ timer.start();
++ }
++
++ @Override
++ public Dimension getPreferredSize() {
++ return new Dimension(350, 110);
++ }
++
++ public void update() {
++ Runtime jvm = Runtime.getRuntime();
++ DATA.add(new GraphData(jvm.totalMemory(), jvm.freeMemory(), jvm.maxMemory()));
++
++ PointerInfo pointerInfo = MouseInfo.getPointerInfo();
++ if (pointerInfo != null) {
++ Point point = pointerInfo.getLocation();
++ if (point != null) {
++ Point loc = new Point(point);
++ SwingUtilities.convertPointFromScreen(loc, this);
++ if (this.contains(loc)) {
++ ToolTipManager.sharedInstance().mouseMoved(
++ new MouseEvent(this, -1, System.currentTimeMillis(), 0, loc.x, loc.y,
++ point.x, point.y, 0, false, 0));
++ }
++ }
++ }
++
++ currentTick++;
++ }
++
++ @Override
++ public void paint(Graphics graphics) {
++ graphics.setColor(new Color(0xFFFFFFFF));
++ graphics.fillRect(0, 0, 350, 100);
++
++ graphics.setColor(new Color(0x888888));
++ graphics.drawLine(1, 25, 348, 25);
++ graphics.drawLine(1, 50, 348, 50);
++ graphics.drawLine(1, 75, 348, 75);
++
++ int i = 0;
++ for (GraphData data : DATA) {
++ i++;
++ if ((i + currentTick) % 120 == 0) {
++ graphics.setColor(new Color(0x888888));
++ graphics.drawLine(i, 1, i, 99);
++ }
++ int used = data.getUsedPercent();
++ if (used > 0) {
++ Color color = data.getLineColor();
++ graphics.setColor(data.getFillColor());
++ graphics.fillRect(i, 100 - used, 1, used);
++ graphics.setColor(color);
++ graphics.fillRect(i, 100 - used, 1, 1);
++ }
++ }
++
++ graphics.setColor(new Color(0xFF000000));
++ graphics.drawRect(0, 0, 348, 100);
++
++ Point m = getMousePosition();
++ if (m != null && m.x > 0 && m.x < 348 && m.y > 0 && m.y < 100) {
++ GraphData data = DATA.get(m.x);
++ int used = data.getUsedPercent();
++ graphics.setColor(new Color(0x000000));
++ graphics.drawLine(m.x, 1, m.x, 99);
++ graphics.drawOval(m.x - 2, 100 - used - 2, 5, 5);
++ graphics.setColor(data.getLineColor());
++ graphics.fillOval(m.x - 2, 100 - used - 2, 5, 5);
++ setToolTipText(String.format("<html><body>Used: %s mb (%s%%)<br/>%s</body></html>",
++ Math.round(data.getUsedMem() / 1024F / 1024F),
++ used, getTime(m.x)));
++ }
++ }
++
++ public String getTime(int halfSeconds) {
++ int millis = (348 - halfSeconds) / 2 * 1000;
++ return TIME_FORMAT.format(new Date((System.currentTimeMillis() - millis)));
++ }
++
++ public void stop() {
++ timer.stop();
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
+index 75083eeb9b413e6dd5375007360dce6857a08fff..66464c10a6b33414c6d1b67b926a66c343d5f887 100644
+--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
++++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
+@@ -95,7 +95,7 @@ public class MinecraftServerGui extends JComponent {
+
+ private JComponent buildInfoPanel() {
+ JPanel jpanel = new JPanel(new BorderLayout());
+- StatsComponent guistatscomponent = new StatsComponent(this.server);
++ com.destroystokyo.paper.gui.GuiStatsComponent guistatscomponent = new com.destroystokyo.paper.gui.GuiStatsComponent(this.server); // Paper
+ Collection<Runnable> collection = this.finalizers; // CraftBukkit - decompile error
+
+ Objects.requireNonNull(guistatscomponent);