@@ -128,22 +128,24 @@ private fun BitmapFont.width(text: String): Float {
128128 return layout.width
129129}
130130
131- private fun launchGame (version : GameVersion ) {
132- if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" )) {
131+ var runningProcess: Process ? = null
132+
133+ private fun launchGame (version : GameVersion , button : Button ): Process =
134+ if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" ) || version is ChannelVersion ) {
133135 if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
134- ProcessBuilder (" cmd" , " /c" , " gradlew.bat lwjgl3:run" ).run {
136+ ProcessBuilder (" cmd" , " /c" , " gradlew.bat --no-daemon lwjgl3:run" ).run {
135137 environment()[" PATH" ] = " $JAVA_HOME \\ bin:${System .getenv(" PATH" )} "
136138 environment()[" JAVA_HOME" ] = JAVA_HOME
137139 directory(File (" versions/${version.id} /" ))
138140 }.inheritIO().start()
139141 } else if (System .getProperty(" os.name" ).startsWith(" Linux" )) {
140- ProcessBuilder (" bash" , " -c" , " chmod +x gradlew && ./gradlew lwjgl3:run" ).run {
142+ ProcessBuilder (" bash" , " -c" , " chmod +x gradlew && ./gradlew --no-daemon lwjgl3:run" ).run {
141143 environment()[" PATH" ] = " $JAVA_HOME /bin:${System .getenv(" PATH" )} "
142144 environment()[" JAVA_HOME" ] = JAVA_HOME
143145 directory(File (" versions/${version.id} /" ))
144146 }.inheritIO().start()
145147 } else if (System .getProperty(" os.name" ).startsWith(" Mac" )) {
146- ProcessBuilder (" bash" , " -c" , " chmod +x gradlew && ./gradlew lwjgl3:run" ).run {
148+ ProcessBuilder (" bash" , " -c" , " chmod +x gradlew && ./gradlew --no-daemon lwjgl3:run" ).run {
147149 environment()[" PATH" ] = " $JAVA_HOME /bin:${System .getenv(" PATH" )} "
148150 environment()[" JAVA_HOME" ] = JAVA_HOME
149151 directory(File (" versions/${version.id} /" ))
@@ -154,42 +156,45 @@ private fun launchGame(version: GameVersion) {
154156 } else {
155157 if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
156158 ProcessBuilder (
157- " .. \\ .. \\ $JAVA_HOME \\ bin\\ $JAVA_EXEC_NAME " ,
159+ " $JAVA_HOME \\ bin\\ $JAVA_EXEC_NAME " ,
158160 " -cp" ,
159161 " lib/*" ,
160162 " dev.ultreon.quantum.lwjgl3.Lwjgl3Launcher"
161163 ).run {
162164 environment()[" PATH" ] = " ${File (JAVA_HOME ).absolutePath} \\ bin:${System .getenv(" PATH" )} "
163165 environment()[" JAVA_HOME" ] = File (JAVA_HOME ).absolutePath
164166 directory(File (" versions/${version.id} /" ))
165- }
167+ }.inheritIO().start()
166168 } else if (System .getProperty(" os.name" ).startsWith(" Linux" )) {
167169 ProcessBuilder (
168- " ../../ $JAVA_HOME /bin/$JAVA_EXEC_NAME " ,
170+ " $JAVA_HOME /bin/$JAVA_EXEC_NAME " ,
169171 " -cp" ,
170172 " lib/*" ,
171173 " dev.ultreon.quantum.lwjgl3.Lwjgl3Launcher"
172174 ).run {
173175 environment()[" PATH" ] = " ${File (JAVA_HOME ).absolutePath} /bin:${System .getenv(" PATH" )} "
174176 environment()[" JAVA_HOME" ] = File (JAVA_HOME ).absolutePath
175177 directory(File (" versions/${version.id} /" ))
176- }
178+ }.inheritIO().start()
177179 } else if (System .getProperty(" os.name" ).startsWith(" Mac" )) {
178180 ProcessBuilder (
179- " ../../ $JAVA_HOME /bin/$JAVA_EXEC_NAME " ,
181+ " $JAVA_HOME /bin/$JAVA_EXEC_NAME " ,
180182 " -cp" ,
181183 " lib/*" ,
182184 " dev.ultreon.quantum.lwjgl3.Lwjgl3Launcher"
183185 ).run {
184186 environment()[" PATH" ] = " ${File (JAVA_HOME ).absolutePath} /bin:${System .getenv(" PATH" )} "
185187 environment()[" JAVA_HOME" ] = File (JAVA_HOME ).absolutePath
186188 directory(File (" versions/${version.id} /" ))
187- }
189+ }.inheritIO().start()
188190 } else {
189191 throw UnsupportedOperationException ()
190- }.inheritIO().start()
192+ }
193+ }.also {
194+ button.text = " Click to Stop"
195+ button.enabled = true
196+ runningProcess = it
191197 }
192- }
193198
194199class Downloader (
195200 private val url : String ,
@@ -201,10 +206,14 @@ class Downloader(
201206 private var downloadedBytes: Long = 0
202207
203208 fun download () {
204- thread {
209+ thread(isDaemon = false ) {
205210 val connection = URL (url).openConnection()
206211 totalBytes = if (connection.contentLengthLong == - 1L ) totalBytes else connection.contentLengthLong
207212
213+ if (! Gdx .files.local(" temp" ).exists()) {
214+ Gdx .files.local(" temp" ).mkdirs()
215+ }
216+
208217 val file = RandomAccessFile (Gdx .files.local(" temp/$name " ).file(), " rw" )
209218
210219 connection.inputStream.use { inputStream ->
@@ -297,15 +306,15 @@ val JDK_URL = if (System.getProperty("os.name").startsWith("Windows")) {
297306 throw UnsupportedOperationException ()
298307}
299308
300- val JAVA_HOME = if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
309+ val JAVA_HOME = File ( if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
301310 " jdk/jdk-${JDK_VERSION .replace(" _" , " +" )} "
302311} else if (System .getProperty(" os.name" ).startsWith(" Linux" )) {
303312 " jdk/jdk-${JDK_VERSION .replace(" _" , " +" )} "
304313} else if (System .getProperty(" os.name" ).startsWith(" Mac" )) {
305314 " jdk/jdk-${JDK_VERSION .replace(" _" , " +" )} /Contents/Home"
306315} else {
307316 throw UnsupportedOperationException ()
308- }
317+ }).absolutePath
309318
310319val JAVA_EXEC_NAME = if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
311320 " javaw.exe"
@@ -416,19 +425,32 @@ fun versionsFromGitHub(): List<GameVersion> {
416425
417426fun unpackGame (version : GameVersion ) {
418427 if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
428+ if (! Gdx .files.local(" versions" ).exists()) {
429+ Gdx .files.local(" versions" ).mkdirs()
430+ }
431+
419432 ZipFile (Gdx .files.local(" temp/${version.id} " ).file()).use { zip ->
420433 if (! Gdx .files.local(" versions/${version.id} " ).exists()) {
421434 Gdx .files.local(" versions/${version.id} " ).mkdirs()
422435 }
423436 zip.entries().asSequence().forEach { entry ->
424437 zip.getInputStream(entry).use { inputStream ->
425- if (! Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " ).parent()
426- .exists()
427- ) {
428- Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " ).parent().mkdirs()
438+ if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" ) || version is ChannelVersion ) {
439+ if (! Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " ).parent()
440+ .exists()
441+ ) {
442+ Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " ).parent().mkdirs()
443+ }
444+ Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " )
445+ .write(inputStream, false )
446+ } else {
447+ if (! Gdx .files.local(" temp/${version.id} -extract" ).exists()) {
448+ Gdx .files.local(" temp/${version.id} -extract" ).mkdirs()
449+ }
450+ Gdx .files.local(" temp/${version.id} -extract/${entry.name.substringAfter(' /' )} " ).parent().mkdirs()
451+ Gdx .files.local(" temp/${version.id} -extract/${entry.name.substringAfter(' /' )} " )
452+ .write(inputStream, false )
429453 }
430- Gdx .files.local(" versions/${version.id} /${entry.name.substringAfter(' /' )} " )
431- .write(inputStream, false )
432454 }
433455 }
434456 }
@@ -448,7 +470,7 @@ fun unpackGame(version: GameVersion) {
448470 println (" Failed to unpack ${version.id} " )
449471 }
450472
451- if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" )) {
473+ if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" ) || version is ChannelVersion ) {
452474 val exec2 = Runtime .getRuntime()
453475 .exec(arrayOf(" mv" , " ${Gdx .files.local(" temp/${version.id} -extract" ).list()[0 ]} " , " versions/${version.id} " ))
454476
@@ -491,7 +513,7 @@ fun unpackGame(version: GameVersion) {
491513 println (" Failed to unpack ${version.id} " )
492514 }
493515
494- if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" )) {
516+ if (version.id in arrayOf(" 0.0.0-indev" , " 0.0.1-indev" ) || version is ChannelVersion ) {
495517 val arrayOf =
496518 arrayOf(" mv" , " ${Gdx .files.local(" temp/${version.id} -extract" ).list()[0 ]} " , " versions/${version.id} " )
497519 println (arrayOf.contentToString())
@@ -554,28 +576,61 @@ fun unpack(path: String, dest: String) {
554576 }
555577}
556578
579+ fun killProcess (process : Process ) {
580+ try {
581+ process.destroyForcibly()
582+ process.descendants().forEach {
583+ it.destroyForcibly()
584+ }
585+ process.waitFor()
586+ } catch (e: Exception ) {
587+ println (e.message)
588+ }
589+ }
590+
557591/* * [com.badlogic.gdx.ApplicationListener] implementation shared by all platforms. */
558- class Main : ApplicationAdapter () {
592+ object Main : ApplicationAdapter() {
593+
594+ private lateinit var looper: Thread
559595 private val spriteBatch by lazy { SpriteBatch () }
560596
561597 private val font by lazy { BitmapFont (Gdx .files.internal(" luna_pixel.fnt" )) }
562598
563599 private var selectedVersion: GameVersion ? = null
564600
601+ private var triedDestoyingOnce = false
602+
565603 private val playButton by lazy {
566604 Button (font, callback = {
605+ val runningProcess1 = runningProcess
606+ if (runningProcess1 != null && runningProcess1.isAlive) {
607+ try {
608+ killProcess(runningProcess1)
609+ } catch (e: Exception ) {
610+ println (e.message)
611+ }
612+ return @Button
613+ }
614+
615+ triedDestoyingOnce = false
567616 val version = selectedVersion ? : return @Button
568617
569618 enabled = false
570619
620+ if (version is ChannelVersion ) {
621+ File (" versions/${version.id} " ).deleteRecursively()
622+ }
623+
571624 if (! version.isDownloaded()) {
572625 downloadGame(version, this ) {
626+
627+ File (" temp" ).deleteRecursively()
573628 text = " Launching ${version.name} "
574- launchGame(version)
629+ launchGame(version, this )
575630 }
576631 } else {
577632 text = " Launching ${version.name} "
578- launchGame(version)
633+ launchGame(version, this )
579634 }
580635 })
581636 }
@@ -597,8 +652,8 @@ class Main : ApplicationAdapter() {
597652 }
598653
599654 private val background by lazy { Texture (Gdx .files.internal(" background.png" )) }
600-
601655 val width get() = Gdx .graphics.width.toFloat() / 2f
656+
602657 val height get() = Gdx .graphics.height.toFloat() / 2f
603658
604659 private var selectedButton: Button ? = null
@@ -650,6 +705,26 @@ class Main : ApplicationAdapter() {
650705 return true
651706 }
652707 }
708+
709+ looper = thread(isDaemon = false ) {
710+ while (true ) {
711+ if (runningProcess != null && ! runningProcess!! .isAlive) {
712+ runningProcess = null
713+ playButton.enabled = true
714+ playButton.text = " Play"
715+ }
716+
717+ try {
718+ Thread .sleep(1000 )
719+ } catch (e: Exception ) {
720+ return @thread
721+ }
722+
723+ if (Thread .interrupted()) {
724+ return @thread
725+ }
726+ }
727+ }
653728 }
654729
655730 var scrollY = 0f
@@ -698,4 +773,16 @@ class Main : ApplicationAdapter() {
698773 spriteBatch.end()
699774 }
700775 }
776+
777+ fun handleClose (): Boolean {
778+ val process = runningProcess
779+ if (process != null && process.isAlive) {
780+ killProcess(process)
781+ return false
782+ }
783+ if (this ::looper.isInitialized) {
784+ looper.interrupt()
785+ }
786+ return true
787+ }
701788}
0 commit comments