improved crash reports more
This commit is contained in:
parent
31fd9ef2b1
commit
60896b7a30
|
@ -2,12 +2,12 @@ package net.lax1dude.eaglercraft;
|
|||
|
||||
import static org.teavm.jso.webgl.WebGLRenderingContext.*;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSExceptions;
|
||||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.browser.Window;
|
||||
import org.teavm.jso.core.JSError;
|
||||
import org.teavm.jso.dom.html.HTMLCanvasElement;
|
||||
|
@ -70,23 +70,23 @@ public class Client {
|
|||
}
|
||||
String serverWorkerURI = conf.optString("serverWorkerURI", null);
|
||||
EaglerAdapterImpl2.setWorldDatabaseName(conf.optString("worldsFolder", "MAIN"));
|
||||
|
||||
registerErrorHandler();
|
||||
|
||||
try {
|
||||
|
||||
EaglerAdapterImpl2.initializeContext(rootElement, assetsURI, serverWorkerURI);
|
||||
|
||||
ServerList.loadDefaultServers(conf);
|
||||
AssetRepository.loadOverrides(conf);
|
||||
LocalStorageManager.loadStorage();
|
||||
|
||||
run0();
|
||||
|
||||
}catch(Throwable t) {
|
||||
StringWriter s = new StringWriter();
|
||||
t.printStackTrace(new PrintWriter(s));
|
||||
showCrashScreen(s.toString());
|
||||
showCrashScreen(t.toString() + "\n\n" + getStackTrace(t));
|
||||
return;
|
||||
}
|
||||
|
||||
registerErrorHandler();
|
||||
ServerList.loadDefaultServers(conf);
|
||||
AssetRepository.loadOverrides(conf);
|
||||
LocalStorageManager.loadStorage();
|
||||
|
||||
run0();
|
||||
|
||||
}
|
||||
|
||||
private static void oldMain() {
|
||||
|
@ -100,23 +100,37 @@ public class Client {
|
|||
crashScreenOptsDump += "\"" + sh + "\"";
|
||||
}
|
||||
crashScreenOptsDump += " ]";
|
||||
|
||||
registerErrorHandler();
|
||||
|
||||
try {
|
||||
|
||||
EaglerAdapterImpl2.initializeContext(rootElement = Window.current().getDocument().getElementById(e[0]), e[1], "worker_bootstrap.js");
|
||||
|
||||
LocalStorageManager.loadStorage();
|
||||
if(e.length > 2 && e[2].length() > 0) {
|
||||
ServerList.loadDefaultServers(e[2]);
|
||||
}
|
||||
if(e.length > 3) {
|
||||
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[3]);
|
||||
}
|
||||
|
||||
run0();
|
||||
|
||||
}catch(Throwable t) {
|
||||
StringWriter s = new StringWriter();
|
||||
t.printStackTrace(new PrintWriter(s));
|
||||
showCrashScreen(s.toString());
|
||||
showCrashScreen(t.toString() + "\n\n" + getStackTrace(t));
|
||||
return;
|
||||
}
|
||||
registerErrorHandler();
|
||||
LocalStorageManager.loadStorage();
|
||||
if(e.length > 2 && e[2].length() > 0) {
|
||||
ServerList.loadDefaultServers(e[2]);
|
||||
}
|
||||
|
||||
private static String getStackTrace(Throwable t) {
|
||||
JSObject obj = JSExceptions.getJSException(t);
|
||||
if(obj != null) {
|
||||
JSError err = (JSError)obj;
|
||||
return err.getStack() == null ? "[no stack trace]" : err.getStack();
|
||||
}else {
|
||||
return "[no stack trace]";
|
||||
}
|
||||
if(e.length > 3) {
|
||||
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[3]);
|
||||
}
|
||||
run0();
|
||||
}
|
||||
|
||||
private static void run0() {
|
||||
|
@ -131,29 +145,51 @@ public class Client {
|
|||
|
||||
@JSBody(params = { }, script = "return window.minecraftOpts;")
|
||||
public static native String[] getOpts();
|
||||
|
||||
public static void registerErrorHandler() {
|
||||
setWindowErrorHandler(new WindowErrorHandler() {
|
||||
|
||||
@JSBody(params = { }, script = "window.minecraftError = null; window.onerror = function(message, file, line, column, errorObj) { if(errorObj) { window.minecraftError = errorObj; window.minecraftErrorL = \"\"+line+\":\"+column; javaMethods.get(\"net.lax1dude.eaglercraft.Client.handleNativeError()V\").invoke(); } else { alert(\"a native browser exception was thrown but your browser does not support fith argument in onerror\"); } };")
|
||||
public static native void registerErrorHandler();
|
||||
|
||||
@JSBody(params = { }, script = "return window.minecraftError;")
|
||||
public static native JSError getWindowError();
|
||||
|
||||
@JSBody(params = { }, script = "return window.minecraftErrorL;")
|
||||
public static native String getWindowErrorL();
|
||||
|
||||
public static void handleNativeError() {
|
||||
JSError e = getWindowError();
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("Native Browser Exception\n");
|
||||
str.append("----------------------------------\n");
|
||||
str.append(" Line: ").append(getWindowErrorL()).append('\n');
|
||||
str.append(" Type: ").append(e.getName()).append('\n');
|
||||
str.append(" Message: ").append(e.getMessage()).append('\n');
|
||||
str.append("----------------------------------\n\n");
|
||||
str.append(e.getStack()).append('\n');
|
||||
showCrashScreen(str.toString());
|
||||
@Override
|
||||
public void call(String message, String file, int line, int col, JSError error) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
str.append("Native Browser Exception\n");
|
||||
str.append("----------------------------------\n");
|
||||
str.append(" Line: ").append((file == null ? "unknown" : file) + ":" + line + ":" + col).append('\n');
|
||||
str.append(" Type: ").append(error == null ? "generic" : error.getName()).append('\n');
|
||||
|
||||
if(error != null) {
|
||||
str.append(" Desc: ").append(error.getMessage() == null ? "null" : error.getMessage()).append('\n');
|
||||
}
|
||||
|
||||
if(message != null) {
|
||||
if(error == null || error.getMessage() == null || !message.endsWith(error.getMessage())) {
|
||||
str.append(" Desc: ").append(message).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
str.append("----------------------------------\n\n");
|
||||
str.append(error.getStack() == null ? "No stack trace is available" : error.getStack()).append('\n');
|
||||
|
||||
showCrashScreen(str.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@JSFunctor
|
||||
private static interface WindowErrorHandler extends JSObject {
|
||||
void call(String message, String file, int line, int col, JSError error);
|
||||
}
|
||||
|
||||
@JSBody(params = { "handler" }, script = "window.addEventListener(\"error\", function(e) { handler("
|
||||
+ "(typeof e.message === \"string\") ? e.message : null,"
|
||||
+ "(typeof e.filename === \"string\") ? e.filename : null,"
|
||||
+ "(typeof e.lineno === \"number\") ? e.lineno : 0,"
|
||||
+ "(typeof e.colno === \"number\") ? e.colno : 0,"
|
||||
+ "(typeof e.error === \"undefined\") ? null : e.error); });")
|
||||
public static native void setWindowErrorHandler(WindowErrorHandler handler);
|
||||
|
||||
private static boolean isCrashed = false;
|
||||
|
||||
private static void showCrashScreen(String t) {
|
||||
|
@ -166,7 +202,7 @@ public class Client {
|
|||
str.append('\n').append('\n');
|
||||
str.append("eaglercraft.version = \"").append(ConfigConstants.version).append("\"\n");
|
||||
str.append("eaglercraft.minecraft = \"1.5.2\"\n");
|
||||
str.append("eaglercraft.brand = \"eagtek\"\n");
|
||||
str.append("eaglercraft.brand = \"lax1dude\"\n");
|
||||
str.append("eaglercraft.username = \"").append(EaglerProfile.username).append("\"\n");
|
||||
str.append('\n');
|
||||
str.append(addWebGLToCrash());
|
||||
|
@ -193,8 +229,6 @@ public class Client {
|
|||
addDebugScreen(str, "colorDepth");
|
||||
addDebugScreen(str, "pixelDepth");
|
||||
str.append('\n');
|
||||
addDebug(str, "currentContext");
|
||||
str.append('\n');
|
||||
addDebugLocation(str, "href");
|
||||
str.append("\n----- Begin Minecraft Config -----\n");
|
||||
str.append(LocalStorageManager.dumpConfiguration());
|
||||
|
@ -221,14 +255,14 @@ public class Client {
|
|||
private static String addWebGLToCrash() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
||||
|
||||
cvs.setWidth(64);
|
||||
cvs.setHeight(64);
|
||||
|
||||
WebGLRenderingContext ctx = EaglerAdapterImpl2.webgl;
|
||||
|
||||
if(ctx == null) {
|
||||
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
||||
|
||||
cvs.setWidth(64);
|
||||
cvs.setHeight(64);
|
||||
|
||||
ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
||||
}
|
||||
|
||||
|
@ -236,8 +270,14 @@ public class Client {
|
|||
if(EaglerAdapterImpl2.webgl != null) {
|
||||
ret.append("webgl.version = ").append(ctx.getParameterString(VERSION)).append('\n');
|
||||
}
|
||||
ret.append("webgl.renderer = ").append(ctx.getParameterString(RENDERER)).append('\n');
|
||||
ret.append("webgl.vendor = ").append(ctx.getParameterString(VENDOR)).append('\n');
|
||||
if(ctx.getExtension("WEBGL_debug_renderer_info") != null) {
|
||||
ret.append("webgl.renderer = ").append(ctx.getParameterString(/* UNMASKED_RENDERER_WEBGL */ 0x9246)).append('\n');
|
||||
ret.append("webgl.vendor = ").append(ctx.getParameterString(/* UNMASKED_VENDOR_WEBGL */ 0x9245)).append('\n');
|
||||
}else {
|
||||
ret.append("webgl.renderer = ").append("" + ctx.getParameterString(RENDERER) + " [masked]").append('\n');
|
||||
ret.append("webgl.vendor = ").append("" + ctx.getParameterString(VENDOR) + " [masked]").append('\n');
|
||||
}
|
||||
ret.append("\nwebgl.anisotropicGlitch = ").append(DetectAnisotropicGlitch.hasGlitch()).append('\n');
|
||||
}else {
|
||||
ret.append("Failed to query GPU info!\n");
|
||||
}
|
||||
|
@ -292,7 +332,15 @@ public class Client {
|
|||
WebGLRenderingContext ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
||||
|
||||
if(ctx != null) {
|
||||
String r = ctx.getParameterString(RENDERER);
|
||||
String r;
|
||||
if(ctx.getExtension("WEBGL_debug_renderer_info") != null) {
|
||||
r = ctx.getParameterString(/* UNMASKED_RENDERER_WEBGL */ 0x9246);
|
||||
}else {
|
||||
r = ctx.getParameterString(RENDERER);
|
||||
if(r != null) {
|
||||
r += " [masked]";
|
||||
}
|
||||
}
|
||||
if(r != null) {
|
||||
webGLRenderer = r;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,19 @@ import net.lax1dude.eaglercraft.adapter.teavm.WebGLVertexArray;
|
|||
import org.teavm.jso.webgl.*;
|
||||
|
||||
public class DetectAnisotropicGlitch {
|
||||
|
||||
private static boolean known = false;
|
||||
private static boolean detected = false;
|
||||
|
||||
public static boolean detectGlitch() {
|
||||
public static boolean hasGlitch() {
|
||||
if(!known) {
|
||||
detected = detect();
|
||||
known = true;
|
||||
}
|
||||
return detected;
|
||||
}
|
||||
|
||||
public static boolean detect() {
|
||||
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
||||
|
||||
cvs.setWidth(400);
|
||||
|
|
|
@ -1032,7 +1032,7 @@ public class EaglerAdapterImpl2 {
|
|||
return getNavString("platform").toLowerCase().contains("win");
|
||||
}
|
||||
public static final boolean glNeedsAnisotropicFix() {
|
||||
return anisotropicFilteringSupported && DetectAnisotropicGlitch.detectGlitch();
|
||||
return anisotropicFilteringSupported && DetectAnisotropicGlitch.hasGlitch();
|
||||
}
|
||||
|
||||
private static HTMLCanvasElement imageLoadCanvas = null;
|
||||
|
@ -1076,13 +1076,15 @@ public class EaglerAdapterImpl2 {
|
|||
Uint8ClampedArray pxls = pxlsDat.getData();
|
||||
int totalPixels = pxlsDat.getWidth() * pxlsDat.getHeight();
|
||||
freeDataURL(toLoad.getSrc());
|
||||
if(pxls.getByteLength() < totalPixels * 4) {
|
||||
if(pxls.getByteLength() < totalPixels << 2) {
|
||||
ret.complete(null);
|
||||
return;
|
||||
}
|
||||
DataView dv = DataView.create(pxls.getBuffer());
|
||||
int[] pixels = new int[totalPixels];
|
||||
for(int i = 0; i < pixels.length; ++i) {
|
||||
pixels[i] = (pxls.get(i * 4) << 16) | (pxls.get(i * 4 + 1) << 8) | pxls.get(i * 4 + 2) | (pxls.get(i * 4 + 3) << 24);
|
||||
for(int i = 0, j; i < pixels.length; ++i) {
|
||||
j = dv.getUint32(i << 2, false);
|
||||
pixels[i] = (j >> 8) | ((j & 0xFF) << 24);
|
||||
}
|
||||
ret.complete(new EaglerImage(pixels, pxlsDat.getWidth(), pxlsDat.getHeight(), true));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user