    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 void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr)
    026        {
    027            if (par2ArrayOfStr.length == 1)
    028            {
    029                if (par2ArrayOfStr[0].equals("start"))
    030                {
    031                    notifyAdmins(par1ICommandSender, "commands.debug.start", new Object[0]);
    032                    MinecraftServer.getServer().enableProfiling();
    033                    this.startTime = System.currentTimeMillis();
    034                    this.startTicks = MinecraftServer.getServer().getTickCounter();
    035                    return;
    036                }
    037
    038                if (par2ArrayOfStr[0].equals("stop"))
    039                {
    040                    if (!MinecraftServer.getServer().theProfiler.profilingEnabled)
    041                    {
    042                        throw new CommandException("commands.debug.notStarted", new Object[0]);
    043                    }
    044
    045                    long var3 = System.currentTimeMillis();
    046                    int var5 = MinecraftServer.getServer().getTickCounter();
    047                    long var6 = var3 - this.startTime;
    048                    int var8 = var5 - this.startTicks;
    049                    this.saveProfilerResults(var6, var8);
    050                    MinecraftServer.getServer().theProfiler.profilingEnabled = false;
    051                    notifyAdmins(par1ICommandSender, "commands.debug.stop", new Object[] {Float.valueOf((float)var6 / 1000.0F), Integer.valueOf(var8)});
    052                    return;
    053                }
    054            }
    055
    056            throw new WrongUsageException("commands.debug.usage", new Object[0]);
    057        }
    058
    059        private void saveProfilerResults(long par1, int par3)
    060        {
    061            File var4 = new File(MinecraftServer.getServer().getFile("debug"), "profile-results-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + ".txt");
    062            var4.getParentFile().mkdirs();
    063
    064            try
    065            {
    066                FileWriter var5 = new FileWriter(var4);
    067                var5.write(this.getProfilerResults(par1, par3));
    068                var5.close();
    069            }
    070            catch (Throwable var6)
    071            {
    072                Logger.getLogger("Minecraft").log(Level.SEVERE, "Could not save profiler results to " + var4, var6);
    073            }
    074        }
    075
    076        private String getProfilerResults(long par1, int par3)
    077        {
    078            StringBuilder var4 = new StringBuilder();
    079            var4.append("---- Minecraft Profiler Results ----\n");
    080            var4.append("// ");
    081            var4.append(getWittyComment());
    082            var4.append("\n\n");
    083            var4.append("Time span: ").append(par1).append(" ms\n");
    084            var4.append("Tick span: ").append(par3).append(" ticks\n");
    085            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");
    086            var4.append("--- BEGIN PROFILE DUMP ---\n\n");
    087            this.getProfileDump(0, "root", var4);
    088            var4.append("--- END PROFILE DUMP ---\n\n");
    089            return var4.toString();
    090        }
    091
    092        private void getProfileDump(int par1, String par2Str, StringBuilder par3StringBuilder)
    093        {
    094            List var4 = MinecraftServer.getServer().theProfiler.getProfilingData(par2Str);
    095
    096            if (var4 != null && var4.size() >= 3)
    097            {
    098                for (int var5 = 1; var5 < var4.size(); ++var5)
    099                {
    100                    ProfilerResult var6 = (ProfilerResult)var4.get(var5);
    101                    par3StringBuilder.append(String.format("[%02d] ", new Object[] {Integer.valueOf(par1)}));
    102
    103                    for (int var7 = 0; var7 < par1; ++var7)
    104                    {
    105                        par3StringBuilder.append(" ");
    106                    }
    107
    108                    par3StringBuilder.append(var6.field_76331_c);
    109                    par3StringBuilder.append(" - ");
    110                    par3StringBuilder.append(String.format("%.2f", new Object[] {Double.valueOf(var6.field_76332_a)}));
    111                    par3StringBuilder.append("%/");
    112                    par3StringBuilder.append(String.format("%.2f", new Object[] {Double.valueOf(var6.field_76330_b)}));
    113                    par3StringBuilder.append("%\n");
    114
    115                    if (!var6.field_76331_c.equals("unspecified"))
    116                    {
    117                        try
    118                        {
    119                            this.getProfileDump(par1 + 1, par2Str + "." + var6.field_76331_c, par3StringBuilder);
    120                        }
    121                        catch (Exception var8)
    122                        {
    123                            par3StringBuilder.append("[[ EXCEPTION " + var8 + " ]]");
    124                        }
    125                    }
    126                }
    127            }
    128        }
    129
    130        /**
    131         * Returns a random "witty" comment.
    132         */
    133        private static String getWittyComment()
    134        {
    135            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."};
    136
    137            try
    138            {
    139                return var0[(int)(System.nanoTime() % (long)var0.length)];
    140            }
    141            catch (Throwable var2)
    142            {
    143                return "Witty comment unavailable :(";
    144            }
    145        }
    146
    147        /**
    148         * Adds the strings available in this command to the given list of tab completion options.
    149         */
    150        public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr)
    151        {
    152            return par2ArrayOfStr.length == 1 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] {"start", "stop"}): null;
    153        }
    154    }