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, 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}