mirror of
https://github.com/Anvilcraft/modpacktools
synced 2024-06-11 06:59:28 +02:00
BuildTechnic.kt should work now
improved FileDownloader.kt
This commit is contained in:
parent
069b2896e6
commit
db1f46d728
|
@ -20,9 +20,7 @@ constructor(
|
||||||
ArgumentParsers.newFor(displayName)
|
ArgumentParsers.newFor(displayName)
|
||||||
.build()
|
.build()
|
||||||
.description(helpMessage)
|
.description(helpMessage)
|
||||||
.apply {
|
.apply {addArgs()}
|
||||||
addArgs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,5 +29,5 @@ constructor(
|
||||||
*
|
*
|
||||||
* @receiver the parser to add the args to
|
* @receiver the parser to add the args to
|
||||||
*/
|
*/
|
||||||
open fun ArgumentParser.addArgs() {}
|
protected open fun ArgumentParser.addArgs() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ley.anvil.modpacktools.command.AbstractCommand
|
||||||
import ley.anvil.modpacktools.command.CommandReturn
|
import ley.anvil.modpacktools.command.CommandReturn
|
||||||
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
|
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
|
||||||
import ley.anvil.modpacktools.command.LoadCommand
|
import ley.anvil.modpacktools.command.LoadCommand
|
||||||
|
import ley.anvil.modpacktools.util.FileToDownload
|
||||||
import ley.anvil.modpacktools.util.addonscript.installFile
|
import ley.anvil.modpacktools.util.addonscript.installFile
|
||||||
import ley.anvil.modpacktools.util.downloadFiles
|
import ley.anvil.modpacktools.util.downloadFiles
|
||||||
import ley.anvil.modpacktools.util.fPrintln
|
import ley.anvil.modpacktools.util.fPrintln
|
||||||
|
@ -16,7 +17,6 @@ import net.sourceforge.argparse4j.inf.Namespace
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.net.URL
|
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
@LoadCommand
|
@LoadCommand
|
||||||
|
@ -37,39 +37,51 @@ object BuildTechnic : AbstractCommand("BuildTechnic") {
|
||||||
}
|
}
|
||||||
|
|
||||||
val fileList = mutableListOf<FileOrLink>()
|
val fileList = mutableListOf<FileOrLink>()
|
||||||
val toDownload = mutableMapOf<URL, Pair<String, File>>()
|
//Map of File to Installer
|
||||||
MPJH.asWrapper!!.defaultVersion.getRelations {"client" in it.options}.forEach {
|
val toDownload = mutableMapOf<FileToDownload, String>()
|
||||||
if(it.hasFile())
|
|
||||||
fileList.add(it.file.get())
|
//RELATIONS
|
||||||
}
|
fileList.addAll(
|
||||||
|
MPJH.asWrapper!!.defaultVersion.getRelations {"client" in it.options}.filter {it.hasFile()}
|
||||||
|
.map {it.file.get()}
|
||||||
|
)
|
||||||
|
//FILES
|
||||||
|
fileList.addAll(MPJH.asWrapper!!.defaultVersion.getFiles {true}.map {it.get()})
|
||||||
|
|
||||||
|
//FORGE
|
||||||
|
@Suppress("DEPRECATION") //no idea why this is deprecated. Too Bad!
|
||||||
|
val forge = MPJH.asWrapper!!.defaultVersion.getRelations {it.id.toLowerCase() == "forge"}.first().forgeUniversal
|
||||||
|
toDownload[
|
||||||
|
FileToDownload(
|
||||||
|
//Technic wants it to be called modpack.jar
|
||||||
|
File(download, "modpack.jar"),
|
||||||
|
forge.url
|
||||||
|
)
|
||||||
|
] = "internal.dir:bin"
|
||||||
|
|
||||||
fileList.forEach {
|
fileList.forEach {
|
||||||
when {
|
when {
|
||||||
it.isFile -> {
|
!it.isURL -> {
|
||||||
if(!it.isASDirSet)
|
if(!it.isASDirSet)
|
||||||
it.setASDir(srcDir)
|
it.setASDir(srcDir)
|
||||||
|
|
||||||
if(it.file.exists())
|
if(it.file.exists())
|
||||||
installFile(it.installer, it.file, tmp).printf()
|
installFile(it.installer, it.file, tmp).printf()
|
||||||
}
|
}
|
||||||
it.isURL -> toDownload[it.url] = it.installer to download
|
it.isURL -> toDownload[FileToDownload(download, it.url, true)] = it.installer
|
||||||
else -> return fail("${it.link} is neither a file nor an URL")
|
else -> return fail("${it.link} is neither a file nor an URL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadFiles(
|
downloadFiles(toDownload.keys.toList()) {
|
||||||
toDownload.mapValues {it.value.second},
|
if(it.downloadedFile != null) {
|
||||||
{
|
fPrintln("${it.responseCode} ${it.responseMessage} ${it.file.url} ${it.downloadedFile}", TERMC.brightBlue)
|
||||||
if(it.exception == null) {
|
//Use map of file to installer to get installer for given file
|
||||||
fPrintln("downloaded file ${it.file}", TERMC.brightBlue)
|
installFile(toDownload[it.file]!!, it.downloadedFile, tmp).printf()
|
||||||
installFile(toDownload[it.url]!!.first, it.file, tmp).printf()
|
} else if(it.exception != null) {
|
||||||
} else {
|
fPrintln("ERROR DOWNLOADING ${it.file.url}")
|
||||||
fPrintln("ERROR DOWNLOADING ${it.url}")
|
it.exception.printStackTrace()
|
||||||
it.exception.printStackTrace()
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
resolveFileName = true
|
|
||||||
)
|
|
||||||
|
|
||||||
fPrintln("Making Zip", TERMC.brightGreen)
|
fPrintln("Making Zip", TERMC.brightGreen)
|
||||||
ZipOutputStream(FileOutputStream("build/${MPJH.asWrapper!!.json.id}-${MPJH.asWrapper!!.defaultVersion.versionName}-technic.zip"))
|
ZipOutputStream(FileOutputStream("build/${MPJH.asWrapper!!.json.id}-${MPJH.asWrapper!!.defaultVersion.versionName}-technic.zip"))
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ley.anvil.modpacktools.command.CommandReturn
|
||||||
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
|
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
|
||||||
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
|
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
|
||||||
import ley.anvil.modpacktools.command.LoadCommand
|
import ley.anvil.modpacktools.command.LoadCommand
|
||||||
|
import ley.anvil.modpacktools.util.FileToDownload
|
||||||
import ley.anvil.modpacktools.util.addonscript.installFile
|
import ley.anvil.modpacktools.util.addonscript.installFile
|
||||||
import ley.anvil.modpacktools.util.arg
|
import ley.anvil.modpacktools.util.arg
|
||||||
import ley.anvil.modpacktools.util.downloadFiles
|
import ley.anvil.modpacktools.util.downloadFiles
|
||||||
|
@ -18,11 +19,9 @@ import net.sourceforge.argparse4j.impl.Arguments.storeTrue
|
||||||
import net.sourceforge.argparse4j.inf.ArgumentParser
|
import net.sourceforge.argparse4j.inf.ArgumentParser
|
||||||
import net.sourceforge.argparse4j.inf.Namespace
|
import net.sourceforge.argparse4j.inf.Namespace
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.apache.commons.io.FilenameUtils
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.FileWriter
|
import java.io.FileWriter
|
||||||
import java.net.URL
|
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
@LoadCommand
|
@LoadCommand
|
||||||
|
@ -45,7 +44,7 @@ object BuildTwitch : AbstractCommand("BuildTwitch") {
|
||||||
val ml = convertAStoManifest(wr) {args.getBoolean("all") || "required" in it.options}
|
val ml = convertAStoManifest(wr) {args.getBoolean("all") || "required" in it.options}
|
||||||
val archiveName = "${wr.json.id}-${wr.defaultVersion.versionName}-twitch"
|
val archiveName = "${wr.json.id}-${wr.defaultVersion.versionName}-twitch"
|
||||||
val dir = File("./build")
|
val dir = File("./build")
|
||||||
val toDownload = mutableMapOf<URL, Pair<File, String>>()
|
val toDownload = mutableMapOf<FileToDownload, String>()
|
||||||
val srcDir by lazy {File(CONFIG.config.pathOrException<String>("Locations/src"))}
|
val srcDir by lazy {File(CONFIG.config.pathOrException<String>("Locations/src"))}
|
||||||
val overrides by lazy {File(tmp, "overrides")}
|
val overrides by lazy {File(tmp, "overrides")}
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
|
@ -67,21 +66,23 @@ object BuildTwitch : AbstractCommand("BuildTwitch") {
|
||||||
installFile(uf.value, file, overrides).printf()
|
installFile(uf.value, file, overrides).printf()
|
||||||
}
|
}
|
||||||
} else if(uf.key.isURL) {
|
} else if(uf.key.isURL) {
|
||||||
val filePath = URL(uf.key.link)
|
toDownload[FileToDownload(downloadDir, uf.key.url, true)] = uf.value
|
||||||
toDownload[filePath] = Pair(File(downloadDir, FilenameUtils.getName(filePath.toString())), uf.value)
|
|
||||||
} else {
|
} else {
|
||||||
return fail("{$uf.key.link} is neither a file nor an URL")
|
return fail("{$uf.key.link} is neither a file nor an URL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadFiles(
|
downloadFiles(
|
||||||
toDownload.mapValues {it.value.first},
|
toDownload.keys.toList()
|
||||||
{
|
) {
|
||||||
fPrintln("downloaded file ${it.file}", TERMC.brightBlue)
|
if(it.downloadedFile != null) {
|
||||||
installFile(toDownload[it.url]!!.second, it.file, overrides).printf()
|
fPrintln("downloaded file ${it.file.url}", TERMC.brightBlue)
|
||||||
},
|
installFile(toDownload[it.file]!!, it.downloadedFile, overrides).printf()
|
||||||
false
|
} else if(it.exception != null) {
|
||||||
)
|
fPrintln("ERROR DOWNLOADING ${it.file}")
|
||||||
|
it.exception.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fPrintln("Creating zip", TERMC.brightGreen)
|
fPrintln("Creating zip", TERMC.brightGreen)
|
||||||
val zip = ZipOutputStream(FileOutputStream("${dir.path}/$archiveName.zip"))
|
val zip = ZipOutputStream(FileOutputStream("${dir.path}/$archiveName.zip"))
|
||||||
|
|
|
@ -6,7 +6,7 @@ import ley.anvil.modpacktools.command.AbstractCommand
|
||||||
import ley.anvil.modpacktools.command.CommandReturn
|
import ley.anvil.modpacktools.command.CommandReturn
|
||||||
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
|
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
|
||||||
import ley.anvil.modpacktools.command.LoadCommand
|
import ley.anvil.modpacktools.command.LoadCommand
|
||||||
import ley.anvil.modpacktools.util.DownloadFileTask
|
import ley.anvil.modpacktools.util.FileToDownload
|
||||||
import ley.anvil.modpacktools.util.arg
|
import ley.anvil.modpacktools.util.arg
|
||||||
import ley.anvil.modpacktools.util.downloadFiles
|
import ley.anvil.modpacktools.util.downloadFiles
|
||||||
import ley.anvil.modpacktools.util.fPrintln
|
import ley.anvil.modpacktools.util.fPrintln
|
||||||
|
@ -15,8 +15,6 @@ import net.sourceforge.argparse4j.impl.type.FileArgumentType
|
||||||
import net.sourceforge.argparse4j.inf.ArgumentParser
|
import net.sourceforge.argparse4j.inf.ArgumentParser
|
||||||
import net.sourceforge.argparse4j.inf.Namespace
|
import net.sourceforge.argparse4j.inf.Namespace
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
|
||||||
import java.util.stream.Collectors.toMap
|
|
||||||
|
|
||||||
@LoadCommand
|
@LoadCommand
|
||||||
object DownloadMods : AbstractCommand("DownloadMods") {
|
object DownloadMods : AbstractCommand("DownloadMods") {
|
||||||
|
@ -42,46 +40,36 @@ object DownloadMods : AbstractCommand("DownloadMods") {
|
||||||
override fun execute(args: Namespace): CommandReturn {
|
override fun execute(args: Namespace): CommandReturn {
|
||||||
val json = MPJH.asWrapper
|
val json = MPJH.asWrapper
|
||||||
val fileList = mutableListOf<FileOrLink>()
|
val fileList = mutableListOf<FileOrLink>()
|
||||||
for(
|
for(rel in json!!.defaultVersion!!.getRelations {"client" in it.options && (args.getBoolean("all") || it.type == "mod")})
|
||||||
rel in json!!.defaultVersion!!.getRelations {
|
|
||||||
"client" in it.options && (args.getBoolean("all") || it.type == "mod")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if(rel.hasFile())
|
if(rel.hasFile())
|
||||||
fileList.add(rel.file.get())
|
fileList.add(rel.file.get())
|
||||||
|
|
||||||
downloadFiles(
|
downloadFiles(
|
||||||
fileList.stream()
|
fileList
|
||||||
.filter {it.isURL}
|
.filter {it.isURL}
|
||||||
.filter {
|
.filter {
|
||||||
val (installer, dir) = it.installer.split(':')
|
val (installer, dir) = it.installer.split(':')
|
||||||
|
|
||||||
installer == "internal.dir" && (args.getBoolean("all") || dir == "mods")
|
installer == "internal.dir" && (args.getBoolean("all") || dir == "mods")
|
||||||
}
|
}
|
||||||
.collect(
|
.map {
|
||||||
toMap<FileOrLink, URL, File>(
|
FileToDownload(
|
||||||
{URL(it.link)},
|
if(args.getBoolean("all"))
|
||||||
{
|
File(args.get<File>("dir"), it.installer.split(':')[1])
|
||||||
val dir = it.installer.split(':').last()
|
else
|
||||||
|
args.get<File>("dir"),
|
||||||
if(args.getBoolean("all"))
|
it.url,
|
||||||
File(args.get<File>("dir"), dir)
|
true,
|
||||||
else
|
!args.getBoolean("force")
|
||||||
args.get<File>("dir")
|
|
||||||
},
|
|
||||||
{_: File, f: File -> f}
|
|
||||||
)
|
)
|
||||||
),
|
|
||||||
{r: DownloadFileTask.Return ->
|
|
||||||
println("${r.responseCode} ${r.responseMessage} ${r.url} ${r.file}")
|
|
||||||
if(r.exception != null) {
|
|
||||||
fPrintln("ERROR DOWNLOADING ${r.url}")
|
|
||||||
r.exception.printStackTrace()
|
|
||||||
}
|
}
|
||||||
},
|
) {
|
||||||
!args.getBoolean("force"),
|
println("${it.responseCode} ${it.responseMessage} ${it.file.url} ${it.downloadedFile}")
|
||||||
true
|
if(it.exception != null) {
|
||||||
)
|
fPrintln("ERROR DOWNLOADING ${it.file.url}")
|
||||||
|
it.exception.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
return success()
|
return success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,57 +11,58 @@ import java.io.IOException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.stream.Collectors
|
|
||||||
|
|
||||||
private var latch: CountDownLatch? = null
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads all supplied urls to the given files
|
* Downloads all supplied urls to the given files
|
||||||
*
|
*
|
||||||
* @param files the files to download and the file to save them to
|
* @param files the files to download
|
||||||
* @param callback the callback which will be called once a download finishes
|
* @param callback the callback which will be called once a download finishes
|
||||||
* @param skipExistingFiles if true, files that already exist will not be downloaded
|
|
||||||
* @param resolveFileName if true, the file name will be resolved using the URL (target file will now serve as directory)
|
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
|
||||||
fun downloadFiles(
|
fun downloadFiles(
|
||||||
files: Map<URL, File>,
|
files: List<FileToDownload>,
|
||||||
callback: (DownloadFileTask.Return) -> Unit,
|
callback: (DownloadFileTask.Return) -> Unit
|
||||||
skipExistingFiles: Boolean = false,
|
|
||||||
resolveFileName: Boolean = false
|
|
||||||
) {
|
) {
|
||||||
val tasks = files.entries.stream()
|
val latch = CountDownLatch(files.size)
|
||||||
//remove if it should be skipped
|
files.forEach {
|
||||||
.filter {!skipExistingFiles || !it.value.exists()}
|
val req = DownloadFileTask(callback, latch, it)
|
||||||
.collect(Collectors.toList())
|
|
||||||
latch = CountDownLatch(tasks.size)
|
|
||||||
tasks.forEach {
|
|
||||||
val req = DownloadFileTask(it.key, it.value, callback, latch!!, resolveFileName)
|
|
||||||
HTTP_CLIENT.newCall(req.request).enqueue(req)
|
HTTP_CLIENT.newCall(req.request).enqueue(req)
|
||||||
}
|
}
|
||||||
latch!!.await()
|
latch.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file that should be downloaded
|
||||||
|
*
|
||||||
|
* @param fileOrDir the file to save to
|
||||||
|
* @param url the url to download from
|
||||||
|
* @param shouldResolveFileName if true, the fileOrDir will be treated as directory and the file name will be resolved from the URL
|
||||||
|
*/
|
||||||
|
data class FileToDownload(
|
||||||
|
val fileOrDir: File,
|
||||||
|
val url: URL,
|
||||||
|
val shouldResolveFileName: Boolean = false,
|
||||||
|
val shouldSkipIfExists: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
open class DownloadFileTask(
|
open class DownloadFileTask(
|
||||||
protected open val url: URL,
|
|
||||||
protected open val file: File,
|
|
||||||
protected open val callback: (Return) -> Unit,
|
protected open val callback: (Return) -> Unit,
|
||||||
protected open val latch: CountDownLatch,
|
protected open val latch: CountDownLatch,
|
||||||
protected open val resolveFileName: Boolean
|
protected open val file: FileToDownload
|
||||||
) : Callback {
|
) : Callback {
|
||||||
open val request = Request.Builder()
|
open val request = Request.Builder()
|
||||||
.get()
|
.get()
|
||||||
.url(url)
|
.url(file.url)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
callback(
|
callback(
|
||||||
Return(
|
Return(
|
||||||
url,
|
|
||||||
file,
|
file,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
e
|
null,
|
||||||
|
e,
|
||||||
|
true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
latch.countDown()
|
latch.countDown()
|
||||||
|
@ -69,31 +70,28 @@ open class DownloadFileTask(
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
override fun onResponse(call: Call, response: Response) {
|
||||||
callback(
|
callback(
|
||||||
try {
|
run {
|
||||||
|
var wasSkipped = true
|
||||||
val outFile =
|
val outFile =
|
||||||
if(resolveFileName)
|
if(file.shouldResolveFileName)
|
||||||
file mergeTo Paths.get(response.request.url.toUri().path).fileName.toFile()
|
file.fileOrDir mergeTo Paths.get(response.request.url.toUri().path).fileName.toFile()
|
||||||
else
|
else
|
||||||
file
|
file.fileOrDir
|
||||||
|
|
||||||
val stream = response.body?.byteStream()
|
if(!file.shouldSkipIfExists || !outFile.exists()) {
|
||||||
FileUtils.copyInputStreamToFile(stream, outFile)
|
response.body?.byteStream().use {
|
||||||
stream!!.close()
|
FileUtils.copyInputStreamToFile(it, outFile)
|
||||||
|
}
|
||||||
|
wasSkipped = false
|
||||||
|
}
|
||||||
|
|
||||||
Return(
|
Return(
|
||||||
url,
|
file,
|
||||||
outFile,
|
outFile,
|
||||||
response.code,
|
response.code,
|
||||||
response.message,
|
response.message,
|
||||||
null
|
null,
|
||||||
)
|
wasSkipped
|
||||||
} catch(e: NullPointerException) {
|
|
||||||
Return(
|
|
||||||
url,
|
|
||||||
file,
|
|
||||||
response.code,
|
|
||||||
response.message,
|
|
||||||
e
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -101,10 +99,11 @@ open class DownloadFileTask(
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Return(
|
data class Return(
|
||||||
val url: URL,
|
val file: FileToDownload,
|
||||||
val file: File,
|
val downloadedFile: File?,
|
||||||
val responseCode: Int?,
|
val responseCode: Int?,
|
||||||
val responseMessage: String?,
|
val responseMessage: String?,
|
||||||
val exception: Exception?
|
val exception: Exception?,
|
||||||
|
val wasSkipped: Boolean
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue