1+ package org.bundleproject.launchwrapper
2+
3+ import org.bundleproject.launchwrapper.utils.bundleClassName
4+ import org.bundleproject.launchwrapper.utils.err
5+ import org.bundleproject.launchwrapper.utils.get
6+ import org.bundleproject.launchwrapper.utils.info
7+ import java.io.File
8+ import kotlin.reflect.KClass
9+ import kotlin.reflect.full.callSuspend
10+ import kotlin.reflect.full.createType
11+ import kotlin.reflect.full.functions
12+ import kotlin.reflect.full.primaryConstructor
13+
14+ val fallbackEntrypoints = arrayOf(
15+ " net.fabricmc.loader.launch.knot.KnotClient" ,
16+ " cpw.mods.bootstraplauncher.BootstrapLauncher" ,
17+ " net.minecraft.launchwrapper.Launch" ,
18+ " org.bookmc.loader.impl.launch.Quilt" ,
19+ " com.github.glassmc.loader.client.GlassClientMain" ,
20+ " net.minecraft.client.main.Main" , // just in case user installed to vanilla
21+ )
22+
23+ suspend fun launch (args : Array <String >, gameDir : File , classLoader : ClassLoader ) {
24+ (args[" bundleMainClass" ]?.let { Class .forName(it).kotlin } ? : findEntrypoint())?.run {
25+ val version = args[" version" ]
26+ ?.takeIf { it != " MultiMC5" }
27+ val modFolderName = " mods"
28+
29+ val bundleClass = runCatching { Class .forName(bundleClassName, true , classLoader).kotlin }
30+ .onFailure {
31+ err(" Bundle is not in the classpath! Cannot launch bundle!" )
32+ return @launch
33+ }
34+ .getOrThrow()
35+
36+ info(" Invoking constructor..." )
37+ bundleClass.constructors.find { it.typeParameters[1 ] == String ::class .createType() }
38+ ?.call(gameDir, version, modFolderName)
39+
40+ info(" Starting Bundle... Goodbye, Launchwrapper..." )
41+ bundleClass.functions.find { it.name == " start" }?.callSuspend()
42+ }
43+ }
44+
45+ private fun findEntrypoint (): KClass <* >? {
46+ err(" Relying on fallback entrypoint! Please re-install bundle!" )
47+ fallbackEntrypoints.forEach {
48+ runCatching { Class .forName(it) }
49+ .onSuccess { return it.kotlin }
50+ }
51+
52+ return null
53+ }
0 commit comments