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 }