    001    package net.minecraft.src;
    002
    003    import java.io.File;
    004    import java.io.FileWriter;
    005    import java.text.SimpleDateFormat;
    006    import java.util.Date;
    007    import java.util.List;
    008    import java.util.logging.Level;
    009    import java.util.logging.Logger;
    010    import net.minecraft.server.MinecraftServer;
    011
    012    public class CommandDebug extends CommandBase
    013    {
    014        /** Time the debugging started in milliseconds. */
    015        private long startTime = 0L;
    016
    017        /** The number of ticks when debugging started. */
    018        private int startTicks = 0;
    019
    020        public String getCommandName()
    021        {
    022            return "debug";
    023        }
    024
    025        public int func_82362_a()
    026        {
    027            return 3;
    028        }
    029
    030        public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr)
    031        {
    032            if (par2ArrayOfStr.length == 1)
    033            {
    034                if (par2ArrayOfStr[0].equals("start"))
    035                {
    036                    notifyAdmins(par1ICommandSender, "commands.debug.start", new Object[0]);
    037                    MinecraftServer.getServer().enableProfiling();
    038                    this.startTime = System.currentTimeMillis();
    039                    this.startTicks = MinecraftServer.getServer().getTickCounter();
    040                    return;
    041                }
    042
    043                if (par2ArrayOfStr[0].equals("stop"))
    044                {
    045                    if (!MinecraftServer.getServer().theProfiler.profilingEnabled)
    046                    {
    047                        throw new CommandException("commands.debug.notStarted", new Object[0]);
    048                    }
    049
    050                    long var3 = System.currentTimeMillis();
    051                    int var5 = MinecraftServer.getServer().getTickCounter();
    052                    long var6 = var3 - this.startTime;
    053                    int var8 = var5 - this.startTicks;
    054                    this.saveProfilerResults(var6, var8);
    055                    MinecraftServer.getServer().theProfiler.profilingEnabled = false;
    056                    notifyAdmins(par1ICommandSender, "commands.debug.stop", new Object[] {Float.valueOf((float)var6 / 1000.0F), Integer.valueOf(var8)});
    057                    return;
    058                }
    059            }
    060
    061            throw new WrongUsageException("commands.debug.usage", new Object[0]);
    062        }
    063
    064        private void saveProfilerResults(long par1, int par3)
    065        {
    066            File var4 = new File(MinecraftServer.getServer().getFile("debug"), "profile-results-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + ".txt");
    067            var4.getParentFile().mkdirs();
    068
    069            try
    070            {
    071                FileWriter var5 = new FileWriter(var4);
    072                var5.write(this.getProfilerResults(par1, par3));
    073                var5.close();
    074            }
    075            catch (Throwable var6)
    076            {
    077                Logger.getLogger("Minecraft").log(Level.SEVERE, "Could not save profiler results to " + var4, var6);
    078            }
    079        }
    080
    081        private String getProfilerResults(long par1, int par3)
    082        {
    083            StringBuilder var4 = new StringBuilder();
    084            var4.append("---- Minecraft Profiler Results ----\n");
    085            var4.append("// ");
    086            var4.append(getWittyComment());
    087            var4.append("\n\n");
    088            var4.append("Time span: ").append(par1).append(" ms\n");
    089            var4.append("Tick span: ").append(par3).append(" ticks\n");
    090            var4.append("// This is approximately ").append(String.format("%.2f", new Object[] {Float.valueOf((float)par3 / ((float)par1 / 1000.0F))})).append(" ticks per second. It should be ").append(20).append(" ticks per second\n\n");
    091            var4.append("--- BEGIN PROFILE DUMP ---\n\n");
    092            this.getProfileDump(0, "root", var4);
    093            var4.append("--- END PROFILE DUMP ---\n\n");
    094            return var4.toString();
    095        }
    096
    097        private void getProfileDump(int par1, String par2Str, StringBuilder par3StringBuilder)
    098        {
    099            List var4 = MinecraftServer.getServer().theProfiler.getProfilingData(par2Str);
    100
    101            if (var4 != null && var4.size() >= 3)
    102            {
    103                for (int var5 = 1; var5 < var4.size(); ++var5)
    104                {
    105                    ProfilerResult var6 = (ProfilerResult)var4.get(var5);
    106                    par3StringBuilder.append(String.format("[%02d] ", new Object[] {Integer.valueOf(par1)}));
    107
    108                    for (int var7 = 0; var7 < par1; ++var7)
    109                    {
    110                        par3StringBuilder.append(" ");
    111                    }
    112
    113                    par3StringBuilder.append(var6.field_76331_c);
    114                    par3StringBuilder.append(" - ");
    115                    par3StringBuilder.append(String.format("%.2f", new Object[] {Double.valueOf(var6.field_76332_a)}));
    116                    par3StringBuilder.append("%/");
    117                    par3StringBuilder.append(String.format("%.2f", new Object[] {Double.valueOf(var6.field_76330_b)}));
    118                    par3StringBuilder.append("%\n");
    119
    120                    if (!var6.field_76331_c.equals("unspecified"))
    121                    {
    122                        try
    123                        {
    124                            this.getProfileDump(par1 + 1, par2Str + "." + var6.field_76331_c, par3StringBuilder);
    125                        }
    126                        catch (Exception var8)
    127                        {
    128                            par3StringBuilder.append("[[ EXCEPTION " + var8 + " ]]");
    129                        }
    130                    }
    131                }
    132            }
    133        }
    134
    135        /**
    136         * Returns a random "witty" comment.
    137         */
    138        private static String getWittyComment()
    139        {
    140            String[] var0 = new String[] {"Shiny numbers!", "Am I not running fast enough? :(", "I\'m working as hard as I can!", "Will I ever be good enough for you? :(", "Speedy. Zoooooom!", "Hello world", "40% better than a crash report.", "Now with extra numbers", "Now with less numbers", "Now with the same numbers", "You should add flames to things, it makes them go faster!", "Do you feel the need for... optimization?", "*cracks redstone whip*", "Maybe if you treated it better then it\'ll have more motivation to work faster! Poor server."};
    141
    142            try
    143            {
    144                return var0[(int)(System.nanoTime() % (long)var0.length)];
    145            }
    146            catch (Throwable var2)
    147            {
    148                return "Witty comment unavailable :(";
    149            }
    150        }
    151
    152        /**
    153         * Adds the strings available in this command to the given list of tab completion options.
    154         */
    155        public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr)
    156        {
    157            return par2ArrayOfStr.length == 1 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] {"start", "stop"}): null;
    158        }
    159    }