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