private static void addStackTrace(Error err) { EventProxy.addDetailLineBreak(); EventProxy.errorDetails.append("Stacktrace:").append('\n'); EventProxy.addDetailLineBreak(); StackTraceElement[] stackTrace = err.getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { EventProxy.addCrashDetailLine(String.format(" %3d) %s", i + 1, stackTrace[i])); } }
protected static String generateHandlerTemplate( String methodName, String signature, String sourceClass) { Type[] argTypes = Type.getArgumentTypes(signature); StringBuilder tpl = new StringBuilder(); tpl.append(" public static void ").append(methodName).append('('); for (int var = 0; var < argTypes.length; var++) { if (EventProxy.appendTypeName(tpl, argTypes[var], sourceClass)) tpl.append("[]"); if (var == 0) tpl.append(" e"); if (var > 0) tpl.append(" arg").append(String.valueOf(var)); if (var < argTypes.length - 1) tpl.append(", "); } tpl.append(")\n\t {\n\t // handler code here\n\t }"); return tpl.toString(); }
private static boolean appendTypeName(StringBuilder tpl, Type type, String sourceClass) { switch (type.getSort()) { case Type.BOOLEAN: tpl.append("boolean"); return false; case Type.CHAR: tpl.append("char"); return false; case Type.BYTE: tpl.append("byte"); return false; case Type.SHORT: tpl.append("short"); return false; case Type.INT: tpl.append("int"); return false; case Type.FLOAT: tpl.append("float"); return false; case Type.LONG: tpl.append("long"); return false; case Type.DOUBLE: tpl.append("double"); return false; case Type.ARRAY: EventProxy.appendTypeName(tpl, type.getElementType(), sourceClass); return true; case Type.OBJECT: String typeName = type.getClassName(); typeName = typeName.substring(typeName.lastIndexOf('.') + 1); tpl.append(typeName); if (typeName.endsWith("ReturnEventInfo")) tpl.append('<').append(sourceClass).append(", ?>"); else if (typeName.endsWith("EventInfo")) tpl.append('<').append(sourceClass).append('>'); return false; } tpl.append("Object"); return false; }
protected static void onMissingHandler(Error err, EventInfo<?> e) { String descriptor = err.getMessage(); int dotPos = descriptor.lastIndexOf('.'); int bracketPos = descriptor.indexOf('('); String signature = descriptor.substring(bracketPos); String sourceClass = e.getSource() != null ? e.getSource().getClass().getSimpleName() : "?"; EventProxy.error = "Missing Event Handler Method!"; EventProxy.errorDetails = new StringBuilder(); EventProxy.addCrashDetailLine("\n"); EventProxy.addCrashDetailLine( "You are seeing this message because an event callback was injected by the Event"); EventProxy.addCrashDetailLine( "Injection Subsystem but the specified callback method was not defined. The"); EventProxy.addCrashDetailLine("details of the missing callback are as follows:"); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine(" Event Name: " + e.getName()); EventProxy.addCrashDetailLine(" Cancellable: " + e.isCancellable()); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine(" Callback class: " + descriptor.substring(0, dotPos)); EventProxy.addCrashDetailLine( " Callback method: " + descriptor.substring(dotPos + 1, bracketPos)); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine( "If you are the mod author then in order to fix the error you must add a suitable"); EventProxy.addCrashDetailLine( "callback method in the above class. The method signature should be as follows:"); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine( EventProxy.generateHandlerTemplate( descriptor.substring(dotPos + 1, bracketPos), signature, sourceClass)); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine( "This is an unrecoverable error, please report it to the mod author and remove"); EventProxy.addCrashDetailLine("the offending mod."); EventProxy.addStackTrace(err); throw new RuntimeErrorException( err, "Missing event handler method for event " + e.getName() + ", see crash report for details"); }
protected static void onMissingClass(Error err, EventInfo<?> e) { EventProxy.error = "Missing Event Handler Class!"; EventProxy.errorDetails = new StringBuilder(); EventProxy.addCrashDetailLine("\n"); EventProxy.addCrashDetailLine( "You are seeing this message because an event callback was injected by the Event"); EventProxy.addCrashDetailLine( "Injection Subsystem but the specified callback class was not defined! The"); EventProxy.addCrashDetailLine("details of the missing callback are as follows:"); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine(" Event Name: " + e.getName()); EventProxy.addCrashDetailLine(" Cancellable: " + e.isCancellable()); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine(" Callback class: " + err.getMessage().replace('/', '.')); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine( "If you are the mod author then in order to fix the error you must provide an"); EventProxy.addCrashDetailLine( "implementation for the specified class, or check that the class name and package"); EventProxy.addCrashDetailLine("are correct."); EventProxy.addDetailLineBreak(); EventProxy.addCrashDetailLine( "This is an unrecoverable error, please report it to the mod author and remove"); EventProxy.addCrashDetailLine("the offending mod."); EventProxy.addStackTrace(err); throw new RuntimeErrorException( err, "Missing event handler class for event " + e.getName() + ", see crash report for details"); }