package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Dimension
import java.awt.Font
import java.awt.Font.BOLD
import java.awt.Font.PLAIN
import java.io.OutputStream
import java.io.PrintStream
import javax.swing.*
/**
* Created by minjaesong on 2021-09-18.
*/
class GameCrashHandler(e: Throwable) : JFrame() {
val textArea = JTextPane()
val htmlSB = StringBuilder()
private val outputStream = object : OutputStream() {
override fun write(p0: Int) {
htmlSB.append((p0 and 255).toChar())
}
}
private val css = """
body {
font-size: 12px;
font-family: sans-serif;
margin: 3px;
background-color: #fdfdfd;
}
h3 {
font-size: 16px;
font-weight: 700;
color: #444;
margin: 20px 10px 12px 10px;
}
h4 {
font-size: 14px;
font-weight: 500;
color: #444;
margin: 0 12px 6px 12px;
}
li {
margin: 0;
}
p {
margin: 3px 12px;
}
pre {
font-faminy: monospaced;
font-size: 11px;
color: #801;
border: 1px solid #801;
border-radius: 3px;
padding: 3px 6px;
}
small {
font-size: 9px;
}
emph {
font-style: italic;
color: #777;
}
"""
private val printStream = object : PrintStream(outputStream) {
override fun println(x: String?) {
super.print(x)
}
}
private fun moduleMetaToText(m: ModMgr.ModuleMetadata?) = if (m == null)
"metadata not available or the mod failed to load"
else
"author: ${m.author}, version: ${m.version}, release date: ${m.releaseDate}, dependencies: ${m.dependencies.joinToString("/")}"
init {
val border = JPanel()
border.layout = BorderLayout(18,18)
border.isVisible = true
border.background = Color(63,79,93)
val title = JLabel("Help! A blackhole ate my game!")
title.font = Font("SansSerif", BOLD, 18)
title.foreground = Color.WHITE
title.isVisible = true
title.horizontalAlignment = SwingConstants.CENTER
border.add(title, BorderLayout.NORTH)
textArea.isVisible = true
textArea.isEditable = false
textArea.contentType = "text/html"
border.add(JScrollPane(textArea), BorderLayout.CENTER)
this.layout = BorderLayout(32,32)
this.size = Dimension(1280, 720)
this.isVisible = true
this.defaultCloseOperation = EXIT_ON_CLOSE
this.contentPane.background = Color(63,79,93)
this.add(JLabel(), BorderLayout.EAST)
this.add(JLabel(), BorderLayout.WEST)
this.add(JLabel(), BorderLayout.SOUTH)
this.add(JLabel(), BorderLayout.NORTH)
this.add(border, BorderLayout.CENTER)
this.title = TerrarumAppConfiguration.GAME_NAME
val uptime = App.getTIME_T() - App.startupTime
// print out device info
printStream.println("
System Info
")
printStream.println("")
printStream.println("- Game name: ${TerrarumAppConfiguration.GAME_NAME}
")
printStream.println("- Engine version: ${App.getVERSION_STRING()}
")
printStream.println("- JRE version: ${System.getProperty("java.version")}
")
printStream.println("- Gdx version: ${com.badlogic.gdx.Version.VERSION}
")
printStream.println("- LWJGL version: ${org.lwjgl.Version.VERSION_MAJOR}.${org.lwjgl.Version.VERSION_MINOR}.${org.lwjgl.Version.VERSION_REVISION}
")
printStream.println("- Uptime: ${uptime / 3600}h${(uptime % 3600) / 60}m${uptime % 60}s
")
printStream.println("- BogoFlops: ${App.bogoflops}
")
printStream.println("- OS Name: ${App.OSName}
")
printStream.println("- OS Version: ${App.OSVersion}
")
printStream.println("- System architecture: ${App.systemArch}
")
printStream.println("- Processor: ${App.processor} x${Runtime.getRuntime().availableProcessors()} (${App.processorVendor})
")
printStream.println("
")
printStream.println("OpenGL Info
")
try {
printStream.println("- ${Gdx.graphics.glVersion.debugVersionString.replace("\n", "
- ")}
")
}
catch (e: NullPointerException) {
printStream.println("GL not initialised
")
}
printStream.println("Module Info
")
printStream.println("Load Order
")
printStream.println("${ModMgr.loadOrder.joinToString(separator = "") { "- " +
"$it (" +
"${moduleMetaToText(ModMgr.moduleInfo[it] ?: ModMgr.moduleInfoErrored[it])}" +
")
" }
}
")
ModMgr.errorLogs.let {
if (it.size > 0) {
printStream.println("Module Errors
")
System.err.println("== Module Errors ==")
it.forEach {
printStream.println("From Module ${it.moduleName} (${it.type.toHTML()}):
")
printStream.println("")
it.cause?.printStackTrace(printStream)
printStream.println("")
it.cause?.printStackTrace(System.err)
}
}
}
printStream.println("The Error Info
")
System.err.println("== The Error Info ==")
printStream.println("")
e.printStackTrace(printStream)
printStream.println("")
e.printStackTrace(System.err)
textArea.text = "$htmlSB"
}
private fun ModMgr.LoadErrorType.toHTML() = when(this) {
ModMgr.LoadErrorType.YOUR_FAULT -> "caused by the module"
ModMgr.LoadErrorType.MY_FAULT -> "caused by the game"
ModMgr.LoadErrorType.NOT_EVEN_THERE -> "dependency not satisfied"
}
}