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 static org.teavm.jso.webgl.WebGLRenderingContext.*;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.teavm.jso.JSBody;
|
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.browser.Window;
|
||||||
import org.teavm.jso.core.JSError;
|
import org.teavm.jso.core.JSError;
|
||||||
import org.teavm.jso.dom.html.HTMLCanvasElement;
|
import org.teavm.jso.dom.html.HTMLCanvasElement;
|
||||||
|
@ -71,22 +71,22 @@ public class Client {
|
||||||
String serverWorkerURI = conf.optString("serverWorkerURI", null);
|
String serverWorkerURI = conf.optString("serverWorkerURI", null);
|
||||||
EaglerAdapterImpl2.setWorldDatabaseName(conf.optString("worldsFolder", "MAIN"));
|
EaglerAdapterImpl2.setWorldDatabaseName(conf.optString("worldsFolder", "MAIN"));
|
||||||
|
|
||||||
try {
|
|
||||||
EaglerAdapterImpl2.initializeContext(rootElement, assetsURI, serverWorkerURI);
|
|
||||||
}catch(Throwable t) {
|
|
||||||
StringWriter s = new StringWriter();
|
|
||||||
t.printStackTrace(new PrintWriter(s));
|
|
||||||
showCrashScreen(s.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
registerErrorHandler();
|
registerErrorHandler();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
EaglerAdapterImpl2.initializeContext(rootElement, assetsURI, serverWorkerURI);
|
||||||
|
|
||||||
ServerList.loadDefaultServers(conf);
|
ServerList.loadDefaultServers(conf);
|
||||||
AssetRepository.loadOverrides(conf);
|
AssetRepository.loadOverrides(conf);
|
||||||
LocalStorageManager.loadStorage();
|
LocalStorageManager.loadStorage();
|
||||||
|
|
||||||
run0();
|
run0();
|
||||||
|
|
||||||
|
}catch(Throwable t) {
|
||||||
|
showCrashScreen(t.toString() + "\n\n" + getStackTrace(t));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void oldMain() {
|
private static void oldMain() {
|
||||||
|
@ -100,15 +100,13 @@ public class Client {
|
||||||
crashScreenOptsDump += "\"" + sh + "\"";
|
crashScreenOptsDump += "\"" + sh + "\"";
|
||||||
}
|
}
|
||||||
crashScreenOptsDump += " ]";
|
crashScreenOptsDump += " ]";
|
||||||
try {
|
|
||||||
EaglerAdapterImpl2.initializeContext(rootElement = Window.current().getDocument().getElementById(e[0]), e[1], "worker_bootstrap.js");
|
|
||||||
}catch(Throwable t) {
|
|
||||||
StringWriter s = new StringWriter();
|
|
||||||
t.printStackTrace(new PrintWriter(s));
|
|
||||||
showCrashScreen(s.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
registerErrorHandler();
|
registerErrorHandler();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
EaglerAdapterImpl2.initializeContext(rootElement = Window.current().getDocument().getElementById(e[0]), e[1], "worker_bootstrap.js");
|
||||||
|
|
||||||
LocalStorageManager.loadStorage();
|
LocalStorageManager.loadStorage();
|
||||||
if(e.length > 2 && e[2].length() > 0) {
|
if(e.length > 2 && e[2].length() > 0) {
|
||||||
ServerList.loadDefaultServers(e[2]);
|
ServerList.loadDefaultServers(e[2]);
|
||||||
|
@ -116,7 +114,23 @@ public class Client {
|
||||||
if(e.length > 3) {
|
if(e.length > 3) {
|
||||||
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[3]);
|
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
run0();
|
run0();
|
||||||
|
|
||||||
|
}catch(Throwable t) {
|
||||||
|
showCrashScreen(t.toString() + "\n\n" + getStackTrace(t));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void run0() {
|
private static void run0() {
|
||||||
|
@ -132,28 +146,50 @@ public class Client {
|
||||||
@JSBody(params = { }, script = "return window.minecraftOpts;")
|
@JSBody(params = { }, script = "return window.minecraftOpts;")
|
||||||
public static native String[] getOpts();
|
public static native String[] getOpts();
|
||||||
|
|
||||||
@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 void registerErrorHandler() {
|
||||||
public static native void registerErrorHandler();
|
setWindowErrorHandler(new WindowErrorHandler() {
|
||||||
|
|
||||||
@JSBody(params = { }, script = "return window.minecraftError;")
|
@Override
|
||||||
public static native JSError getWindowError();
|
public void call(String message, String file, int line, int col, JSError error) {
|
||||||
|
|
||||||
@JSBody(params = { }, script = "return window.minecraftErrorL;")
|
|
||||||
public static native String getWindowErrorL();
|
|
||||||
|
|
||||||
public static void handleNativeError() {
|
|
||||||
JSError e = getWindowError();
|
|
||||||
StringBuilder str = new StringBuilder();
|
StringBuilder str = new StringBuilder();
|
||||||
|
|
||||||
str.append("Native Browser Exception\n");
|
str.append("Native Browser Exception\n");
|
||||||
str.append("----------------------------------\n");
|
str.append("----------------------------------\n");
|
||||||
str.append(" Line: ").append(getWindowErrorL()).append('\n');
|
str.append(" Line: ").append((file == null ? "unknown" : file) + ":" + line + ":" + col).append('\n');
|
||||||
str.append(" Type: ").append(e.getName()).append('\n');
|
str.append(" Type: ").append(error == null ? "generic" : error.getName()).append('\n');
|
||||||
str.append(" Message: ").append(e.getMessage()).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("----------------------------------\n\n");
|
||||||
str.append(e.getStack()).append('\n');
|
str.append(error.getStack() == null ? "No stack trace is available" : error.getStack()).append('\n');
|
||||||
|
|
||||||
showCrashScreen(str.toString());
|
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 boolean isCrashed = false;
|
||||||
|
|
||||||
private static void showCrashScreen(String t) {
|
private static void showCrashScreen(String t) {
|
||||||
|
@ -166,7 +202,7 @@ public class Client {
|
||||||
str.append('\n').append('\n');
|
str.append('\n').append('\n');
|
||||||
str.append("eaglercraft.version = \"").append(ConfigConstants.version).append("\"\n");
|
str.append("eaglercraft.version = \"").append(ConfigConstants.version).append("\"\n");
|
||||||
str.append("eaglercraft.minecraft = \"1.5.2\"\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("eaglercraft.username = \"").append(EaglerProfile.username).append("\"\n");
|
||||||
str.append('\n');
|
str.append('\n');
|
||||||
str.append(addWebGLToCrash());
|
str.append(addWebGLToCrash());
|
||||||
|
@ -193,8 +229,6 @@ public class Client {
|
||||||
addDebugScreen(str, "colorDepth");
|
addDebugScreen(str, "colorDepth");
|
||||||
addDebugScreen(str, "pixelDepth");
|
addDebugScreen(str, "pixelDepth");
|
||||||
str.append('\n');
|
str.append('\n');
|
||||||
addDebug(str, "currentContext");
|
|
||||||
str.append('\n');
|
|
||||||
addDebugLocation(str, "href");
|
addDebugLocation(str, "href");
|
||||||
str.append("\n----- Begin Minecraft Config -----\n");
|
str.append("\n----- Begin Minecraft Config -----\n");
|
||||||
str.append(LocalStorageManager.dumpConfiguration());
|
str.append(LocalStorageManager.dumpConfiguration());
|
||||||
|
@ -221,14 +255,14 @@ public class Client {
|
||||||
private static String addWebGLToCrash() {
|
private static String addWebGLToCrash() {
|
||||||
StringBuilder ret = new StringBuilder();
|
StringBuilder ret = new StringBuilder();
|
||||||
|
|
||||||
|
WebGLRenderingContext ctx = EaglerAdapterImpl2.webgl;
|
||||||
|
|
||||||
|
if(ctx == null) {
|
||||||
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
||||||
|
|
||||||
cvs.setWidth(64);
|
cvs.setWidth(64);
|
||||||
cvs.setHeight(64);
|
cvs.setHeight(64);
|
||||||
|
|
||||||
WebGLRenderingContext ctx = EaglerAdapterImpl2.webgl;
|
|
||||||
|
|
||||||
if(ctx == null) {
|
|
||||||
ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,8 +270,14 @@ public class Client {
|
||||||
if(EaglerAdapterImpl2.webgl != null) {
|
if(EaglerAdapterImpl2.webgl != null) {
|
||||||
ret.append("webgl.version = ").append(ctx.getParameterString(VERSION)).append('\n');
|
ret.append("webgl.version = ").append(ctx.getParameterString(VERSION)).append('\n');
|
||||||
}
|
}
|
||||||
ret.append("webgl.renderer = ").append(ctx.getParameterString(RENDERER)).append('\n');
|
if(ctx.getExtension("WEBGL_debug_renderer_info") != null) {
|
||||||
ret.append("webgl.vendor = ").append(ctx.getParameterString(VENDOR)).append('\n');
|
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 {
|
}else {
|
||||||
ret.append("Failed to query GPU info!\n");
|
ret.append("Failed to query GPU info!\n");
|
||||||
}
|
}
|
||||||
|
@ -292,7 +332,15 @@ public class Client {
|
||||||
WebGLRenderingContext ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
WebGLRenderingContext ctx = (WebGLRenderingContext)cvs.getContext("webgl");
|
||||||
|
|
||||||
if(ctx != null) {
|
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) {
|
if(r != null) {
|
||||||
webGLRenderer = r;
|
webGLRenderer = r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,18 @@ import org.teavm.jso.webgl.*;
|
||||||
|
|
||||||
public class DetectAnisotropicGlitch {
|
public class DetectAnisotropicGlitch {
|
||||||
|
|
||||||
public static boolean detectGlitch() {
|
private static boolean known = false;
|
||||||
|
private static boolean detected = false;
|
||||||
|
|
||||||
|
public static boolean hasGlitch() {
|
||||||
|
if(!known) {
|
||||||
|
detected = detect();
|
||||||
|
known = true;
|
||||||
|
}
|
||||||
|
return detected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean detect() {
|
||||||
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
|
||||||
|
|
||||||
cvs.setWidth(400);
|
cvs.setWidth(400);
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ public class EaglerAdapterImpl2 {
|
||||||
return getNavString("platform").toLowerCase().contains("win");
|
return getNavString("platform").toLowerCase().contains("win");
|
||||||
}
|
}
|
||||||
public static final boolean glNeedsAnisotropicFix() {
|
public static final boolean glNeedsAnisotropicFix() {
|
||||||
return anisotropicFilteringSupported && DetectAnisotropicGlitch.detectGlitch();
|
return anisotropicFilteringSupported && DetectAnisotropicGlitch.hasGlitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HTMLCanvasElement imageLoadCanvas = null;
|
private static HTMLCanvasElement imageLoadCanvas = null;
|
||||||
|
@ -1076,13 +1076,15 @@ public class EaglerAdapterImpl2 {
|
||||||
Uint8ClampedArray pxls = pxlsDat.getData();
|
Uint8ClampedArray pxls = pxlsDat.getData();
|
||||||
int totalPixels = pxlsDat.getWidth() * pxlsDat.getHeight();
|
int totalPixels = pxlsDat.getWidth() * pxlsDat.getHeight();
|
||||||
freeDataURL(toLoad.getSrc());
|
freeDataURL(toLoad.getSrc());
|
||||||
if(pxls.getByteLength() < totalPixels * 4) {
|
if(pxls.getByteLength() < totalPixels << 2) {
|
||||||
ret.complete(null);
|
ret.complete(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DataView dv = DataView.create(pxls.getBuffer());
|
||||||
int[] pixels = new int[totalPixels];
|
int[] pixels = new int[totalPixels];
|
||||||
for(int i = 0; i < pixels.length; ++i) {
|
for(int i = 0, j; 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);
|
j = dv.getUint32(i << 2, false);
|
||||||
|
pixels[i] = (j >> 8) | ((j & 0xFF) << 24);
|
||||||
}
|
}
|
||||||
ret.complete(new EaglerImage(pixels, pxlsDat.getWidth(), pxlsDat.getHeight(), true));
|
ret.complete(new EaglerImage(pixels, pxlsDat.getWidth(), pxlsDat.getHeight(), true));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user