Skip to content

Commit 7e5d676

Browse files
authored
Separate mappings directory (#6)
* Separate mappings directory * Separate mappings directory * Separate mappings directory
1 parent 271a59d commit 7e5d676

File tree

6 files changed

+31
-27
lines changed

6 files changed

+31
-27
lines changed

Diff for: src/main/kotlin/me/urielsalis/mccrashlib/CrashReader.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import arrow.core.Either
44
import me.urielsalis.mccrashlib.parser.JavaCrashParser
55
import me.urielsalis.mccrashlib.parser.MinecraftCrashParser
66
import me.urielsalis.mccrashlib.parser.ParserError
7+
import java.io.File
78

89
const val MINECRAFT_CRASH_HEADER = "---- Minecraft Crash Report ----"
910
const val JAVA_CRASH_HEADER = "# EXCEPTION_ACCESS_VIOLATION"
@@ -14,12 +15,13 @@ class CrashReader {
1415
val minecraftParser = MinecraftCrashParser()
1516
val javaParser = JavaCrashParser()
1617

17-
fun processCrash(crash: List<String>): Either<ParserError, Crash> = when {
18-
crash.anyContains(MINECRAFT_CRASH_HEADER) -> minecraftParser.parse(crash)
18+
fun processCrash(crash: List<String>, mappingsDir: File): Either<ParserError, Crash> = when {
19+
crash.anyContains(MINECRAFT_CRASH_HEADER) -> minecraftParser.parse(crash, mappingsDir)
1920
crash.anyContains(SERVER_CONSOLE_LOG) && crash.anyContains(JAVA_CRASH_HEADER) -> javaParser.parse(
20-
crash.map { it.replace(SERVER_CONSOLE_LOG, "").trim() }
21+
crash.map { it.replace(SERVER_CONSOLE_LOG, "").trim() },
22+
mappingsDir
2123
)
22-
crash.anyContains(JAVA_CRASH_HEADER) -> javaParser.parse(crash)
24+
crash.anyContains(JAVA_CRASH_HEADER) -> javaParser.parse(crash, mappingsDir)
2325
crash.anyContains(LAUNCHER_LOG_CONTENT) -> Either.right(Crash.LauncherLog)
2426
else -> Either.right(Crash.Unknown)
2527
}

Diff for: src/main/kotlin/me/urielsalis/mccrashlib/deobfuscator/Deobfuscator.kt

+12-15
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ import java.io.StringReader
1010
import java.io.StringWriter
1111
import java.net.HttpURLConnection
1212
import java.net.URL
13-
import java.nio.file.Files
1413

15-
val mappingsFile = Files.createTempDirectory("mappings").toFile()
16-
17-
fun getDeobfuscation(modded: Boolean, version: String, content: String, isClient: Boolean): String? {
14+
fun getDeobfuscation(modded: Boolean, version: String, content: String, isClient: Boolean, mappingsDirectory: File): String? {
1815
if (modded) {
1916
return null
2017
}
2118

22-
if (version.isBlank() || version.contains("\\") || version.contains("/") || isZipSlip(version)) {
19+
if (version.isBlank() || version.contains("\\") || version.contains("/") || isZipSlip(version, mappingsDirectory)) {
2320
return null
2421
}
2522

@@ -29,10 +26,10 @@ fun getDeobfuscation(modded: Boolean, version: String, content: String, isClient
2926
"$version-server"
3027
}
3128

32-
val mappingFile = synchronized(mappingsFile) {
33-
val mappingFile = File(mappingsFile, name)
29+
val mappingFile = synchronized(mappingsDirectory) {
30+
val mappingFile = File(mappingsDirectory, name)
3431
if (!mappingFile.exists()) {
35-
downloadMapping(version, name, isClient)
32+
downloadMapping(version, name, isClient, mappingsDirectory)
3633
}
3734
if (!mappingFile.exists()) {
3835
return null
@@ -46,14 +43,14 @@ fun getDeobfuscation(modded: Boolean, version: String, content: String, isClient
4643
return stringWriter.toString()
4744
}
4845

49-
fun isZipSlip(version: String): Boolean {
50-
val canonicalDestinationDir = mappingsFile.canonicalPath
51-
val destinationFile = File(mappingsFile, version)
46+
fun isZipSlip(version: String, mappingsDirectory: File): Boolean {
47+
val canonicalDestinationDir = mappingsDirectory.canonicalPath
48+
val destinationFile = File(mappingsDirectory, version)
5249
val canonicalDestinationFile = destinationFile.canonicalPath
5350
return !canonicalDestinationFile.startsWith(canonicalDestinationDir + File.separator)
5451
}
5552

56-
private fun downloadMapping(version: String, name: String, isClient: Boolean) {
53+
private fun downloadMapping(version: String, name: String, isClient: Boolean, mappingsDirectory: File) {
5754
val mapper = jacksonObjectMapper()
5855
val manifest = mapper
5956
.readValue(URL("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest::class.java)
@@ -67,14 +64,14 @@ private fun downloadMapping(version: String, name: String, isClient: Boolean) {
6764
if (mappingUrl == null) {
6865
return
6966
}
70-
downloadFile(mappingUrl, name)
67+
downloadFile(mappingUrl, name, mappingsDirectory)
7168
}
7269

73-
fun downloadFile(url: String, name: String) {
70+
fun downloadFile(url: String, name: String, mappingsDirectory: File) {
7471
val connection: HttpURLConnection = URL(url).openConnection() as HttpURLConnection
7572
connection.requestMethod = "GET"
7673
val stream = connection.inputStream
77-
val file = File(mappingsFile, name)
74+
val file = File(mappingsDirectory, name)
7875
file.createNewFile()
7976
val out = FileOutputStream(file)
8077
stream.transferTo(out)

Diff for: src/main/kotlin/me/urielsalis/mccrashlib/parser/CrashParser.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package me.urielsalis.mccrashlib.parser
22

33
import arrow.core.Either
44
import me.urielsalis.mccrashlib.Crash
5+
import java.io.File
56

67
interface CrashParser {
7-
fun parse(lines: List<String>): Either<ParserError, Crash>
8+
fun parse(lines: List<String>, mappingsDirectory: File): Either<ParserError, Crash>
89
}
910

1011
interface ParserError

Diff for: src/main/kotlin/me/urielsalis/mccrashlib/parser/JavaCrashParser.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package me.urielsalis.mccrashlib.parser
33
import arrow.core.Either
44
import arrow.core.firstOrNone
55
import me.urielsalis.mccrashlib.Crash
6+
import java.io.File
67

78
/*
89
All the lines of the crash start with #
@@ -13,7 +14,7 @@ import me.urielsalis.mccrashlib.Crash
1314
class JavaCrashParser : CrashParser {
1415
object IncompleteJavaCrash : ParserError
1516

16-
override fun parse(lines: List<String>): Either<ParserError, Crash> {
17+
override fun parse(lines: List<String>, mappingsDirectory: File): Either<ParserError, Crash> {
1718
val linesWithMarker = lines.map(String::trim).filter { it.startsWith("#") }
1819
val importantLine = linesWithMarker.firstOrNone { it.startsWith("# C") && "[" in it && "+" in it }
1920
return importantLine.fold(

Diff for: src/main/kotlin/me/urielsalis/mccrashlib/parser/MinecraftCrashParser.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import arrow.core.Either
44
import arrow.core.Option
55
import me.urielsalis.mccrashlib.Crash
66
import me.urielsalis.mccrashlib.deobfuscator.getDeobfuscation
7+
import java.io.File
78

89
/*
910
Minecraft crashes are separated into sections starting and ending with --
@@ -21,7 +22,7 @@ class MinecraftCrashParser : CrashParser {
2122
object SectionsNotFound : ParserError
2223
object NoExceptionFound : ParserError
2324

24-
override fun parse(lines: List<String>): Either<ParserError, Crash> {
25+
override fun parse(lines: List<String>, mappingsDirectory: File): Either<ParserError, Crash> {
2526
val sections = parseSections(lines)
2627
if (!sections.containsKey(crashReportSection) || !sections.containsKey(systemDetailsSection)) {
2728
return Either.left(SectionsNotFound)
@@ -32,7 +33,7 @@ class MinecraftCrashParser : CrashParser {
3233
val version = getMinecraftVersion(details)
3334
val type = getType(details)
3435
val isClient = type == "Client"
35-
val deobf = getDeobfuscation(isModded, version, lines.joinToString("\n"), isClient)
36+
val deobf = getDeobfuscation(isModded, version, lines.joinToString("\n"), isClient, mappingsDirectory)
3637
return exception.fold(
3738
{ Either.left(NoExceptionFound) },
3839
{

Diff for: src/test/kotlin/CrashReaderIntegrationTest.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import me.urielsalis.mccrashlib.CrashReader
44
import me.urielsalis.mccrashlib.parser.ParserError
55
import org.junit.Test
66
import java.io.File
7+
import java.nio.file.Files
78

89
class CrashReaderIntegrationTest {
910
val crashReader = CrashReader()
11+
val tempDir = Files.createTempDirectory("mappings").toFile()
1012

1113
@Test
1214
fun shouldRunAllMinecraftCrashes() {
@@ -18,7 +20,7 @@ class CrashReaderIntegrationTest {
1820
val isModded = parts[0] == "true"
1921
val expectedException = parts[1]
2022

21-
val crashEither = crashReader.processCrash(it.readLines())
23+
val crashEither = crashReader.processCrash(it.readLines(), tempDir)
2224
assert(crashEither is Either.Right)
2325
val crash = (crashEither as Either.Right).b
2426
assert(crash is Crash.Minecraft)
@@ -36,7 +38,7 @@ class CrashReaderIntegrationTest {
3638
val parts = name.split("-")
3739
val expectedCode = parts[0]
3840

39-
val crashEither = crashReader.processCrash(it.readLines())
41+
val crashEither = crashReader.processCrash(it.readLines(), tempDir)
4042
assert(crashEither is Either.Right)
4143
val crash = (crashEither as Either.Right).b
4244
assert(crash is Crash.Java)
@@ -49,7 +51,7 @@ class CrashReaderIntegrationTest {
4951
val crashes = File(this::class.java.getResource("crashes/log").file).listFiles()
5052

5153
crashes.forEach {
52-
val crashEither = crashReader.processCrash(it.readLines())
54+
val crashEither = crashReader.processCrash(it.readLines(), tempDir)
5355
assert(crashEither is Either.Right)
5456
val crash = (crashEither as Either.Right).b
5557
assert(crash is Crash.LauncherLog)
@@ -62,7 +64,7 @@ class CrashReaderIntegrationTest {
6264

6365
crashes.forEach {
6466
if (!it.nameWithoutExtension.endsWith("deobf")) {
65-
val either = crashReader.processCrash(it.readLines())
67+
val either = crashReader.processCrash(it.readLines(), tempDir)
6668
val content = File(it.parent, it.nameWithoutExtension + "-deobf.log")
6769
if (content.exists()) {
6870
assertDeobf(either, content.readText())

0 commit comments

Comments
 (0)