From e9967c9d8e3901158de9561bf7f77ea607fd5902 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Sun, 12 Mar 2023 03:50:23 +0100 Subject: [PATCH] feat: finished backend stuff, added installing and unziping of loader and zipfiles, added other utils Signed-off-by: limited_dev --- build.gradle.kts | 6 +- .../modpackinstaller/backend/Manager.kt | 70 +++++++++++++++- .../modpackinstaller/gui/DataUtil.kt | 83 +++++++++++++++++++ .../limited_dev/modpackinstaller/gui/GUI.kt | 2 +- .../modpackinstaller/gui/MainPanel.kt | 3 +- .../modpackinstaller/util/PopupFactory.kt | 10 +++ .../modpackinstaller/build/BuildConstants.kt | 1 + 7 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/de/limited_dev/modpackinstaller/gui/DataUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index fa4ae5f..09777e0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,10 @@ version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_ val fabricDownloadLocation = "https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.2/fabric-installer-0.11.2.jar" -val modpackDownloadLocation = "https://fileshare.limited-dev.de/modpack.zip" +//https://fileshare.limited-dev.de:4443/share-download/4e6935a2-6ba8-4131-9141-29197ce9dc18 +//http://192.168.178.200:5091/share?id=70853092-8026-4220-ba8f-3cb6c520df75 +val modpackDownloadLocation = "https://fileshare.limited-dev.de:4443/share?id=70853092-8026-4220-ba8f-3cb6c520df75" +var mcversion = "1.19.2" val mavenArtifact = "ModpackInstaller" @@ -59,6 +62,7 @@ val templateSrc = project.rootDir.resolve("src/main/templates") val templateDest = project.buildDir.resolve("generated/templates") val templateProps = mapOf( "version" to project.version as String, + "mcversion" to mcversion, "fabricDownloadLocation" to fabricDownloadLocation, "modpackDownloadLocation" to modpackDownloadLocation ) diff --git a/src/main/kotlin/de/limited_dev/modpackinstaller/backend/Manager.kt b/src/main/kotlin/de/limited_dev/modpackinstaller/backend/Manager.kt index fe7d162..9f4abc9 100644 --- a/src/main/kotlin/de/limited_dev/modpackinstaller/backend/Manager.kt +++ b/src/main/kotlin/de/limited_dev/modpackinstaller/backend/Manager.kt @@ -18,24 +18,90 @@ package de.limited_dev.modpackinstaller.backend +import de.limited_dev.modpackinstaller.build.BuildConstants +import de.limited_dev.modpackinstaller.gui.DataUtil +import de.limited_dev.modpackinstaller.gui.DataUtil.downloadFile +import de.limited_dev.modpackinstaller.gui.MainPanel +import de.limited_dev.modpackinstaller.util.PopupFactory import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import java.io.File +import kotlin.system.exitProcess object Manager { fun startDownloadAndInstall(dotMcLocation: String) { + val tempFolder = File(dotMcLocation + File.separator + "temp") + val modFolder = File(dotMcLocation + File.separator + "mods") + Runtime.getRuntime().addShutdownHook(Thread { + println("Application is shutting down") + val tempFolder2 = File(dotMcLocation + File.separator + "temp") + if (tempFolder.exists()) + tempFolder2.deleteRecursively() + }) + if (tempFolder.exists()) + tempFolder.deleteRecursively() + tempFolder.mkdirs() + val modloaderCoroutine = GlobalScope.launch { println("Downloading Modloader") + val megabytesDownloaded = runBlocking { + downloadFile( + BuildConstants.fabricDownloadLocation, + dotMcLocation + File.separator + "temp" + File.separator + "fabric.jar", + true + ) + } + println("Downloaded $megabytesDownloaded MB Modloader") + MainPanel.updateFabricModloader("Installing...") + val command = "java" + val args = listOf( + "-jar", + "fabric.jar", + "client", + "-dir $dotMcLocation", + "-mcversion ${BuildConstants.mcversion}", + "win32" + ) + + val processBuilder = ProcessBuilder(command, *args.toTypedArray()) + .directory(tempFolder) + .redirectOutput(ProcessBuilder.Redirect.INHERIT) + .redirectError(ProcessBuilder.Redirect.INHERIT) + + val process = processBuilder.start() + val exitCode = process.waitFor() + MainPanel.updateFabricModloader("Done!") + println("Java application exited with code: $exitCode") } val modpackCoroutine = GlobalScope.launch { println("Downloading Modpack") + val megabytesDownloaded = runBlocking { + downloadFile( + BuildConstants.modpackDownloadLocation, + dotMcLocation + File.separator + "temp" + File.separator + "pack.zip", + false + ) + } + println("Downloaded $megabytesDownloaded MB Modpack\nUnzipping...") + + MainPanel.updateModpack("Unzipping...") + var modzip = File(tempFolder.absolutePath + File.separator + "pack.zip") + DataUtil.unzip(modzip, modFolder) + MainPanel.updateModpack("Done!") + println("Done!") } runBlocking { modloaderCoroutine.join() + modpackCoroutine.join() } - - + println("Done.") + PopupFactory.getOk( + "Installed!", + "The Modpack is now installed!\nYou may now (re)open your Minecraft Launcher!\n\nHave fun playing! ~limited_dev" + ) + exitProcess(0) } } \ No newline at end of file diff --git a/src/main/kotlin/de/limited_dev/modpackinstaller/gui/DataUtil.kt b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/DataUtil.kt new file mode 100644 index 0000000..85956ca --- /dev/null +++ b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/DataUtil.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.modpackinstaller.gui + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.BufferedInputStream +import java.io.BufferedOutputStream +import java.io.File +import java.io.FileOutputStream +import java.net.URL +import java.util.zip.ZipFile + +object DataUtil { + suspend fun downloadFile(url: String, downloadLocation: String, isLoader: Boolean): Double { + var bytesDownloaded = 0L + withContext(Dispatchers.IO) { + val connection = URL(url).openConnection() + val stream = BufferedInputStream(connection.getInputStream()) + val outputStream = BufferedOutputStream(FileOutputStream(File(downloadLocation))) + val data = ByteArray(1024) + var bytesRead = stream.read(data, 0, 1024) + while (bytesRead != -1) { + outputStream.write(data, 0, bytesRead) + bytesDownloaded += bytesRead + if (isLoader) + MainPanel.updateFabricModloader("Downloading " + bytesDownloaded.toString() + "MB") + else + MainPanel.updateModpack("Downloading " + bytesDownloaded.toString() + "MB") + bytesRead = stream.read(data, 0, 1024) + } + outputStream.close() + stream.close() + } + return bytesDownloaded / 1024.0 / 1024.0 + } + + fun unzip(zipFile: File, destinationDirectory: File) { + // Create the destination directory if it doesn't exist + if (!destinationDirectory.exists()) { + destinationDirectory.mkdirs() + } + + // Open the ZIP file and iterate over its entries + val zip = ZipFile(zipFile) + val entries = zip.entries() + while (entries.hasMoreElements()) { + val entry = entries.nextElement() + + // Extract the entry to the specified destination directory + val entryDestination = File(destinationDirectory, entry.name) + if (entry.isDirectory) { + entryDestination.mkdirs() + } else { + entryDestination.parentFile.mkdirs() + zip.getInputStream(entry).use { input -> + entryDestination.outputStream().use { output -> + input.copyTo(output) + } + } + } + } + + // Close the ZIP file + zip.close() + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/limited_dev/modpackinstaller/gui/GUI.kt b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/GUI.kt index c46eefe..bef9c0a 100644 --- a/src/main/kotlin/de/limited_dev/modpackinstaller/gui/GUI.kt +++ b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/GUI.kt @@ -31,7 +31,7 @@ class GUI : JFrame("Modpack installer " + BuildConstants.version) { val contentPane = this.contentPane contentPane.layout = BorderLayout() - contentPane.add(MainPanel(), BorderLayout.CENTER) + contentPane.add(MainPanel, BorderLayout.CENTER) contentPane.add(BottomBar(), BorderLayout.SOUTH) this.pack() diff --git a/src/main/kotlin/de/limited_dev/modpackinstaller/gui/MainPanel.kt b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/MainPanel.kt index 1060e8d..e766dfa 100644 --- a/src/main/kotlin/de/limited_dev/modpackinstaller/gui/MainPanel.kt +++ b/src/main/kotlin/de/limited_dev/modpackinstaller/gui/MainPanel.kt @@ -27,7 +27,7 @@ import javax.swing.* import javax.swing.border.EmptyBorder -class MainPanel : JPanel() { +object MainPanel : JPanel() { private val generatorButton = JButton("Download & Install") private var fabricLabel: JLabel private var modpackLabel: JLabel @@ -66,7 +66,6 @@ class MainPanel : JPanel() { } this.add(openFileChooser) generatorButton.addActionListener { - Manager.startDownloadAndInstall(dotMcLocation) val dotMcMods = File(dotMcLocation + File.separator + "mods") if (dotMcMods.exists()) { val bool = PopupFactory.getYesOrNoError( diff --git a/src/main/kotlin/de/limited_dev/modpackinstaller/util/PopupFactory.kt b/src/main/kotlin/de/limited_dev/modpackinstaller/util/PopupFactory.kt index 27f9f64..614427d 100644 --- a/src/main/kotlin/de/limited_dev/modpackinstaller/util/PopupFactory.kt +++ b/src/main/kotlin/de/limited_dev/modpackinstaller/util/PopupFactory.kt @@ -22,6 +22,16 @@ import javax.swing.JOptionPane object PopupFactory { + fun getOk(title: String, msg: String) { + println("Popup created") + val res = JOptionPane.showConfirmDialog( + null, + msg, + title, + JOptionPane.CLOSED_OPTION + ) + } + fun getYesOrNoError(title: String, msg: String): Boolean { println("Popup created") val res = JOptionPane.showConfirmDialog( diff --git a/src/main/templates/de/limited_dev/modpackinstaller/build/BuildConstants.kt b/src/main/templates/de/limited_dev/modpackinstaller/build/BuildConstants.kt index bd76514..00a89ec 100644 --- a/src/main/templates/de/limited_dev/modpackinstaller/build/BuildConstants.kt +++ b/src/main/templates/de/limited_dev/modpackinstaller/build/BuildConstants.kt @@ -2,6 +2,7 @@ package de.limited_dev.modpackinstaller.build internal object BuildConstants { const val version = "${version}" + const val mcversion = "${mcversion}" const val fabricDownloadLocation = "${fabricDownloadLocation}" const val modpackDownloadLocation = "${modpackDownloadLocation}" }