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 //BugFix: Causes AIOOB for stacks < 3 + par1 134 int len = astacktraceelement.length - 3 - par1; 135 if (len <= 0) len = astacktraceelement.length; 136 this.stackTrace = new StackTraceElement[len]; 137 System.arraycopy(astacktraceelement, astacktraceelement.length - len, this.stackTrace, 0, this.stackTrace.length); 138 return this.stackTrace.length; 139 } 140 141 public boolean func_85069_a(StackTraceElement par1StackTraceElement, StackTraceElement par2StackTraceElement) 142 { 143 if (this.stackTrace.length != 0 && par1StackTraceElement != null) 144 { 145 StackTraceElement stacktraceelement2 = this.stackTrace[0]; 146 147 if (stacktraceelement2.isNativeMethod() == par1StackTraceElement.isNativeMethod() && stacktraceelement2.getClassName().equals(par1StackTraceElement.getClassName()) && stacktraceelement2.getFileName().equals(par1StackTraceElement.getFileName()) && stacktraceelement2.getMethodName().equals(par1StackTraceElement.getMethodName())) 148 { 149 if (par2StackTraceElement != null != this.stackTrace.length > 1) 150 { 151 return false; 152 } 153 else if (par2StackTraceElement != null && !this.stackTrace[1].equals(par2StackTraceElement)) 154 { 155 return false; 156 } 157 else 158 { 159 this.stackTrace[0] = par1StackTraceElement; 160 return true; 161 } 162 } 163 else 164 { 165 return false; 166 } 167 } 168 else 169 { 170 return false; 171 } 172 } 173 174 public void func_85070_b(int par1) 175 { 176 StackTraceElement[] astacktraceelement = new StackTraceElement[this.stackTrace.length - par1]; 177 System.arraycopy(this.stackTrace, 0, astacktraceelement, 0, astacktraceelement.length); 178 this.stackTrace = astacktraceelement; 179 } 180 181 public void func_85072_a(StringBuilder par1StringBuilder) 182 { 183 par1StringBuilder.append("-- ").append(this.field_85076_b).append(" --\n"); 184 par1StringBuilder.append("Details:"); 185 Iterator iterator = this.field_85077_c.iterator(); 186 187 while (iterator.hasNext()) 188 { 189 CrashReportCategoryEntry crashreportcategoryentry = (CrashReportCategoryEntry)iterator.next(); 190 par1StringBuilder.append("\n\t"); 191 par1StringBuilder.append(crashreportcategoryentry.func_85089_a()); 192 par1StringBuilder.append(": "); 193 par1StringBuilder.append(crashreportcategoryentry.func_85090_b()); 194 } 195 196 if (this.stackTrace != null && this.stackTrace.length > 0) 197 { 198 par1StringBuilder.append("\nStacktrace:"); 199 StackTraceElement[] astacktraceelement = this.stackTrace; 200 int i = astacktraceelement.length; 201 202 for (int j = 0; j < i; ++j) 203 { 204 StackTraceElement stacktraceelement = astacktraceelement[j]; 205 par1StringBuilder.append("\n\tat "); 206 par1StringBuilder.append(stacktraceelement.toString()); 207 } 208 } 209 } 210 211 public static void func_85068_a(CrashReportCategory par0CrashReportCategory, int par1, int par2, int par3, int par4, int par5) 212 { 213 par0CrashReportCategory.addCrashSectionCallable("Block type", new CallableBlockType(par4)); 214 par0CrashReportCategory.addCrashSectionCallable("Block data value", new CallableBlockDataValue(par5)); 215 par0CrashReportCategory.addCrashSectionCallable("Block location", new CallableBlockLocation(par1, par2, par3)); 216 } 217}