4
0
Fork 0
mirror of https://github.com/Anvilcraft/modpacktools synced 2024-05-19 11:54:20 +02:00
This commit is contained in:
Timo Ley 2020-08-15 17:02:04 +02:00
commit 57fd3a86df
5 changed files with 112 additions and 114 deletions

View file

@ -20,9 +20,7 @@ constructor(
ArgumentParsers.newFor(displayName)
.build()
.description(helpMessage)
.apply {
addArgs()
}
.apply {addArgs()}
}
/**
@ -31,5 +29,5 @@ constructor(
*
* @receiver the parser to add the args to
*/
open fun ArgumentParser.addArgs() {}
protected open fun ArgumentParser.addArgs() {}
}

View file

@ -8,6 +8,7 @@ import ley.anvil.modpacktools.command.AbstractCommand
import ley.anvil.modpacktools.command.CommandReturn
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
import ley.anvil.modpacktools.command.LoadCommand
import ley.anvil.modpacktools.util.FileToDownload
import ley.anvil.modpacktools.util.addonscript.installFile
import ley.anvil.modpacktools.util.downloadFiles
import ley.anvil.modpacktools.util.fPrintln
@ -16,7 +17,6 @@ import net.sourceforge.argparse4j.inf.Namespace
import org.apache.commons.io.FileUtils
import java.io.File
import java.io.FileOutputStream
import java.net.URL
import java.util.zip.ZipOutputStream
@LoadCommand
@ -37,39 +37,51 @@ object BuildTechnic : AbstractCommand("BuildTechnic") {
}
val fileList = mutableListOf<FileOrLink>()
val toDownload = mutableMapOf<URL, Pair<String, File>>()
MPJH.asWrapper!!.defaultVersion.getRelations {"client" in it.options}.forEach {
if(it.hasFile())
fileList.add(it.file.get())
}
//Map of File to Installer
val toDownload = mutableMapOf<FileToDownload, String>()
//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 {
when {
it.isFile -> {
!it.isURL -> {
if(!it.isASDirSet)
it.setASDir(srcDir)
if(it.file.exists())
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")
}
}
downloadFiles(
toDownload.mapValues {it.value.second},
{
if(it.exception == null) {
fPrintln("downloaded file ${it.file}", TERMC.brightBlue)
installFile(toDownload[it.url]!!.first, it.file, tmp).printf()
} else {
fPrintln("ERROR DOWNLOADING ${it.url}")
it.exception.printStackTrace()
}
},
resolveFileName = true
)
downloadFiles(toDownload.keys.toList()) {
if(it.downloadedFile != null) {
fPrintln("${it.responseCode} ${it.responseMessage} ${it.file.url} ${it.downloadedFile}", TERMC.brightBlue)
//Use map of file to installer to get installer for given file
installFile(toDownload[it.file]!!, it.downloadedFile, tmp).printf()
} else if(it.exception != null) {
fPrintln("ERROR DOWNLOADING ${it.file.url}")
it.exception.printStackTrace()
}
}
fPrintln("Making Zip", TERMC.brightGreen)
ZipOutputStream(FileOutputStream("build/${MPJH.asWrapper!!.json.id}-${MPJH.asWrapper!!.defaultVersion.versionName}-technic.zip"))

View file

@ -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.success
import ley.anvil.modpacktools.command.LoadCommand
import ley.anvil.modpacktools.util.FileToDownload
import ley.anvil.modpacktools.util.addonscript.installFile
import ley.anvil.modpacktools.util.arg
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.Namespace
import org.apache.commons.io.FileUtils
import org.apache.commons.io.FilenameUtils
import java.io.File
import java.io.FileOutputStream
import java.io.FileWriter
import java.net.URL
import java.util.zip.ZipOutputStream
@LoadCommand
@ -45,7 +44,7 @@ object BuildTwitch : AbstractCommand("BuildTwitch") {
val ml = convertAStoManifest(wr) {args.getBoolean("all") || "required" in it.options}
val archiveName = "${wr.json.id}-${wr.defaultVersion.versionName}-twitch"
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 overrides by lazy {File(tmp, "overrides")}
dir.mkdirs()
@ -67,21 +66,23 @@ object BuildTwitch : AbstractCommand("BuildTwitch") {
installFile(uf.value, file, overrides).printf()
}
} else if(uf.key.isURL) {
val filePath = URL(uf.key.link)
toDownload[filePath] = Pair(File(downloadDir, FilenameUtils.getName(filePath.toString())), uf.value)
toDownload[FileToDownload(downloadDir, uf.key.url, true)] = uf.value
} else {
return fail("{$uf.key.link} is neither a file nor an URL")
}
}
downloadFiles(
toDownload.mapValues {it.value.first},
{
fPrintln("downloaded file ${it.file}", TERMC.brightBlue)
installFile(toDownload[it.url]!!.second, it.file, overrides).printf()
},
false
)
toDownload.keys.toList()
) {
if(it.downloadedFile != null) {
fPrintln("downloaded file ${it.file.url}", TERMC.brightBlue)
installFile(toDownload[it.file]!!, it.downloadedFile, overrides).printf()
} else if(it.exception != null) {
fPrintln("ERROR DOWNLOADING ${it.file}")
it.exception.printStackTrace()
}
}
fPrintln("Creating zip", TERMC.brightGreen)
val zip = ZipOutputStream(FileOutputStream("${dir.path}/$archiveName.zip"))

View file

@ -6,7 +6,7 @@ import ley.anvil.modpacktools.command.AbstractCommand
import ley.anvil.modpacktools.command.CommandReturn
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
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.downloadFiles
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.Namespace
import java.io.File
import java.net.URL
import java.util.stream.Collectors.toMap
@LoadCommand
object DownloadMods : AbstractCommand("DownloadMods") {
@ -42,46 +40,36 @@ object DownloadMods : AbstractCommand("DownloadMods") {
override fun execute(args: Namespace): CommandReturn {
val json = MPJH.asWrapper
val fileList = mutableListOf<FileOrLink>()
for(
rel in json!!.defaultVersion!!.getRelations {
"client" in it.options && (args.getBoolean("all") || it.type == "mod")
}
)
for(rel in json!!.defaultVersion!!.getRelations {"client" in it.options && (args.getBoolean("all") || it.type == "mod")})
if(rel.hasFile())
fileList.add(rel.file.get())
downloadFiles(
fileList.stream()
fileList
.filter {it.isURL}
.filter {
val (installer, dir) = it.installer.split(':')
installer == "internal.dir" && (args.getBoolean("all") || dir == "mods")
}
.collect(
toMap<FileOrLink, URL, File>(
{URL(it.link)},
{
val dir = it.installer.split(':').last()
if(args.getBoolean("all"))
File(args.get<File>("dir"), dir)
else
args.get<File>("dir")
},
{_: File, f: File -> f}
.map {
FileToDownload(
if(args.getBoolean("all"))
File(args.get<File>("dir"), it.installer.split(':')[1])
else
args.get<File>("dir"),
it.url,
true,
!args.getBoolean("force")
)
),
{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"),
true
)
) {
println("${it.responseCode} ${it.responseMessage} ${it.file.url} ${it.downloadedFile}")
if(it.exception != null) {
fPrintln("ERROR DOWNLOADING ${it.file.url}")
it.exception.printStackTrace()
}
}
return success()
}
}

View file

@ -11,57 +11,58 @@ import java.io.IOException
import java.net.URL
import java.nio.file.Paths
import java.util.concurrent.CountDownLatch
import java.util.stream.Collectors
private var latch: CountDownLatch? = null
/**
* 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 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(
files: Map<URL, File>,
callback: (DownloadFileTask.Return) -> Unit,
skipExistingFiles: Boolean = false,
resolveFileName: Boolean = false
files: List<FileToDownload>,
callback: (DownloadFileTask.Return) -> Unit
) {
val tasks = files.entries.stream()
//remove if it should be skipped
.filter {!skipExistingFiles || !it.value.exists()}
.collect(Collectors.toList())
latch = CountDownLatch(tasks.size)
tasks.forEach {
val req = DownloadFileTask(it.key, it.value, callback, latch!!, resolveFileName)
val latch = CountDownLatch(files.size)
files.forEach {
val req = DownloadFileTask(callback, latch, it)
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(
protected open val url: URL,
protected open val file: File,
protected open val callback: (Return) -> Unit,
protected open val latch: CountDownLatch,
protected open val resolveFileName: Boolean
protected open val file: FileToDownload
) : Callback {
open val request = Request.Builder()
.get()
.url(url)
.url(file.url)
.build()
override fun onFailure(call: Call, e: IOException) {
callback(
Return(
url,
file,
null,
null,
e
null,
e,
true
)
)
latch.countDown()
@ -69,31 +70,28 @@ open class DownloadFileTask(
override fun onResponse(call: Call, response: Response) {
callback(
try {
run {
var wasSkipped = true
val outFile =
if(resolveFileName)
file mergeTo Paths.get(response.request.url.toUri().path).fileName.toFile()
if(file.shouldResolveFileName)
file.fileOrDir mergeTo Paths.get(response.request.url.toUri().path).fileName.toFile()
else
file
file.fileOrDir
val stream = response.body?.byteStream()
FileUtils.copyInputStreamToFile(stream, outFile)
stream!!.close()
if(!file.shouldSkipIfExists || !outFile.exists()) {
response.body?.byteStream().use {
FileUtils.copyInputStreamToFile(it, outFile)
}
wasSkipped = false
}
Return(
url,
file,
outFile,
response.code,
response.message,
null
)
} catch(e: NullPointerException) {
Return(
url,
file,
response.code,
response.message,
e
null,
wasSkipped
)
}
)
@ -101,10 +99,11 @@ open class DownloadFileTask(
}
data class Return(
val url: URL,
val file: File,
val file: FileToDownload,
val downloadedFile: File?,
val responseCode: Int?,
val responseMessage: String?,
val exception: Exception?
val exception: Exception?,
val wasSkipped: Boolean
)
}