    001package net.minecraft.server.gui;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.awt.Color;
    006import java.awt.Dimension;
    007import java.awt.Graphics;
    008import java.text.DecimalFormat;
    009import javax.swing.JComponent;
    010import javax.swing.Timer;
    011import net.minecraft.network.TcpConnection;
    012import net.minecraft.server.MinecraftServer;
    013import net.minecraft.world.WorldServer;
    014import net.minecraftforge.common.DimensionManager;
    015
    016@SideOnly(Side.SERVER)
    017public class GuiStatsComponent extends JComponent
    018{
    019    private static final DecimalFormat field_79020_a = new DecimalFormat("########0.000");
    020
    021    /** An array containing the columns that make up the memory use graph. */
    022    private int[] memoryUse = new int[256];
    023
    024    /**
    025     * Counts the number of updates. Used as the index into the memoryUse array to display the latest value.
    026     */
    027    private int updateCounter = 0;
    028
    029    /** An array containing the strings displayed in this stats component. */
    030    private String[] displayStrings = new String[11];
    031    private final MinecraftServer field_79017_e;
    032
    033    public GuiStatsComponent(MinecraftServer par1MinecraftServer)
    034    {
    035        this.field_79017_e = par1MinecraftServer;
    036        this.setPreferredSize(new Dimension(456, 246));
    037        this.setMinimumSize(new Dimension(456, 246));
    038        this.setMaximumSize(new Dimension(456, 246));
    039        (new Timer(500, new GuiStatsListener(this))).start();
    040        this.setBackground(Color.BLACK);
    041    }
    042
    043    /**
    044     * Updates the stat values and calls paint to redraw the component.
    045     */
    046    private void updateStats()
    047    {
    048        this.displayStrings = new String[5 + DimensionManager.getIDs().length];
    049        long var1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    050        System.gc();
    051        this.displayStrings[0] = "Memory use: " + var1 / 1024L / 1024L + " mb (" + Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory() + "% free)";
    052        this.displayStrings[1] = "Threads: " + TcpConnection.field_74471_a.get() + " + " + TcpConnection.field_74469_b.get();
    053        this.displayStrings[2] = "Avg tick: " + field_79020_a.format(this.calcArrayAverage(this.field_79017_e.tickTimeArray) * 1.0E-6D) + " ms";
    054        this.displayStrings[3] = "Avg sent: " + (int)this.calcArrayAverage(this.field_79017_e.sentPacketCountArray) + ", Avg size: " + (int)this.calcArrayAverage(this.field_79017_e.sentPacketSizeArray);
    055        this.displayStrings[4] = "Avg rec: " + (int)this.calcArrayAverage(this.field_79017_e.receivedPacketCountArray) + ", Avg size: " + (int)this.calcArrayAverage(this.field_79017_e.receivedPacketSizeArray);
    056
    057        if (this.field_79017_e.worldServers != null)
    058        {
    059            int var3 = 0;
    060            for (Integer id : DimensionManager.getIDs())
    061            {
    062                this.displayStrings[5 + var3] = "Lvl " + id + " tick: " + field_79020_a.format(this.calcArrayAverage(this.field_79017_e.worldTickTimes.get(id)) * 1.0E-6D) + " ms";
    063
    064                WorldServer world = DimensionManager.getWorld(id);
    065                if (world != null && world.theChunkProviderServer != null)
    066                {
    067                    this.displayStrings[5 + var3] = this.displayStrings[5 + var3] + ", " + world.theChunkProviderServer.makeString();
    068                    this.displayStrings[5 + var3] = this.displayStrings[5 + var3] + ", Vec3: " + world.getWorldVec3Pool().func_82590_d() + " / " + world.getWorldVec3Pool().getPoolSize();
    069                }
    070                var3++;
    071            }
    072        }
    073
    074        this.memoryUse[this.updateCounter++ & 255] = (int)(this.calcArrayAverage(this.field_79017_e.sentPacketSizeArray) * 100.0D / 12500.0D);
    075        this.repaint();
    076    }
    077
    078    /**
    079     * Calculates the avarage value of the given long array.
    080     */
    081    private double calcArrayAverage(long[] par1ArrayOfLong)
    082    {
    083        long var2 = 0L;
    084
    085        for (int var4 = 0; var4 < par1ArrayOfLong.length; ++var4)
    086        {
    087            var2 += par1ArrayOfLong[var4];
    088        }
    089
    090        return (double)var2 / (double)par1ArrayOfLong.length;
    091    }
    092
    093    public void paint(Graphics par1Graphics)
    094    {
    095        par1Graphics.setColor(new Color(16777215));
    096        par1Graphics.fillRect(0, 0, 456, 246);
    097        int var2;
    098
    099        for (var2 = 0; var2 < 256; ++var2)
    100        {
    101            int var3 = this.memoryUse[var2 + this.updateCounter & 255];
    102            par1Graphics.setColor(new Color(var3 + 28 << 16));
    103            par1Graphics.fillRect(var2, 100 - var3, 1, var3);
    104        }
    105
    106        par1Graphics.setColor(Color.BLACK);
    107
    108        for (var2 = 0; var2 < this.displayStrings.length; ++var2)
    109        {
    110            String var4 = this.displayStrings[var2];
    111
    112            if (var4 != null)
    113            {
    114                par1Graphics.drawString(var4, 32, 116 + var2 * 16);
    115            }
    116        }
    117    }
    118
    119    /**
    120     * Public static accessor to call updateStats.
    121     */
    122    static void update(GuiStatsComponent par0GuiStatsComponent)
    123    {
    124        par0GuiStatsComponent.updateStats();
    125    }
    126}