001package net.minecraft.crash; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.ArrayList; 006import java.util.Iterator; 007import java.util.List; 008import java.util.concurrent.Callable; 009import net.minecraft.util.MathHelper; 010 011public class CrashReportCategory 012{ 013 private final CrashReport theCrashReport; 014 private final String field_85076_b; 015 private final List field_85077_c = new ArrayList(); 016 private StackTraceElement[] stackTrace = new StackTraceElement[0]; 017 018 public CrashReportCategory(CrashReport par1CrashReport, String par2Str) 019 { 020 this.theCrashReport = par1CrashReport; 021 this.field_85076_b = par2Str; 022 } 023 024 @SideOnly(Side.CLIENT) 025 public static String func_85074_a(double par0, double par2, double par4) 026 { 027 return String.format("%.2f,%.2f,%.2f - %s", new Object[] {Double.valueOf(par0), Double.valueOf(par2), Double.valueOf(par4), getLocationInfo(MathHelper.floor_double(par0), MathHelper.floor_double(par2), MathHelper.floor_double(par4))}); 028 } 029 030 /** 031 * Returns a string with world information on location.Args:x,y,z 032 */ 033 public static String getLocationInfo(int par0, int par1, int par2) 034 { 035 StringBuilder stringbuilder = new StringBuilder(); 036 037 try 038 { 039 stringbuilder.append(String.format("World: (%d,%d,%d)", new Object[] {Integer.valueOf(par0), Integer.valueOf(par1), Integer.valueOf(par2)})); 040 } 041 catch (Throwable throwable) 042 { 043 stringbuilder.append("(Error finding world loc)"); 044 } 045 046 stringbuilder.append(", "); 047 int l; 048 int i1; 049 int j1; 050 int k1; 051 int l1; 052 int i2; 053 int j2; 054 int k2; 055 int l2; 056 057 try 058 { 059 l = par0 >> 4; 060 i1 = par2 >> 4; 061 j1 = par0 & 15; 062 k1 = par1 >> 4; 063 l1 = par2 & 15; 064 i2 = l << 4; 065 j2 = i1 << 4; 066 k2 = (l + 1 << 4) - 1; 067 l2 = (i1 + 1 << 4) - 1; 068 stringbuilder.append(String.format("Chunk: (at %d,%d,%d in %d,%d; contains blocks %d,0,%d to %d,255,%d)", new Object[] {Integer.valueOf(j1), Integer.valueOf(k1), Integer.valueOf(l1), Integer.valueOf(l), Integer.valueOf(i1), Integer.valueOf(i2), Integer.valueOf(j2), Integer.valueOf(k2), Integer.valueOf(l2)})); 069 } 070 catch (Throwable throwable1) 071 { 072 stringbuilder.append("(Error finding chunk loc)"); 073 } 074 075 stringbuilder.append(", "); 076 077 try 078 { 079 l = par0 >> 9; 080 i1 = par2 >> 9; 081 j1 = l << 5; 082 k1 = i1 << 5; 083 l1 = (l + 1 << 5) - 1; 084 i2 = (i1 + 1 << 5) - 1; 085 j2 = l << 9; 086 k2 = i1 << 9; 087 l2 = (l + 1 << 9) - 1; 088 int i3 = (i1 + 1 << 9) - 1; 089 stringbuilder.append(String.format("Region: (%d,%d; contains chunks %d,%d to %d,%d, blocks %d,0,%d to %d,255,%d)", new Object[] {Integer.valueOf(l), Integer.valueOf(i1), Integer.valueOf(j1), Integer.valueOf(k1), Integer.valueOf(l1), Integer.valueOf(i2), Integer.valueOf(j2), Integer.valueOf(k2), Integer.valueOf(l2), Integer.valueOf(i3)})); 090 } 091 catch (Throwable throwable2) 092 { 093 stringbuilder.append("(Error finding world loc)"); 094 } 095 096 return stringbuilder.toString(); 097 } 098 099 /** 100 * Adds a Crashreport section with the given name with the value set to the result of the given Callable; 101 */ 102 public void addCrashSectionCallable(String par1Str, Callable par2Callable) 103 { 104 try 105 { 106 this.addCrashSection(par1Str, par2Callable.call()); 107 } 108 catch (Throwable throwable) 109 { 110 this.addCrashSectionThrowable(par1Str, throwable); 111 } 112 } 113 114 /** 115 * Adds a Crashreport section with the given name with the given value (convered .toString()) 116 */ 117 public void addCrashSection(String par1Str, Object par2Obj) 118 { 119 this.field_85077_c.add(new CrashReportCategoryEntry(par1Str, par2Obj)); 120 } 121 122 /** 123 * Adds a Crashreport section with the given name with the given Throwable 124 */ 125 public void addCrashSectionThrowable(String par1Str, Throwable par2Throwable) 126 { 127 this.addCrashSection(par1Str, par2Throwable); 128 } 129 130 public int func_85073_a(int par1) 131 { 132 StackTraceElement[] astacktraceelement = Thread.currentThread().getStackTrace(); 133 this.stackTrace = new StackTraceElement[astacktraceelement.length - 3 - par1]; 134 System.arraycopy(astacktraceelement, 3 + par1, this.stackTrace, 0, this.stackTrace.length); 135 return this.stackTrace.length; 136 } 137 138 public boolean func_85069_a(StackTraceElement par1StackTraceElement, StackTraceElement par2StackTraceElement) 139 { 140 if (this.stackTrace.length != 0 && par1StackTraceElement != null) 141 { 142 StackTraceElement stacktraceelement2 = this.stackTrace[0]; 143 144 if (stacktraceelement2.isNativeMethod() == par1StackTraceElement.isNativeMethod() && stacktraceelement2.getClassName().equals(par1StackTraceElement.getClassName()) && stacktraceelement2.getFileName().equals(par1StackTraceElement.getFileName()) && stacktraceelement2.getMethodName().equals(par1StackTraceElement.getMethodName())) 145 { 146 if (par2StackTraceElement != null != this.stackTrace.length > 1) 147 { 148 return false; 149 } 150 else if (par2StackTraceElement != null && !this.stackTrace[1].equals(par2StackTraceElement)) 151 { 152 return false; 153 } 154 else 155 { 156 this.stackTrace[0] = par1StackTraceElement; 157 return true; 158 } 159 } 160 else 161 { 162 return false; 163 } 164 } 165 else 166 { 167 return false; 168 } 169 } 170 171 public void func_85070_b(int par1) 172 { 173 StackTraceElement[] astacktraceelement = new StackTraceElement[this.stackTrace.length - par1]; 174 System.arraycopy(this.stackTrace, 0, astacktraceelement, 0, astacktraceelement.length); 175 this.stackTrace = astacktraceelement; 176 } 177 178 public void func_85072_a(StringBuilder par1StringBuilder) 179 { 180 par1StringBuilder.append("-- ").append(this.field_85076_b).append(" --\n"); 181 par1StringBuilder.append("Details:"); 182 Iterator iterator = this.field_85077_c.iterator(); 183 184 while (iterator.hasNext()) 185 { 186 CrashReportCategoryEntry crashreportcategoryentry = (CrashReportCategoryEntry)iterator.next(); 187 par1StringBuilder.append("\n\t"); 188 par1StringBuilder.append(crashreportcategoryentry.func_85089_a()); 189 par1StringBuilder.append(": "); 190 par1StringBuilder.append(crashreportcategoryentry.func_85090_b()); 191 } 192 193 if (this.stackTrace != null && this.stackTrace.length > 0) 194 { 195 par1StringBuilder.append("\nStacktrace:"); 196 StackTraceElement[] astacktraceelement = this.stackTrace; 197 int i = astacktraceelement.length; 198 199 for (int j = 0; j < i; ++j) 200 { 201 StackTraceElement stacktraceelement = astacktraceelement[j]; 202 par1StringBuilder.append("\n\tat "); 203 par1StringBuilder.append(stacktraceelement.toString()); 204 } 205 } 206 } 207 208 public static void func_85068_a(CrashReportCategory par0CrashReportCategory, int par1, int par2, int par3, int par4, int par5) 209 { 210 par0CrashReportCategory.addCrashSectionCallable("Block type", new CallableBlockType(par4)); 211 par0CrashReportCategory.addCrashSectionCallable("Block data value", new CallableBlockDataValue(par5)); 212 par0CrashReportCategory.addCrashSectionCallable("Block location", new CallableBlockLocation(par1, par2, par3)); 213 } 214}